10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-06-19 19:52:06 +02:00
QCaml/Notebooks/F12_matrix.ipynb

47 KiB

None <html> <head> </head>

Test of F12 matrix elements

Initialization

In [1]:
#cd "/home/scemama/QCaml";;
#use "topfind";;
#require "jupyter.notebook";;

#require "lacaml";;
#require "alcotest";;
#require "str";;
#require "bigarray";;
#require "zarith";;
#require "getopt";;
#directory "_build";;
#directory "_build/Basis";;
#directory "_build/CI";;
#directory "_build/MOBasis";;
#directory "_build/Nuclei";;
#directory "_build/Parallel";;
#directory "_build/Perturbation";;
#directory "_build/SCF";;
#directory "_build/Utils";;
/home/scemama/qp2/external/opam/4.07.1/lib/bytes: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/base64: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/base64/base64.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/ocaml/compiler-libs: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/ocaml/compiler-libs/ocamlcommon.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/result: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/result/result.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/ppx_deriving/runtime: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/ppx_deriving/runtime/ppx_deriving_runtime.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/ppx_deriving_yojson/runtime: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/ppx_deriving_yojson/runtime/ppx_deriving_yojson_runtime.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/ocaml/unix.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/uuidm: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/uuidm/uuidm.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/easy-format: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/easy-format/easy_format.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/biniou: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/biniou/biniou.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/yojson: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/yojson/yojson.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/jupyter: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/jupyter/jupyter.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/jupyter/notebook: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/jupyter/notebook/jupyter_notebook.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/ocaml/bigarray.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/lacaml: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/lacaml/lacaml.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/astring: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/astring/astring.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/cmdliner: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/cmdliner/cmdliner.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/seq: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/stdlib-shims: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/stdlib-shims/stdlib_shims.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/fmt: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/fmt/fmt.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/fmt/fmt_cli.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/fmt/fmt_tty.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/alcotest: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/alcotest/alcotest.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/ocaml/str.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/zarith: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/zarith/zarith.cma: loaded
/home/scemama/qp2/external/opam/4.07.1/lib/getopt: added to search path
/home/scemama/qp2/external/opam/4.07.1/lib/getopt/getopt.cma: loaded

Modules to load

In [2]:
#load "Constants.cmo";;
#load_rec "Util.cma";;
#load_rec "Matrix.cmo";;
#load_rec "Simulation.cmo";;
#load_rec "Spindeterminant.cmo";;
#load_rec "Determinant.cmo";;
#load_rec "HartreeFock.cmo";;
#load_rec "MOBasis.cmo";;
#load_rec "F12CI.cmo";;

open Lacaml.D;;

Printers

In [3]:
#install_printer AngularMomentum.pp_string ;;
#install_printer Basis.pp ;;
#install_printer Charge.pp ;;
#install_printer Coordinate.pp ;;
#install_printer Vector.pp;;
#install_printer Matrix.pp;;
#install_printer Util.pp_float_2darray;;
#install_printer Util.pp_float_array;;
#install_printer Util.pp_matrix;;
#install_printer HartreeFock.pp ;;
#install_printer Fock.pp ;;
#install_printer MOClass.pp ;;
let pp_mo ppf t = MOBasis.pp ~start:1 ~finish:0 ppf t ;;
#install_printer pp_mo;;
#install_printer DeterminantSpace.pp;;
#install_printer SpindeterminantSpace.pp;;
#install_printer Bitstring.pp;;
Out[3]:
val pp_mo : Format.formatter -> MOBasis.t -> unit = <fun>

Run

Simulation

In [4]:
let basis_filename  = "/home/scemama/qp2/data/basis/6-31g" 
let aux_basis_filename = "/home/scemama/qp2/data/basis/cc-pvdz" 
let nuclei = Nuclei.of_zmt_string "be" 
let frozen_core = false
let multiplicity = 1
let state = 1

