2019-02-20 18:15:15 +01:00
|
|
|
type mo_class =
|
2019-03-20 19:18:36 +01:00
|
|
|
| Core of int (* Always doubly occupied *)
|
|
|
|
| Inactive of int (* With 0,1 or 2 holes *)
|
|
|
|
| Active of int (* With 0,1 or 2 holes or particles *)
|
|
|
|
| Virtual of int (* With 0,1 or 2 particles *)
|
|
|
|
| Deleted of int (* Always unoccupied *)
|
|
|
|
| Auxiliary of int (* Auxiliary basis function *)
|
2019-02-20 18:15:15 +01:00
|
|
|
|
|
|
|
type t = mo_class list
|
|
|
|
|
|
|
|
|
2019-12-03 12:25:31 +01:00
|
|
|
let pp_mo_class ppf = function
|
2019-03-20 19:18:36 +01:00
|
|
|
| Core i -> Format.fprintf ppf "@[Core %d@]" i
|
|
|
|
| Inactive i -> Format.fprintf ppf "@[Inactive %d@]" i
|
|
|
|
| Active i -> Format.fprintf ppf "@[Active %d@]" i
|
|
|
|
| Virtual i -> Format.fprintf ppf "@[Virtual %d@]" i
|
|
|
|
| Deleted i -> Format.fprintf ppf "@[Deleted %d@]" i
|
|
|
|
| Auxiliary i -> Format.fprintf ppf "@[Auxiliary %d@]" i
|
2019-02-20 18:15:15 +01:00
|
|
|
|
2019-12-03 12:25:31 +01:00
|
|
|
let pp ppf t =
|
|
|
|
Format.fprintf ppf "@[[@,";
|
|
|
|
let rec aux = function
|
|
|
|
| [] -> Format.fprintf ppf "]@]"
|
|
|
|
| x :: [] -> Format.fprintf ppf "%a@,]@]" pp_mo_class x
|
|
|
|
| x :: rest -> ( Format.fprintf ppf "%a@,;@," pp_mo_class x; aux rest )
|
|
|
|
in
|
|
|
|
aux t
|
|
|
|
|
2019-02-20 18:15:15 +01:00
|
|
|
|
|
|
|
|
|
|
|
let of_list t = t
|
|
|
|
|
2019-03-18 12:41:32 +01:00
|
|
|
let to_list t = t
|
|
|
|
|
|
|
|
|
2019-02-20 18:15:15 +01:00
|
|
|
let core_mos t =
|
|
|
|
List.map (fun x ->
|
|
|
|
match x with
|
|
|
|
| Core i -> Some i
|
|
|
|
| _ -> None) t
|
|
|
|
|> Util.list_some
|
|
|
|
|
2019-03-18 12:41:32 +01:00
|
|
|
|
2019-02-20 18:15:15 +01:00
|
|
|
let inactive_mos t =
|
|
|
|
List.map (fun x ->
|
|
|
|
match x with
|
|
|
|
| Inactive i -> Some i
|
|
|
|
| _ -> None ) t
|
|
|
|
|> Util.list_some
|
|
|
|
|
2019-03-18 12:41:32 +01:00
|
|
|
|
2019-02-20 18:15:15 +01:00
|
|
|
let active_mos t =
|
|
|
|
List.map (fun x ->
|
|
|
|
match x with
|
|
|
|
| Active i -> Some i
|
|
|
|
| _ -> None ) t
|
|
|
|
|> Util.list_some
|
|
|
|
|
2019-03-18 12:41:32 +01:00
|
|
|
|
2019-02-20 18:15:15 +01:00
|
|
|
let virtual_mos t =
|
|
|
|
List.map (fun x ->
|
|
|
|
match x with
|
|
|
|
| Virtual i -> Some i
|
|
|
|
| _ -> None ) t
|
|
|
|
|> Util.list_some
|
|
|
|
|
2019-03-18 12:41:32 +01:00
|
|
|
|
2019-02-20 18:15:15 +01:00
|
|
|
let deleted_mos t =
|
|
|
|
List.map (fun x ->
|
|
|
|
match x with
|
|
|
|
| Deleted i -> Some i
|
|
|
|
| _ -> None ) t
|
|
|
|
|> Util.list_some
|
|
|
|
|
|
|
|
|
2019-03-20 23:10:53 +01:00
|
|
|
let auxiliary_mos t =
|
2019-03-20 19:18:36 +01:00
|
|
|
List.map (fun x ->
|
|
|
|
match x with
|
|
|
|
| Auxiliary i -> Some i
|
|
|
|
| _ -> None ) t
|
|
|
|
|> Util.list_some
|
|
|
|
|
|
|
|
|
2019-03-18 12:41:32 +01:00
|
|
|
let mo_class_array t =
|
|
|
|
let sze = List.length t + 1 in
|
|
|
|
let result = Array.make sze (Deleted 0) in
|
|
|
|
List.iter (fun c ->
|
|
|
|
match c with
|
|
|
|
| Core i -> result.(i) <- Core i
|
|
|
|
| Inactive i -> result.(i) <- Inactive i
|
|
|
|
| Active i -> result.(i) <- Active i
|
|
|
|
| Virtual i -> result.(i) <- Virtual i
|
|
|
|
| Deleted i -> result.(i) <- Deleted i
|
2019-03-20 19:18:36 +01:00
|
|
|
| Auxiliary i -> result.(i) <- Auxiliary i
|
2019-03-18 12:41:32 +01:00
|
|
|
) t;
|
|
|
|
result
|
|
|
|
|
|
|
|
|
2020-01-13 11:39:40 +01:00
|
|
|
let fci ~frozen_core mo_basis =
|
2019-02-20 19:43:16 +01:00
|
|
|
let mo_num = MOBasis.size mo_basis in
|
|
|
|
let ncore = (Nuclei.small_core @@ Simulation.nuclei @@ MOBasis.simulation mo_basis) / 2 in
|
|
|
|
of_list (
|
|
|
|
if frozen_core then
|
|
|
|
List.concat [
|
|
|
|
Util.list_range 1 ncore
|
|
|
|
|> List.map (fun i -> Core i) ;
|
|
|
|
Util.list_range (ncore+1) mo_num
|
|
|
|
|> List.map (fun i -> Active i)
|
|
|
|
]
|
|
|
|
else
|
|
|
|
Util.list_range 1 mo_num
|
|
|
|
|> List.map (fun i -> Active i)
|
|
|
|
)
|
|
|
|
|
2019-03-18 12:41:32 +01:00
|
|
|
|
2019-03-23 15:54:46 +01:00
|
|
|
let cas_sd mo_basis ~frozen_core n m =
|
2019-03-18 12:41:32 +01:00
|
|
|
let mo_num = MOBasis.size mo_basis in
|
|
|
|
let n_alfa = MOBasis.simulation mo_basis |> Simulation.electrons |> Electrons.n_alfa in
|
2019-03-20 19:18:36 +01:00
|
|
|
let n_beta = MOBasis.simulation mo_basis |> Simulation.electrons |> Electrons.n_beta in
|
2019-03-18 12:41:32 +01:00
|
|
|
let n_unpaired = n_alfa - n_beta in
|
2019-03-23 15:54:46 +01:00
|
|
|
let n_alfa_in_cas = (n - n_unpaired)/2 + n_unpaired in
|
2019-03-20 19:18:36 +01:00
|
|
|
let last_inactive = n_alfa - n_alfa_in_cas in
|
2019-03-18 12:41:32 +01:00
|
|
|
let last_active = last_inactive + m in
|
2019-03-20 19:18:36 +01:00
|
|
|
let ncore =
|
2019-03-23 15:54:46 +01:00
|
|
|
if frozen_core then
|
|
|
|
(Nuclei.small_core @@ Simulation.nuclei @@ MOBasis.simulation mo_basis) / 2
|
|
|
|
|> min last_inactive
|
|
|
|
else 0
|
2019-03-20 19:18:36 +01:00
|
|
|
in
|
2019-03-18 12:41:32 +01:00
|
|
|
of_list (
|
|
|
|
List.concat [
|
2019-03-20 19:18:36 +01:00
|
|
|
if ncore > 0 then
|
|
|
|
Util.list_range 1 ncore
|
|
|
|
|> List.map (fun i -> Core i)
|
|
|
|
else
|
|
|
|
[] ;
|
2019-03-18 12:41:32 +01:00
|
|
|
Util.list_range (ncore+1) last_inactive
|
|
|
|
|> List.map (fun i -> Inactive i) ;
|
|
|
|
Util.list_range (last_inactive+1) last_active
|
|
|
|
|> List.map (fun i -> Active i) ;
|
|
|
|
Util.list_range (last_active+1) mo_num
|
|
|
|
|> List.map (fun i -> Virtual i)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
2019-03-20 19:18:36 +01:00
|
|
|
|