10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-11-19 04:22:21 +01:00
QCaml/CI/SpindeterminantSpace.ml

71 lines
2.4 KiB
OCaml
Raw Normal View History

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 =
List.fold_left (fun accu i -> let j = i-1 in Z.(logor accu (shift_left one j))
2019-02-20 19:43:16 +01:00
) Z.zero 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-02-20 18:27:58 +01:00
let neg_active_mask = Z.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-02-19 17:36:07 +01:00
Util.bit_permtutations elec_num mo_num
2019-02-20 18:15:15 +01:00
|> List.filter (fun b -> Z.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 =
List.fold_left (fun accu i -> let j = i-1 in Z.(logor accu (shift_left one j))
) Z.zero l
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
let occ_mask = Z.logor occ_mask inactive_mask in
let neg_active_mask = Z.lognot active_mask in
(* Here we generate the FCI space and filter out all the unwanted determinants.
This should be improved. *)
let spin_determinants =
Util.bit_permtutations elec_num mo_num
|> List.filter (fun b -> Z.logand neg_active_mask b = occ_mask)
|> List.map (fun b -> Spindeterminant.of_bitstring b)
|> Array.of_list
in
{ elec_num ; mo_basis ; mo_class ; spin_determinants }
2019-02-19 17:36:07 +01:00
let pp_spindet_space ppf t =
2019-02-20 19:43:16 +01:00
Format.fprintf ppf "@[<v 2>[ ";
Array.iteri (fun i d -> Format.fprintf ppf "@[<v>@[%8d@] @[%a@]@]@;" i
(Spindeterminant.pp_spindet (MOBasis.size (mo_basis t))) d) (spin_determinants t) ;
2019-02-19 17:36:07 +01:00
Format.fprintf ppf "]@]"