let basis =  Basis.of_nuclei_and_basis_filenames ~nuclei [basis_filename] 
let aux_basis =  Basis.of_nuclei_and_basis_filenames ~nuclei (basis_filename :: aux_basis_filename :: []) 
let f12 = F12factor.gaussian_geminal 1.0 
let charge = 0 


let simulation =
    Simulation.make 
        ~f12 ~charge ~multiplicity ~nuclei
        ~cartesian:true
        basis
Out[4]:
val basis_filename : string = "/home/scemama/qp2/data/basis/6-31g"
Out[4]:
val aux_basis_filename : string = "/home/scemama/qp2/data/basis/cc-pvdz"
Out[4]:
val nuclei : Nuclei.t = [|(Element.Be,   0.0000   0.0000   0.0000)|]
Out[4]:
val frozen_core : bool = false
Out[4]:
val multiplicity : int = 1
Out[4]:
val state : int = 1
Out[4]:
val basis : Basis.t =
  
                          Atomic Basis set
                          ----------------

-----------------------------------------------------------------------
 #   Angular   Coordinates (Bohr)       Exponents       Coefficients
    Momentum  X        Y        Z
-----------------------------------------------------------------------
  1-3  S   0.0000   0.0000   0.0000   1.26458570e+03    1.94480000e-03
                                      1.89936810e+02    1.48351000e-02
                                      4.31590890e+01    7.20906000e-02
                                      1.20986630e+01    2.37154200e-01
                                      3.80632320e+00    4.69198700e-01
                                      1.27289030e+00    3.56520200e-01
                                    
                                      3.19646310e+00   -1.12648700e-01
                                      7.47813300e-01   -2.29506400e-01
                                      2.19966300e-01    1.18691670e+00
                                    
                                      8.23099000e-02    1.00000000e+00
                                    
                                    
-----------------------------------------------------------------------
  3-8  P   0.0000   0.0000   0.0000   3.19646310e+00    5.59802000e-02
                                      7.47813300e-01    2.61550600e-01
                                      2.19966300e-01    7.93972300e-01
                                    
                                      8.23099000e-02    1.00000000e+00
                                    
                                    
-----------------------------------------------------------------------

Out[4]:
val aux_basis : Basis.t =
  
                          Atomic Basis set
                          ----------------

-----------------------------------------------------------------------
 #   Angular   Coordinates (Bohr)       Exponents       Coefficients
    Momentum  X        Y        Z
-----------------------------------------------------------------------
  1-6  S   0.0000   0.0000   0.0000   1.26458570e+03    1.94480000e-03
                                      1.89936810e+02    1.48351000e-02
                                      4.31590890e+01    7.20906000e-02
                                      1.20986630e+01    2.37154200e-01
                                      3.80632320e+00    4.69198700e-01
                                      1.27289030e+00    3.56520200e-01
                                    
                                      3.19646310e+00   -1.12648700e-01
                                      7.47813300e-01   -2.29506400e-01
                                      2.19966300e-01    1.18691670e+00
                                    
                                      8.23099000e-02    1.00000000e+00
                                    
                                      2.94000000e+03    6.80000000e-04
                                      4.41200000e+02    5.23600000e-03
                                      1.00500000e+02    2.66060000e-02
                                      2.84300000e+01    9.99930000e-02
                                      9.16900000e+00    2.69702000e-01
                                      3.19600000e+00    4.51469000e-01
                                      1.15900000e+00    2.95074000e-01
                                      1.81100000e-01    1.25870000e-02
                                    
                                      2.94000000e+03   -1.23000000e-04
                                      4.41200000e+02   -9.66000000e-04
                                      1.00500000e+02   -4.83100000e-03
                                      2.84300000e+01   -1.93140000e-02
                                      9.16900000e+00   -5.32800000e-02
                                      3.19600000e+00   -1.20723000e-01
                                      1.15900000e+00   -1.33435000e-01
                                      1.81100000e-01    5.30767000e-01
                                    
                                      5.89000000e-02    1.00000000e+00
                                    
                                    
