2019-02-19 17:36:07 +01:00
|
|
|
type t =
|
2019-02-20 19:43:16 +01:00
|
|
|
{
|
|
|
|
elec_num : int;
|
|
|
|
mo_basis : MOBasis.t;
|
|
|
|
mo_class : MOClass.t;
|
|
|
|
spin_determinants : Spindeterminant.t array;
|
|
|
|
}
|
2019-02-19 17:36:07 +01:00
|
|
|
|
2019-02-20 18:15:15 +01:00
|
|
|
|
2019-02-20 19:43:16 +01:00
|
|
|
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
|
|
|
|
|
2019-03-23 15:54:46 +01:00
|
|
|
let fci_of_mo_basis ~frozen_core mo_basis elec_num =
|
2019-02-19 17:36:07 +01:00
|
|
|
let mo_num = MOBasis.size mo_basis in
|
2019-02-20 19:43:16 +01:00
|
|
|
let mo_class = MOClass.fci ~frozen_core mo_basis in
|
2019-02-20 18:15:15 +01:00
|
|
|
let m l =
|
2019-03-26 01:20:17 +01:00
|
|
|
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
|
2019-02-20 18:15:15 +01:00
|
|
|
in
|
|
|
|
let occ_mask = m (MOClass.core_mos mo_class)
|
|
|
|
and active_mask = m (MOClass.active_mos mo_class)
|
|
|
|
in
|
2019-03-25 19:28:38 +01:00
|
|
|
let neg_active_mask = Bitstring.lognot active_mask in
|
2019-03-18 19:17:15 +01:00
|
|
|
(* Here we generate the FCI space and filter out unwanted determinants
|
|
|
|
with excitations involving the core electrons. This should be improved. *)
|
2019-02-20 19:43:16 +01:00
|
|
|
let spin_determinants =
|
2019-03-25 19:28:38 +01:00
|
|
|
Bitstring.permtutations elec_num mo_num
|
|
|
|
|> List.filter (fun b -> Bitstring.logand neg_active_mask b = occ_mask)
|
2019-02-19 17:36:07 +01:00
|
|
|
|> List.map (fun b -> Spindeterminant.of_bitstring b)
|
|
|
|
|> Array.of_list
|
|
|
|
in
|
2019-02-20 19:43:16 +01:00
|
|
|
{ elec_num ; mo_basis ; mo_class ; spin_determinants }
|
2019-02-19 17:36:07 +01:00
|
|
|
|
|
|
|
|
2019-03-23 15:54:46 +01:00
|
|
|
let cas_of_mo_basis mo_basis ~frozen_core elec_num n m =
|
2019-03-18 19:17:15 +01:00
|
|
|
let mo_num = MOBasis.size mo_basis in
|
2019-03-23 15:54:46 +01:00
|
|
|
let mo_class = MOClass.cas_sd ~frozen_core mo_basis n m in
|
2019-03-18 19:17:15 +01:00
|
|
|
let m l =
|
2019-03-26 01:20:17 +01:00
|
|
|
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
|
2019-03-18 19:17:15 +01:00
|
|
|
in
|
|
|
|
let active_mask = m (MOClass.active_mos mo_class) in
|
|
|
|
let occ_mask = m (MOClass.core_mos mo_class) in
|
|
|
|
let inactive_mask = m (MOClass.inactive_mos mo_class) in
|
2019-03-25 19:28:38 +01:00
|
|
|
let occ_mask = Bitstring.logor occ_mask inactive_mask in
|
|
|
|
let neg_active_mask = Bitstring.lognot active_mask in
|
2019-03-18 19:17:15 +01:00
|
|
|
(* Here we generate the FCI space and filter out all the unwanted determinants.
|
|
|
|
This should be improved. *)
|
|
|
|
let spin_determinants =
|
2019-03-25 19:28:38 +01:00
|
|
|
Bitstring.permtutations elec_num mo_num
|
|
|
|
|> List.filter (fun b -> Bitstring.logand neg_active_mask b = occ_mask)
|
2019-03-18 19:17:15 +01:00
|
|
|
|> List.map (fun b -> Spindeterminant.of_bitstring b)
|
|
|
|
|> Array.of_list
|
|
|
|
in
|
|
|
|
{ elec_num ; mo_basis ; mo_class ; spin_determinants }
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-12-03 12:25:31 +01:00
|
|
|
let pp ppf t =
|
|
|
|
Format.fprintf ppf "@[<v 2> [";
|
|
|
|
let pp = Spindeterminant.pp @@ MOBasis.size (mo_basis t) in
|
|
|
|
Array.iteri (fun i d ->
|
|
|
|
Format.fprintf ppf "@[<v>@[%8d@] @[%a@]@]@;" i pp d)
|
|
|
|
(spin_determinants t) ;
|
2019-02-19 17:36:07 +01:00
|
|
|
Format.fprintf ppf "]@]"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|