type mo_class = | 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 *) type t = mo_class list let pp_mo_occ ppf = function | 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 let of_list t = t let core_mos t = List.map (fun x -> match x with | Core i -> Some i | _ -> None) t |> Util.list_some let inactive_mos t = List.map (fun x -> match x with | Inactive i -> Some i | _ -> None ) t |> Util.list_some let active_mos t = List.map (fun x -> match x with | Active i -> Some i | _ -> None ) t |> Util.list_some let virtual_mos t = List.map (fun x -> match x with | Virtual i -> Some i | _ -> None ) t |> Util.list_some let deleted_mos t = List.map (fun x -> match x with | Deleted i -> Some i | _ -> None ) t |> Util.list_some let fci ?(frozen_core=true) mo_basis = 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) )