-----------------------------------------------------------------------
  3-14 P   0.0000   0.0000   0.0000   3.19646310e+00    5.59802000e-02
                                      7.47813300e-01    2.61550600e-01
                                      2.19966300e-01    7.93972300e-01
                                    
                                      8.23099000e-02    1.00000000e+00
                                    
                                      3.61900000e+00    2.91110000e-02
                                      7.11000000e-01    1.69365000e-01
                                      1.95100000e-01    5.13458000e-01
                                    
                                      6.01800000e-02    1.00000000e+00
                                    
                                    
-----------------------------------------------------------------------
 19-24 D   0.0000   0.0000   0.0000   2.38000000e-01    1.00000000e+00
                                    
                                    
-----------------------------------------------------------------------

Out[4]:
val f12 : F12factor.t =
  {F12factor.expo_s = 1.;
   gaussian =
    {GaussianOperator.coef_g =
      [  -0.314400  -0.303700  -0.168100  -0.098110  -0.060240  -0.037260 ];
     expo_sg =
      [   0.220900   1.004000   3.622000  12.160000  45.870000 254.400000 ];
     expo_sg_inv =
      [   4.526935   0.996016   0.276091   0.082237   0.021801   0.003931 ]}}
Out[4]:
val charge : int = 0
Out[4]:
val simulation : Simulation.t = <abstr>

Hartree-Fock

