mirror of
https://gitlab.com/scemama/QCaml.git
synced 2024-08-28 23:42:00 +02:00
Introduced AOBasis
This commit is contained in:
parent
d954d5ecdb
commit
9e5933f0d0
2
.merlin
2
.merlin
@ -1,7 +1,9 @@
|
|||||||
PKG str unix bigarray lacaml
|
PKG str unix bigarray lacaml
|
||||||
S .
|
S .
|
||||||
S Nuclei
|
S Nuclei
|
||||||
|
S CI
|
||||||
S Utils
|
S Utils
|
||||||
S Basis
|
S Basis
|
||||||
S SCF
|
S SCF
|
||||||
|
S MOBasis
|
||||||
B _build/**
|
B _build/**
|
||||||
|
43
Basis/AOBasis.ml
Normal file
43
Basis/AOBasis.ml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
open Lacaml.D
|
||||||
|
|
||||||
|
type t =
|
||||||
|
{
|
||||||
|
basis : Basis.t ;
|
||||||
|
overlap : Overlap.t lazy_t;
|
||||||
|
ortho : Orthonormalization.t lazy_t;
|
||||||
|
eN_ints : NucInt.t lazy_t;
|
||||||
|
ee_ints : ERI.t lazy_t;
|
||||||
|
kin_ints : KinInt.t lazy_t;
|
||||||
|
cartesian : bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
let make ~cartesian ~basis nuclei =
|
||||||
|
|
||||||
|
let overlap = lazy (
|
||||||
|
Overlap.of_basis basis
|
||||||
|
) in
|
||||||
|
|
||||||
|
let ortho = lazy (
|
||||||
|
Orthonormalization.make ~cartesian ~basis (Lazy.force overlap)
|
||||||
|
) in
|
||||||
|
|
||||||
|
let eN_ints = lazy (
|
||||||
|
NucInt.of_basis_nuclei ~basis nuclei
|
||||||
|
) in
|
||||||
|
|
||||||
|
let kin_ints = lazy (
|
||||||
|
KinInt.of_basis basis
|
||||||
|
) in
|
||||||
|
|
||||||
|
let ee_ints = lazy (
|
||||||
|
ERI.of_basis basis
|
||||||
|
) in
|
||||||
|
|
||||||
|
{ basis ; overlap ; ortho ; eN_ints ; kin_ints ; ee_ints ;
|
||||||
|
cartesian ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
19
Basis/AOBasis.mli
Normal file
19
Basis/AOBasis.mli
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
(** Data structure for Atomic Orbitals. *)
|
||||||
|
|
||||||
|
type t =
|
||||||
|
{
|
||||||
|
basis : Basis.t ; (* One-electron basis set *)
|
||||||
|
overlap : Overlap.t lazy_t; (* Overlap matrix *)
|
||||||
|
ortho : Orthonormalization.t lazy_t; (* Orthonormalization matrix of the overlap *)
|
||||||
|
eN_ints : NucInt.t lazy_t; (* Electron-nucleus potential integrals *)
|
||||||
|
ee_ints : ERI.t lazy_t; (* Electron-electron potential integrals *)
|
||||||
|
kin_ints : KinInt.t lazy_t; (* Kinetic energy integrals *)
|
||||||
|
cartesian : bool ; (* If true, use cartesian Gaussians (6d, 10f, ...) *)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val make : cartesian:bool -> basis:Basis.t -> Nuclei.t -> t
|
||||||
|
(** Creates the data structure for atomic orbitals from a {Basis.t} and the
|
||||||
|
molecular geometry {Nuclei.t} *)
|
||||||
|
|
||||||
|
|
17
Basis/KinInt.mli
Normal file
17
Basis/KinInt.mli
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
(** Electronic kinetic energy integrals, expressed as a matrix in a {Basis.t}.
|
||||||
|
|
||||||
|
{%
|
||||||
|
$$
|
||||||
|
T_{ij} = \left \langle \chi_i \left| -\frac{1}{2} \Delta \right| \chi_j \right \rangle
|
||||||
|
$$
|
||||||
|
%}
|
||||||
|
*)
|
||||||
|
|
||||||
|
type t = Lacaml.D.Mat.t
|
||||||
|
|
||||||
|
val of_basis : Basis.t -> t
|
||||||
|
(** Build from a {Basis.t}. *)
|
||||||
|
|
||||||
|
val to_file : filename:string -> t -> unit
|
||||||
|
(** Write the integrals in a file. *)
|
||||||
|
|
@ -41,7 +41,7 @@ let cutoff2 = cutoff *. cutoff
|
|||||||
exception NullIntegral
|
exception NullIntegral
|
||||||
|
|
||||||
|
|
||||||
let of_basis_nuclei basis nuclei =
|
let of_basis_nuclei ~basis nuclei =
|
||||||
let to_powers x =
|
let to_powers x =
|
||||||
let open Zkey in
|
let open Zkey in
|
||||||
match to_powers x with
|
match to_powers x with
|
||||||
|
15
Basis/NucInt.mli
Normal file
15
Basis/NucInt.mli
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
(** Electron-Nucleus attractive potential integrals, expressed as a matrix in a {Basis.t}.
|
||||||
|
|
||||||
|
{% $$
|
||||||
|
V_{ij} = \left \langle \chi_i \left| \sum_A \frac{-Z_A}{ | \mathbf{r} - \mathbf{R}_A |} \right| \chi_j \right \rangle
|
||||||
|
$$ %}
|
||||||
|
|
||||||
|
*)
|
||||||
|
|
||||||
|
type t = Lacaml.D.Mat.t
|
||||||
|
|
||||||
|
val of_basis_nuclei : basis:Basis.t -> Nuclei.t -> t
|
||||||
|
(** Build from a {Basis.t} and the nuclei (coordinates and charges). *)
|
||||||
|
|
||||||
|
val to_file : filename:string -> t -> unit
|
||||||
|
(** Write the integrals in a file. *)
|
11
SCF/Fock.ml
11
SCF/Fock.ml
@ -3,7 +3,6 @@ open Simulation
|
|||||||
open Constants
|
open Constants
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
{
|
{
|
||||||
fock : Mat.t ;
|
fock : Mat.t ;
|
||||||
@ -12,11 +11,13 @@ type t =
|
|||||||
exchange : Mat.t ;
|
exchange : Mat.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
let make ~density simulation =
|
module Ao = AOBasis
|
||||||
|
|
||||||
|
let make ~density ao_basis =
|
||||||
let m_P = density
|
let m_P = density
|
||||||
and m_T = Lazy.force simulation.kin_ints
|
and m_T = Lazy.force ao_basis.Ao.kin_ints
|
||||||
and m_V = Lazy.force simulation.eN_ints
|
and m_V = Lazy.force ao_basis.Ao.eN_ints
|
||||||
and m_G = Lazy.force simulation.ee_ints
|
and m_G = Lazy.force ao_basis.Ao.ee_ints
|
||||||
in
|
in
|
||||||
let nBas = Mat.dim1 m_T
|
let nBas = Mat.dim1 m_T
|
||||||
in
|
in
|
||||||
|
47
SCF/Guess.ml
47
SCF/Guess.ml
@ -7,43 +7,44 @@ type guess =
|
|||||||
|
|
||||||
type t = guess
|
type t = guess
|
||||||
|
|
||||||
module Si = Simulation
|
module Ao = AOBasis
|
||||||
module El = Electrons
|
module El = Electrons
|
||||||
|
|
||||||
let hcore_guess simulation =
|
let hcore_guess ao_basis =
|
||||||
let eN_ints = Lazy.force simulation.Si.eN_ints
|
let eN_ints = Lazy.force ao_basis.Ao.eN_ints
|
||||||
and kin_ints = Lazy.force simulation.Si.kin_ints
|
and kin_ints = Lazy.force ao_basis.Ao.kin_ints
|
||||||
in
|
in
|
||||||
Mat.add eN_ints kin_ints
|
Mat.add eN_ints kin_ints
|
||||||
|
|
||||||
|
|
||||||
let huckel_guess simulation =
|
let huckel_guess ao_basis =
|
||||||
let c = 0.5 *. 1.75 in
|
let c = 0.5 *. 1.75 in
|
||||||
let ao_num = Basis.size simulation.Si.basis in
|
let ao_num = Basis.size ao_basis.Ao.basis in
|
||||||
let eN_ints = Lazy.force simulation.Si.eN_ints
|
let eN_ints = Lazy.force ao_basis.Ao.eN_ints
|
||||||
and kin_ints = Lazy.force simulation.Si.kin_ints
|
and kin_ints = Lazy.force ao_basis.Ao.kin_ints
|
||||||
and overlap = Lazy.force simulation.Si.overlap
|
and overlap = Lazy.force ao_basis.Ao.overlap
|
||||||
and m_X = Lazy.force simulation.Si.overlap_ortho
|
and m_X = Lazy.force ao_basis.Ao.ortho
|
||||||
in
|
in
|
||||||
let diag = Array.init (ao_num+1) (fun i -> if i=0 then 0. else
|
let diag = Array.init (ao_num+1) (fun i -> if i=0 then 0. else
|
||||||
eN_ints.{i,i} +. kin_ints.{i,i})
|
eN_ints.{i,i} +. kin_ints.{i,i})
|
||||||
in
|
in
|
||||||
|
|
||||||
let nocc =
|
function
|
||||||
simulation.Si.electrons.El.n_alpha
|
| 0 -> invalid_arg "Huckel guess needs a non-zero number of occupied MOs."
|
||||||
in
|
| nocc ->
|
||||||
let m_F = (Fock.make ~density:(gemm ~alpha:2. ~transb:`T ~k:nocc m_X m_X) simulation).Fock.fock in
|
let m_F = (Fock.make ~density:(gemm ~alpha:2. ~transb:`T ~k:nocc m_X m_X) ao_basis).Fock.fock in
|
||||||
for j=1 to ao_num do
|
for j=1 to ao_num do
|
||||||
for i=1 to ao_num do
|
for i=1 to ao_num do
|
||||||
if (i <> j) then
|
if (i <> j) then
|
||||||
m_F.{i,j} <- c *. overlap.{i,j} *. (diag.(i) +. diag.(j)) (*TODO Pseudo *)
|
m_F.{i,j} <- c *. overlap.{i,j} *. (diag.(i) +. diag.(j)) (*TODO Pseudo *)
|
||||||
|
done;
|
||||||
done;
|
done;
|
||||||
done;
|
m_F
|
||||||
m_F
|
|
||||||
|
|
||||||
let make ~guess simulation =
|
|
||||||
|
let make ?(nocc=0) ~guess ao_basis =
|
||||||
match guess with
|
match guess with
|
||||||
| `Hcore -> Hcore (hcore_guess simulation)
|
| `Hcore -> Hcore (hcore_guess ao_basis)
|
||||||
| `Huckel -> Huckel (huckel_guess simulation)
|
| `Huckel -> Huckel (huckel_guess ao_basis nocc)
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ type guess =
|
|||||||
type t = guess
|
type t = guess
|
||||||
|
|
||||||
|
|
||||||
val make : guess:[ `Hcore | `Huckel ] -> Simulation.t -> t
|
val make : ?nocc:int -> guess:[ `Hcore | `Huckel ] -> AOBasis.t -> t
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
25
SCF/RHF.ml
25
SCF/RHF.ml
@ -1,37 +1,44 @@
|
|||||||
open Util
|
open Util
|
||||||
open Lacaml.D
|
open Lacaml.D
|
||||||
open Simulation
|
|
||||||
|
module Si = Simulation
|
||||||
|
module El = Electrons
|
||||||
|
module Ao = AOBasis
|
||||||
|
|
||||||
let make ?guess:(guess=`Huckel) ?max_scf:(max_scf=64) ?level_shift:(level_shift=0.1)
|
let make ?guess:(guess=`Huckel) ?max_scf:(max_scf=64) ?level_shift:(level_shift=0.1)
|
||||||
?threshold_SCF:(threshold_SCF=1.e-5) simulation =
|
?threshold_SCF:(threshold_SCF=1.e-5) simulation =
|
||||||
|
|
||||||
(* Number of occupied MOs *)
|
(* Number of occupied MOs *)
|
||||||
let nocc =
|
let nocc =
|
||||||
simulation.electrons.Electrons.n_alpha
|
simulation.Si.electrons.El.n_alpha
|
||||||
in
|
in
|
||||||
|
|
||||||
let nuclear_repulsion =
|
let nuclear_repulsion =
|
||||||
simulation.nuclear_repulsion
|
simulation.Si.nuclear_repulsion
|
||||||
|
in
|
||||||
|
|
||||||
|
let ao_basis =
|
||||||
|
simulation.Si.ao_basis
|
||||||
in
|
in
|
||||||
|
|
||||||
(* Initial guess *)
|
(* Initial guess *)
|
||||||
let guess =
|
let guess =
|
||||||
Guess.make ~guess simulation
|
Guess.make ~nocc ~guess ao_basis
|
||||||
in
|
in
|
||||||
|
|
||||||
(* Orthogonalization matrix *)
|
(* Orthogonalization matrix *)
|
||||||
let m_X =
|
let m_X =
|
||||||
Lazy.force simulation.overlap_ortho
|
Lazy.force ao_basis.Ao.ortho
|
||||||
in
|
in
|
||||||
|
|
||||||
|
|
||||||
(* Overlap matrix *)
|
(* Overlap matrix *)
|
||||||
let m_S =
|
let m_S =
|
||||||
Lazy.force simulation.overlap
|
Lazy.force ao_basis.Ao.overlap
|
||||||
in
|
in
|
||||||
|
|
||||||
let m_T = Lazy.force simulation.kin_ints
|
let m_T = Lazy.force ao_basis.Ao.kin_ints
|
||||||
and m_V = Lazy.force simulation.eN_ints
|
and m_V = Lazy.force ao_basis.Ao.eN_ints
|
||||||
in
|
in
|
||||||
|
|
||||||
(* Level shift in MO basis *)
|
(* Level shift in MO basis *)
|
||||||
@ -53,7 +60,7 @@ let make ?guess:(guess=`Huckel) ?max_scf:(max_scf=64) ?level_shift:(level_shift=
|
|||||||
(* Fock matrix in AO basis *)
|
(* Fock matrix in AO basis *)
|
||||||
let m_F, m_Hc, m_J, m_K =
|
let m_F, m_Hc, m_J, m_K =
|
||||||
let x =
|
let x =
|
||||||
Fock.make ~density:m_P simulation
|
Fock.make ~density:m_P ao_basis
|
||||||
in
|
in
|
||||||
x.Fock.fock, x.Fock.core, x.Fock.coulomb, x.Fock.exchange
|
x.Fock.fock, x.Fock.core, x.Fock.coulomb, x.Fock.exchange
|
||||||
in
|
in
|
||||||
|
@ -1,15 +1,10 @@
|
|||||||
type t = {
|
type t = {
|
||||||
charge : Charge.t;
|
charge : Charge.t;
|
||||||
electrons : Electrons.t ;
|
electrons : Electrons.t ;
|
||||||
basis : Basis.t;
|
nuclei : Nuclei.t;
|
||||||
nuclei : Nuclei.t;
|
basis : Basis.t;
|
||||||
overlap : Overlap.t lazy_t;
|
ao_basis : AOBasis.t;
|
||||||
overlap_ortho : Orthonormalization.t lazy_t;
|
|
||||||
eN_ints : NucInt.t lazy_t;
|
|
||||||
kin_ints : KinInt.t lazy_t;
|
|
||||||
ee_ints : ERI.t lazy_t;
|
|
||||||
nuclear_repulsion : float;
|
nuclear_repulsion : float;
|
||||||
cartesian : bool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let make ?cartesian:(cartesian=false)
|
let make ?cartesian:(cartesian=false)
|
||||||
@ -26,21 +21,22 @@ let make ?cartesian:(cartesian=false)
|
|||||||
let electrons =
|
let electrons =
|
||||||
Electrons.make ~multiplicity ~charge nuclei
|
Electrons.make ~multiplicity ~charge nuclei
|
||||||
in
|
in
|
||||||
|
|
||||||
let charge =
|
let charge =
|
||||||
Charge.(Nuclei.charge nuclei + Electrons.charge electrons)
|
Charge.(Nuclei.charge nuclei + Electrons.charge electrons)
|
||||||
in
|
in
|
||||||
let overlap =
|
|
||||||
lazy (Overlap.of_basis basis)
|
let ao_basis =
|
||||||
|
AOBasis.make ~basis ~cartesian nuclei
|
||||||
in
|
in
|
||||||
|
|
||||||
|
let nuclear_repulsion =
|
||||||
|
Nuclei.repulsion nuclei
|
||||||
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
charge ;
|
charge ; basis ; nuclei ; electrons ; ao_basis ;
|
||||||
basis ; nuclei ; electrons ; overlap ;
|
nuclear_repulsion ;
|
||||||
overlap_ortho = lazy (Orthonormalization.make ~cartesian ~basis (Lazy.force overlap));
|
|
||||||
eN_ints = lazy (NucInt.of_basis_nuclei basis nuclei);
|
|
||||||
kin_ints = lazy (KinInt.of_basis basis);
|
|
||||||
ee_ints = lazy (ERI.of_basis basis);
|
|
||||||
nuclear_repulsion = Nuclei.repulsion nuclei;
|
|
||||||
cartesian ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,10 +36,11 @@ let run ~out =
|
|||||||
print_float s.Simulation.nuclear_repulsion; print_newline ();
|
print_float s.Simulation.nuclear_repulsion; print_newline ();
|
||||||
print_endline @@ Basis.to_string s.Simulation.basis;
|
print_endline @@ Basis.to_string s.Simulation.basis;
|
||||||
|
|
||||||
let overlap = Lazy.force s.Simulation.overlap in
|
let ao_basis = s.Simulation.ao_basis in
|
||||||
let eN_ints = Lazy.force s.Simulation.eN_ints in
|
let overlap = Lazy.force ao_basis.AOBasis.overlap in
|
||||||
let kin_ints = Lazy.force s.Simulation.kin_ints in
|
let eN_ints = Lazy.force ao_basis.AOBasis.eN_ints in
|
||||||
let ee_ints = Lazy.force s.Simulation.ee_ints in
|
let kin_ints = Lazy.force ao_basis.AOBasis.kin_ints in
|
||||||
|
let ee_ints = Lazy.force ao_basis.AOBasis.ee_ints in
|
||||||
Overlap.to_file ~filename:(out_file^".overlap") overlap;
|
Overlap.to_file ~filename:(out_file^".overlap") overlap;
|
||||||
NucInt.to_file ~filename:(out_file^".nuc") eN_ints;
|
NucInt.to_file ~filename:(out_file^".nuc") eN_ints;
|
||||||
KinInt.to_file ~filename:(out_file^".kin") kin_ints;
|
KinInt.to_file ~filename:(out_file^".kin") kin_ints;
|
||||||
|
Loading…
Reference in New Issue
Block a user