10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-12-22 20:33:36 +01:00
QCaml/ci/lib/spindeterminant_space.ml
2024-06-24 14:28:30 +02:00

76 lines
2.5 KiB
OCaml

open Common
type t =
{
elec_num : int;
mo_basis : Mo.Basis.t;
mo_class : Mo.Class.t;
spin_determinants : Spindeterminant.t array;
}
let spin_determinants t = t.spin_determinants
let elec_num t = t.elec_num
let mo_basis t = t.mo_basis
let mo_class t = t.mo_class
let size t = Array.length t.spin_determinants
let fci_of_mo_basis ~frozen_core mo_basis elec_num =
let mo_num = Mo.Basis.size mo_basis in
let mo_class = Mo.Class.fci ~frozen_core mo_basis in
let m l =
List.fold_left (fun accu i -> let j = i-1 in
Bitstring.logor accu (Bitstring.shift_left_one mo_num j)
) (Bitstring.zero mo_num) l
in
let occ_mask = m (Mo.Class.core_mos mo_class)
and active_mask = m (Mo.Class.active_mos mo_class)
in
let neg_active_mask = Bitstring.lognot active_mask in
(* Here we generate the FCI space and filter out unwanted determinants
with excitations involving the core electrons. This should be improved. *)
let spin_determinants =
Bitstring.permutations elec_num mo_num
|> List.filter (fun b -> Bitstring.logand neg_active_mask b = occ_mask)
|> Array.of_list
|> Array.map (fun b -> Spindeterminant.of_bitstring b)
in
{ elec_num ; mo_basis ; mo_class ; spin_determinants }
let cas_of_mo_basis mo_basis ~frozen_core elec_num n m =
let mo_num = Mo.Basis.size mo_basis in
let mo_class = Mo.Class.cas_sd ~frozen_core mo_basis n m in
let m l =
List.fold_left (fun accu i -> let j = i-1 in
Bitstring.logor accu (Bitstring.shift_left_one mo_num j)
) (Bitstring.zero mo_num) l
in
let active_mask = m (Mo.Class.active_mos mo_class) in
let occ_mask = m (Mo.Class.core_mos mo_class) in
let inactive_mask = m (Mo.Class.inactive_mos mo_class) in
let occ_mask = Bitstring.logor occ_mask inactive_mask in
let neg_active_mask = Bitstring.lognot active_mask in
(* Here we generate the FCI space and filter out all the unwanted determinants.
This should be improved. *)
let spin_determinants =
Bitstring.permutations elec_num mo_num
|> List.filter (fun b -> Bitstring.logand neg_active_mask b = occ_mask)
|> Array.of_list
|> Array.map (fun b -> Spindeterminant.of_bitstring b)
in
{ elec_num ; mo_basis ; mo_class ; spin_determinants }
let pp ppf t =
Format.fprintf ppf "@[<v 2> [";
Array.iteri (fun i d ->
Format.fprintf ppf "@[<v>@[%8d@] @[%a@]@]@;" i Spindeterminant.pp d)
(spin_determinants t) ;
Format.fprintf ppf "]@]"