In [5]:
let hf =  HartreeFock.make ~guess:`Hcore  simulation  ;;

let mo_basis = MOBasis.of_hartree_fock hf
15 significant shell pairs computed in 0.004974 seconds
1
2
5
6
Computed ERIs in 0.026928 seconds
MOs =


          -- 1 --     -- 2 --    -- 3 --   -- 4 --      -- 5 --
            1    0.997996    -0.22266          0         0           -0
            2   0.0161427    0.288767 2.2404E-15         0 -7.73804E-16
            3           0 3.58344E-16   0.258415  0.037609    0.0381979
                      ...         ...        ...       ...          ...
            7           0           0    0.78727  0.114442     0.116234
            8           0           0  -0.128237 0.0798944     0.789475
            9           0           0  -0.100874  0.791587   -0.0964853
      

            -- 6 --      -- 7 --     -- 8 --      -- 9 --
            1    0.00338551            0          -0            0
            2       2.01724 -3.80748E-15 4.70544E-15 -6.99768E-16
            3   1.56069E-15        1.292    0.249105    0.0981672
                        ...          ...         ...          ...
            7   -2.3622E-15     -1.05652    -0.20374   -0.0802898
            8   1.64398E-15     0.172096   -0.528064     -0.92522
            9   2.61906E-15     0.135375   -0.918775     0.549573
      
Out[5]:
val hf : HartreeFock.t = 
======================================================================
                        Restricted Hartree-Fock                      
======================================================================

    ------------------------------------------------------------
        #     HF energy       Convergence  HOMO-LUMO
    ------------------------------------------------------------
        1    -14.35428398      3.4264e-01     0.3789
        2    -14.52767889      1.8460e-01     0.3848
        3    -14.56058094      7.7052e-02     0.3856
        4    -14.56582672      3.0375e-02     0.3848
        5    -14.56662378      1.1794e-02     0.3842
        6    -14.56676403      1.7857e-06     0.3837
        7    -14.56676404      1.7598e-08     0.3837
        8    -14.56676403      1.3644e-09     0.3837
    ------------------------------------------------------------


    ============================================================
               One-electron energy  -19.1171562840
                           Kinetic   14.6787428206
                         Potential  -33.7958991046
      --------------------------------------------------------  
               Two-electron energy    4.5503922505
                           Coulomb    7.2329463384
                          Exchange   -2.6825540879
      --------------------------------------------------------  
                           HF HOMO   -8.1986650549
                           HF LUMO    2.2431802579
                      HF LUMO-LUMO   10.4418453128
      --------------------------------------------------------  
               Electronic   energy  -14.5667640335
               Nuclear   repulsion    0.0000000000
               Hartree-Fock energy  -14.5667640335
    ============================================================
    

Out[5]:
val mo_basis : MOBasis.t =
  Eigenvalues:    -4.706891    -0.301295     0.082435     0.082435     0.082435 
            -- 1 --     -- 2 --    -- 3 --   -- 4 --      -- 5 --
      1    0.997996    -0.22266          0         0           -0
      2   0.0161427    0.288767 2.2404E-15         0 -7.73804E-16
      3           0 3.58344E-16   0.258415  0.037609    0.0381979
                ...         ...        ...       ...          ...
      7           0           0    0.78727  0.114442     0.116234
      8           0           0  -0.128237 0.0798944     0.789475
      9           0           0  -0.100874  0.791587   -0.0964853
  
  Eigenvalues:     0.439754     0.464931     0.464931     0.464931 
              -- 6 --      -- 7 --     -- 8 --      -- 9 --
      1    0.00338551            0          -0            0
      2       2.01724 -3.80748E-15 4.70544E-15 -6.99768E-16
      3   1.56069E-15        1.292    0.249105    0.0981672
                  ...          ...         ...          ...
      7   -2.3622E-15     -1.05652    -0.20374   -0.0802898
      8   1.64398E-15     0.172096   -0.528064     -0.92522
      9   2.61906E-15     0.135375   -0.918775     0.549573
  
  

FCI-F12

Notations:

  • $\langle ij || kl \rangle = \int \phi_i(r_1) \phi_j(r_2) \frac{1}{r_{12}} \phi_k(r1) \phi_l(r2) $
  • $\left[ ij || kl \right] = \int \phi_i(r_1) \phi_j(r_2) f_{12} \phi_k(r1) \phi_l(r2) $

Common functions

In [6]:
let f12 = Util.of_some @@ Simulation.f12 simulation 

let mo_num = MOBasis.size mo_basis 

let pp_spindet = Spindeterminant.pp mo_num

let pp_det = Determinant.pp mo_num

;;

#install_printer pp_spindet ;;
#install_printer pp_det ;;
Out[6]:
val f12 : F12factor.t =
  {F12factor.expo_s = 1.;
   gaussian =
    {GaussianOperator.coef_g =
      [  -0.314400  -0.303700  -0.168100  -0.098110  -0.060240  -0.037260 ];
     expo_sg =
      [   0.220900   1.004000   3.622000  12.160000  45.870000 254.400000 ];
     expo_sg_inv =
      [   4.526935   0.996016   0.276091   0.082237   0.021801   0.003931 ]}}
Out[6]:
val mo_num : int = 9
Out[6]:
val pp_spindet : Format.formatter -> Spindeterminant.t -> unit = <fun>
Out[6]:
val pp_det : Format.formatter -> Determinant.t -> unit = <fun>

let simulation_aux = let charge = Charge.to_int @@ Simulation.charge simulation and multiplicity = Electrons.multiplicity @@ Simulation.electrons simulation and nuclei = Simulation.nuclei simulation in let general_basis = Basis.general_basis @@ Simulation.basis simulation in GeneralBasis.combine [ general_basis ; GeneralBasis.read aux_basis_filename ] |> Basis.of_nuclei_and_general_basis nuclei |> Simulation.make ~f12 ~charge ~multiplicity ~nuclei let aux_basis = MOBasis.of_mo_basis simulation_aux mo_basis let () = ignore @@ MOBasis.f12_ints aux_basis let () = ignore @@ MOBasis.two_e_ints aux_basis

Determinant-based functions

Integrals

$\langle I | \hat{H} | J \rangle = \begin{cases} \sum_i h_{ii} + \frac{1}{2} \sum_{ij} \langle ij || ij \rangle \text{ when } |J\rangle = |I\rangle \\ h_{ik} + \sum_{j} \langle ij || kj \rangle \text{ when } |J\rangle = \hat{T}_i^k |I\rangle \\ \langle ij || kl \rangle \text{ when } |J\rangle = \hat{T}_{ij}^{kl} |I\rangle \\ \end{cases}$

$\langle I | \hat{F} | J \rangle = \begin{cases} \sum_i f_{ii} + \frac{1}{2} \sum_{ij} \langle ij || ij \rangle \text{ when } |J\rangle = |I\rangle \\ f_{ik} + \sum_{j} \langle ij || kj \rangle \text{ when } |J\rangle = \hat{T}_i^k |I\rangle \\ \langle ij || kl \rangle \text{ when } |J\rangle = \hat{T}_{ij}^{kl} |I\rangle \\ \end{cases}$

In [7]:
let cancel_singles = false 

let f12_integrals mo_basis =

  
  let two_e_ints  = MOBasis.f12_ints mo_basis in
  let f2 i j k l s s' =
      let ijkl = F12.get_phys two_e_ints i j k l in
      let ijlk = F12.get_phys two_e_ints i j l k in
      if s' <> s then
        ijkl 
      else
        (ijkl -. ijlk) 
  in
  ( (fun _ _ _ -> 0.),
    (if cancel_singles then
        (fun i j k l s s' ->
        (* Required to cancel out single excitations *)
           if (i=k && j<>l) || (j=l && i<>k) then
              0.
           else
              f2 i j k l s s'
        ) 
    else f2),
    None
  )

let h_ij mo_basis ki kj =
  let integrals =
    List.map (fun f -> f mo_basis)
      [ CI.h_integrals ]
  in
  CIMatrixElement.make integrals ki kj 
  |> List.hd


let f_ij mo_basis ki kj =
  let integrals =
    List.map (fun f -> f mo_basis)
      [ f12_integrals ]
  in
  CIMatrixElement.make integrals ki kj 
  |> List.hd                                                                                  


let hf_ij mo_basis ki kj =
  let integrals =
    List.map (fun f -> f mo_basis)
      [ CI.h_integrals ; f12_integrals ]
  in
  CIMatrixElement.make integrals ki kj
Out[7]:
val cancel_singles : bool = false
Out[7]:
val f12_integrals :
  MOBasis.t ->
  ('a -> 'b -> 'c -> float) *
  (int -> int -> int -> int -> 'd -> 'd -> float) * 'e option = <fun>
Out[7]:
val h_ij : MOBasis.t -> CIMatrixElement.De.t -> CIMatrixElement.De.t -> float =
  <fun>
Out[7]:
val f_ij : MOBasis.t -> CIMatrixElement.De.t -> CIMatrixElement.De.t -> float =
  <fun>
Out[7]:
val hf_ij :
  MOBasis.t -> CIMatrixElement.De.t -> CIMatrixElement.De.t -> float list =
  <fun>

Determinant space

In [8]:
Spindeterminant.of_list 10 [1; 3 ; 5; 7]
Out[8]:
- : Spindeterminant.t =
+1 +-+-+-+---------------------------------------------------------
In [9]:
let det_space = 
(*
    DeterminantSpace.fci_f12_of_mo_basis  aux_basis  ~frozen_core  mo_num
    *)
    SpindeterminantSpace.fci_of_mo_basis  mo_basis  ~frozen_core (Electrons.n_alfa @@ Simulation.electrons simulation)
Out[9]:
val det_space : SpindeterminantSpace.t =
   [       0 +1 ++--------------------------------------------------------------
           1 +1 --+-------------------------------------------------------------
           2 +1 ---+------------------------------------------------------------
           3 +1 ----+-----------------------------------------------------------
           4 +1 +----+----------------------------------------------------------
           5 +1 -+---+----------------------------------------------------------
           6 +1 --+--+----------------------------------------------------------
           7 +1 ---+-+----------------------------------------------------------
           8 +1 ----++----------------------------------------------------------
           9 +1 ------+---------------------------------------------------------
          10 +1 +++----+--------------------------------------------------------
          11 +1 ---+---+--------------------------------------------------------
          12 +1 ----+--+--------------------------------------------------------
          13 +1 -----+-+--------------------------------------------------------
          14 +1 ++----++--------------------------------------------------------
          15 +1 --+---++--------------------------------------------------------
          16 +1 ---+--++--------------------------------------------------------
          17 +1 ----+-++--------------------------------------------------------
          18 +1 +----+++--------------------------------------------------------
          19 +1 -+---+++--------------------------------------------------------
          20 +1 --+--+++--------------------------------------------------------
          21 +1 ---+-+++--------------------------------------------------------
          22 +1 ----++++--------------------------------------------------------
          23 +1 +++-----+-------------------------------------------------------
          24 +1 ---+----+-------------------------------------------------------
          25 +1 ----+---+-------------------------------------------------------
          26 +1 +----+--+-------------------------------------------------------
          27 +1 -+---+--+-------------------------------------------------------
          28 +1 --+--+--+-------------------------------------------------------
          29 +1 ---+-+--+-------------------------------------------------------
          30 +1 ----++--+-------------------------------------------------------
          31 +1 +-----+-+-------------------------------------------------------
          32 +1 -+----+-+-------------------------------------------------------
          33 +1 --+---+-+-------------------------------------------------------
          34 +1 ---+--+-+-------------------------------------------------------
          35 +1 ----+-+-+-------------------------------------------------------
    ]

unsigned int v; // current permutation of bits unsigned int w; // next permutation of bits unsigned int t = v | (v - 1); // t gets v's least significant 0 bits set to 1 // Next set to 1 the most significant bit to change, // set to 0 the least significant ones, and add the necessary 1 bits. w = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(v) + 1));

In [51]:
let _ = 
    let open Bitstring in
(*

    let u = Bitstring.of_int 63 in

    let t  = logor u @@ minus_one u in
    let not_t = lognot t in
    let neg_not_t = neg not_t in
    
    shift_right
        (minus_one @@ logand not_t neg_not_t) 
        ( (trailing_zeros u) + 1),
        *)
    popcount (Bitstring.of_int 1)
Out[51]:
- : int = 31
In [33]:
let elec_num = Electrons.n_elec @@ Simulation.electrons simulation

let alfa_num = Electrons.n_alfa @@ Simulation.electrons simulation

let mo_class = MOClass.fci ~frozen_core mo_basis 


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
                   
let occ_mask    = m (MOClass.core_mos    mo_class)

let active_mask = m (MOClass.active_mos  mo_class)


let neg_active_mask = Bitstring.lognot active_mask 

  (* Here we generate the FCI space and filter out unwanted determinants
     with excitations involving the core electrons. This should be improved. *)
     
let permtutations m n =                                                                   
  let open Bitstring in
  let rec aux k u rest =
    if k=1 then
      List.rev (u :: rest)
    else
      let t   = (logor u (minus_one u)) in
      let t'  = plus_one t in
      let t'' = shift_right (minus_one (logand (lognot t) (neg @@ lognot t))) (trailing_zeros u + 1) in                                                             
      (*
      let t'' = shift_right (minus_one (logand (lognot t) t')) (trailing_zeros u + 1) in
      *)
      (aux [@tailcall]) (k-1) (logor t' t'') (u :: rest)
  in
  aux (Util.binom n m) (minus_one (shift_left_one n m)) []

     
let spin_determinants =
    Bitstring.permtutations alfa_num mo_num
    (*
    |> List.filter (fun b -> Bitstring.logand neg_active_mask b = occ_mask)
    |> List.map (fun b -> Spindeterminant.of_bitstring b)
    |> Array.of_list
    *)
Out[33]:
val elec_num : int = 4
Out[33]:
val alfa_num : int = 2
Out[33]:
val mo_class : MOClass.t =
  [Active 1;Active 2;Active 3;Active 4;Active 5;Active 6;Active 7;Active 8;
  Active 9]
Out[33]:
val m : int list -> Bitstring.t = <fun>
Out[33]:
val occ_mask : Bitstring.t =
  ----------------------------------------------------------------
Out[33]:
val active_mask : Bitstring.t =
  +++++++++-------------------------------------------------------
Out[33]:
val neg_active_mask : Bitstring.t =
  ---------+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Out[33]:
val permtutations : int -> int -> Bitstring.t list = <fun>
Out[33]:
val spin_determinants : Bitstring.t list =
  [++--------------------------------------------------------------;
   --+-------------------------------------------------------------;
   ---+------------------------------------------------------------;
   ----+-----------------------------------------------------------;
   -----+----------------------------------------------------------;
   ++----+---------------------------------------------------------;
   --+---+---------------------------------------------------------;
   ---+--+---------------------------------------------------------;
   ----+-+---------------------------------------------------------;
   +----++---------------------------------------------------------;
   -+---++---------------------------------------------------------;
   --+--++---------------------------------------------------------;
   ---+-++---------------------------------------------------------;
   ----+++---------------------------------------------------------;
   +------+--------------------------------------------------------;
   -+-----+--------------------------------------------------------;
   --+----+--------------------------------------------------------;
   ---+---+--------------------------------------------------------;
   ----+--+--------------------------------------------------------;
   +----+-+--------------------------------------------------------;
   -+---+-+--------------------------------------------------------;
   --+--+-+--------------------------------------------------------;
   ---+-+-+--------------------------------------------------------;
   ----++-+--------------------------------------------------------;
   +-----++--------------------------------------------------------;
   -+----++--------------------------------------------------------;
   --+---++--------------------------------------------------------;
   ---+--++--------------------------------------------------------;
   ----+-++--------------------------------------------------------;
   +----+++--------------------------------------------------------;
   -+---+++--------------------------------------------------------;
   --+--+++--------------------------------------------------------;
   ---+-+++--------------------------------------------------------;
   ----++++--------------------------------------------------------;
   +-------+-------------------------------------------------------;
   -+------+-------------------------------------------------------]

let ci = CI.make ~n_states:state det_space let ci_coef, ci_energy = Lazy.force ci.eigensystem

Creates a function f : Determinant.t -> bool that returns true when the determinant has one or two electrons in the CABS.

let is_a_double det_space = let mo_class = DeterminantSpace.mo_class det_space in let mo_num = Array.length @@ MOClass.mo_class_array mo_class 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 aux_mask = m (MOClass.auxiliary_mos mo_class) in fun k -> let alfa = Determinant.alfa k |> Spindeterminant.bitstring in let beta = Determinant.beta k |> Spindeterminant.bitstring in let a = Bitstring.logand aux_mask alfa and b = Bitstring.logand aux_mask beta in match Bitstring.popcount a + Bitstring.popcount b with | 2 | 1 -> true | 0 | _ -> false

Permutation operator $p_{12}$ that generates a new determinant with electrons 1 and 2 swapped.

let p12 det_space = let mo_class = DeterminantSpace.mo_class det_space in let mo_num = Array.length @@ MOClass.mo_class_array mo_class 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 aux_mask = m (MOClass.auxiliary_mos mo_class) in let not_aux_mask = Bitstring.(shift_left_one mo_num (mo_num-1) |> minus_one |> logxor aux_mask) in fun k -> let alfa = Determinant.alfa k |> Spindeterminant.bitstring in let beta = Determinant.beta k |> Spindeterminant.bitstring in let a = Bitstring.logand aux_mask alfa and b = Bitstring.logand aux_mask beta in match Bitstring.popcount a, Bitstring.popcount b with | 2, 0 | 0, 2 -> Some (Determinant.negate_phase k) | 1, 1 -> Some (Determinant.of_spindeterminants (Spindeterminant.of_bitstring @@ Bitstring.(logor b (logand not_aux_mask alfa)) ) (Spindeterminant.of_bitstring @@ Bitstring.(logor a (logand not_aux_mask beta)) ) ) | 1, 0 | 0, 1 -> Some k | _ -> None

Determinants of the FCI space

let in_dets = DeterminantSpace.determinant_stream ci.CI.det_space |> Util.stream_to_list

Integral-based functions

In [ ]:

</html>