mirror of
https://gitlab.com/scemama/QCaml.git
synced 2024-12-06 20:43:33 +01:00
Pretty print RHF
This commit is contained in:
parent
25b3c41c50
commit
eb54ee8ab5
@ -4,7 +4,13 @@ open Constants
|
||||
|
||||
|
||||
|
||||
type t = Mat.t
|
||||
type t =
|
||||
{
|
||||
fock : Mat.t ;
|
||||
core : Mat.t ;
|
||||
coulomb : Mat.t ;
|
||||
exchange : Mat.t ;
|
||||
}
|
||||
|
||||
let make ~density simulation =
|
||||
let m_P = density
|
||||
@ -15,24 +21,40 @@ let make ~density simulation =
|
||||
let nBas = Mat.dim1 m_T
|
||||
in
|
||||
|
||||
let m_F = Mat.add m_T m_V in
|
||||
let m_Hc = Mat.add m_T m_V
|
||||
and m_J = Mat.make0 nBas nBas
|
||||
and m_K = Mat.make0 nBas nBas
|
||||
in
|
||||
for sigma = 1 to nBas do
|
||||
for nu = 1 to nBas do
|
||||
for lambda = 1 to nBas do
|
||||
let p = m_P.{lambda,sigma} in
|
||||
if abs_float p > epsilon then
|
||||
for mu = 1 to nu do
|
||||
m_F.{mu,nu} <- m_F.{mu,nu} +. p *.
|
||||
(ERI.get_phys m_G mu lambda nu sigma
|
||||
-. 0.5 *. ERI.get_phys m_G mu lambda sigma nu)
|
||||
m_J.{mu,nu} <- m_J.{mu,nu} +. p *.
|
||||
ERI.get_phys m_G mu lambda nu sigma
|
||||
done
|
||||
done
|
||||
done
|
||||
done;
|
||||
for nu = 1 to nBas do
|
||||
for sigma = 1 to nBas do
|
||||
for lambda = 1 to nBas do
|
||||
let p = 0.5 *. m_P.{lambda,sigma} in
|
||||
if abs_float p > epsilon then
|
||||
for mu = 1 to nu do
|
||||
m_K.{mu,nu} <- m_K.{mu,nu} -. p *.
|
||||
ERI.get_phys m_G mu lambda sigma nu
|
||||
done
|
||||
done
|
||||
done
|
||||
done;
|
||||
for nu = 1 to nBas do
|
||||
for mu = 1 to nu do
|
||||
m_F.{nu,mu} <- m_F.{mu,nu}
|
||||
m_J.{nu,mu} <- m_J.{mu,nu};
|
||||
m_K.{nu,mu} <- m_K.{mu,nu};
|
||||
done
|
||||
done;
|
||||
m_F
|
||||
{ fock = Mat.add m_Hc @@ Mat.add m_J m_K ;
|
||||
core = m_Hc ; coulomb = m_J ; exchange = m_K }
|
||||
|
||||
|
@ -7,3 +7,5 @@ let make ?guess simulation =
|
||||
else
|
||||
invalid_arg "UHF or ROHF not implemented"
|
||||
|
||||
|
||||
let to_string = HartreeFock_type.to_string
|
||||
|
@ -1,11 +1,44 @@
|
||||
type t =
|
||||
{
|
||||
guess : Guess.t;
|
||||
eigenvectors : Lacaml.D.Mat.t ;
|
||||
eigenvalues : Lacaml.D.Vec.t ;
|
||||
energy : float ;
|
||||
iterations : float array;
|
||||
guess : Guess.t;
|
||||
eigenvectors : Lacaml.D.Mat.t ;
|
||||
eigenvalues : Lacaml.D.Vec.t ;
|
||||
nocc : int;
|
||||
energy : float ;
|
||||
nuclear_repulsion : float ;
|
||||
kin_energy : float ;
|
||||
eN_energy : float ;
|
||||
coulomb_energy : float ;
|
||||
exchange_energy : float ;
|
||||
iterations : (float * float * float) array;
|
||||
}
|
||||
|
||||
|
||||
let to_string hf_calc =
|
||||
let sprintf = Printf.sprintf in
|
||||
"
|
||||
=====================================================
|
||||
Hartree-Fock
|
||||
=====================================================
|
||||
# HF energy Convergence HOMO-LUMO
|
||||
---------------------------------------------------" ::
|
||||
Array.to_list (Array.mapi (fun i (e, c, g) ->
|
||||
sprintf " %5d %13.8f %11.4e %11.4f " (i+1) e c g) hf_calc.iterations)
|
||||
|
||||
@ [
|
||||
" =====================================================";
|
||||
sprintf "%20s energy %16.10f" "One-electron" (hf_calc.kin_energy +. hf_calc.eN_energy) ;
|
||||
sprintf "%20s energy %16.10f" "Kinetic " hf_calc.kin_energy ;
|
||||
sprintf "%20s energy %16.10f" "Potential" hf_calc.eN_energy ;
|
||||
" ---------------------------------------------------";
|
||||
sprintf "%20s energy %16.10f" "Two-electron" (hf_calc.coulomb_energy +. hf_calc.exchange_energy) ;
|
||||
sprintf "%20s energy %16.10f" "Coulomb" hf_calc.coulomb_energy ;
|
||||
sprintf "%20s energy %16.10f" "Exchange" hf_calc.exchange_energy ;
|
||||
" ---------------------------------------------------";
|
||||
sprintf "%20s energy %16.10f" "Electronic" (hf_calc.energy -. hf_calc.nuclear_repulsion);
|
||||
sprintf "%17s repulsion %16.10f" "Nuclear" hf_calc.coulomb_energy ;
|
||||
sprintf "%20s energy %16.10f" "Hartree-Fock" hf_calc.energy ;
|
||||
" =====================================================" ]
|
||||
|> String.concat "\n"
|
||||
|
||||
|
||||
|
@ -2,11 +2,20 @@
|
||||
|
||||
type t =
|
||||
{
|
||||
guess : Guess.t; (** Initial guess *)
|
||||
eigenvectors : Lacaml.D.Mat.t ; (** Final eigenvectors *)
|
||||
eigenvalues : Lacaml.D.Vec.t ; (** Final eigenvalues *)
|
||||
energy : float ; (** Final energy *)
|
||||
iterations : float array; (** Energies of all iterations *)
|
||||
guess : Guess.t; (** Initial guess *)
|
||||
eigenvectors : Lacaml.D.Mat.t ; (** Final eigenvectors *)
|
||||
eigenvalues : Lacaml.D.Vec.t ; (** Final eigenvalues *)
|
||||
nocc : int ; (** Number of occupied MOs *)
|
||||
energy : float ; (** Final energy *)
|
||||
nuclear_repulsion : float ; (** Nucleus-Nucleus potential energy *)
|
||||
kin_energy : float ; (** Kinetic energy *)
|
||||
eN_energy : float ; (** Electron-nucleus potential energy *)
|
||||
coulomb_energy : float ; (** Electron-Electron potential energy *)
|
||||
exchange_energy : float ; (** Exchange energy *)
|
||||
iterations : (float * float * float) array;
|
||||
(** Energy, convergence and HOMO-LUMO gap of all iterations *)
|
||||
}
|
||||
|
||||
val to_string : t -> string
|
||||
(** Results of a Hartree-Fock calculation pretty-printed in a string. *)
|
||||
|
||||
|
@ -10,6 +10,10 @@ let make ?guess:(guess=`Hcore) ?max_scf:(max_scf=64)
|
||||
simulation.electrons.Electrons.n_alpha
|
||||
in
|
||||
|
||||
let nuclear_repulsion =
|
||||
simulation.nuclear_repulsion
|
||||
in
|
||||
|
||||
(* Initial guess *)
|
||||
let guess =
|
||||
Guess.make ~guess simulation
|
||||
@ -21,18 +25,14 @@ let make ?guess:(guess=`Hcore) ?max_scf:(max_scf=64)
|
||||
in
|
||||
|
||||
|
||||
(* Core Hamiltonian *)
|
||||
let m_Hc =
|
||||
let m_T = Lazy.force simulation.kin_ints
|
||||
and m_V = Lazy.force simulation.eN_ints
|
||||
in Mat.add m_T m_V
|
||||
in
|
||||
|
||||
(* Overlap matrix *)
|
||||
let m_S =
|
||||
Lazy.force simulation.overlap
|
||||
in
|
||||
|
||||
let m_T = Lazy.force simulation.kin_ints
|
||||
and m_V = Lazy.force simulation.eN_ints
|
||||
in
|
||||
|
||||
(* SCF iterations *)
|
||||
let rec loop nSCF iterations m_C =
|
||||
@ -43,8 +43,11 @@ let make ?guess:(guess=`Hcore) ?max_scf:(max_scf=64)
|
||||
in
|
||||
|
||||
(* Fock matrix in AO basis *)
|
||||
let m_F =
|
||||
Fock.make ~density:m_P simulation
|
||||
let m_F, m_Hc, m_J, m_K =
|
||||
let x =
|
||||
Fock.make ~density:m_P simulation
|
||||
in
|
||||
x.Fock.fock, x.Fock.core, x.Fock.coulomb, x.Fock.exchange
|
||||
in
|
||||
|
||||
(* Fock matrix in MO basis *)
|
||||
@ -64,7 +67,7 @@ let make ?guess:(guess=`Hcore) ?max_scf:(max_scf=64)
|
||||
|
||||
(* Hartree-Fock energy *)
|
||||
let energy =
|
||||
simulation.nuclear_repulsion +. 0.5 *.
|
||||
nuclear_repulsion +. 0.5 *.
|
||||
Mat.gemm_trace m_P (Mat.add m_Hc m_F)
|
||||
in
|
||||
|
||||
@ -81,24 +84,34 @@ let make ?guess:(guess=`Hcore) ?max_scf:(max_scf=64)
|
||||
in
|
||||
|
||||
let converged =
|
||||
nSCF = max_scf || (abs_float commutator) < threshold_SCF
|
||||
nSCF = max_scf || (abs_float commutator) < threshold_SCF
|
||||
in
|
||||
|
||||
Printf.printf "%d %16.10f %10.4e\n%!" nSCF energy commutator;
|
||||
let gap =
|
||||
eigenvalues.{nocc+1} -. eigenvalues.{nocc};
|
||||
in
|
||||
|
||||
Printf.printf "%d %16.10f %11.4e %10.4f\n%!" nSCF energy commutator gap;
|
||||
|
||||
if not converged then
|
||||
loop (nSCF+1) (energy :: iterations) m_C
|
||||
loop (nSCF+1) ( (energy, commutator, gap) :: iterations) m_C
|
||||
else
|
||||
let iterations =
|
||||
List.rev iterations
|
||||
List.rev ( (energy, commutator, gap) :: iterations )
|
||||
|> Array.of_list
|
||||
in
|
||||
{ HartreeFock_type.
|
||||
nocc;
|
||||
guess ;
|
||||
eigenvectors = m_C ;
|
||||
eigenvalues ;
|
||||
energy = iterations.(Array.length iterations - 1) ;
|
||||
energy ;
|
||||
nuclear_repulsion;
|
||||
iterations ;
|
||||
kin_energy = Mat.gemm_trace m_P m_T;
|
||||
eN_energy = Mat.gemm_trace m_P m_V;
|
||||
coulomb_energy = 0.5 *. Mat.gemm_trace m_P m_J;
|
||||
exchange_energy = 0.5 *. Mat.gemm_trace m_P m_K;
|
||||
}
|
||||
in
|
||||
|
||||
|
@ -58,7 +58,10 @@ val array_product : float array -> float
|
||||
|
||||
|
||||
(** {2 Extension of the List module} *)
|
||||
|
||||
val list_some : 'a option list -> 'a list
|
||||
(** Filters out all [None] elements of the list, and returns the elements without
|
||||
the [Some]. *)
|
||||
|
||||
|
||||
(** {2 Linear algebra } *)
|
||||
@ -72,11 +75,12 @@ val xt_o_x : o:Lacaml.D.mat -> x:Lacaml.D.mat -> Lacaml.D.mat
|
||||
val canonical_ortho: ?thresh:float -> overlap:Lacaml.D.mat -> Lacaml.D.mat -> Lacaml.D.mat
|
||||
(** Canonical orthogonalization. [overlap] is the overlap matrix {% $\mathbf{S}$ %},
|
||||
and the last argument contains the vectors {% $\mathbf{C}$ %} to orthogonalize.
|
||||
|
||||
{%
|
||||
\begin{align}
|
||||
\mathbf{U\, D\, V^\dag} & = \mathbf{S} \\
|
||||
\mathbf{C_\bot} & = \mathbf{C\, U\, D^{-1/2}}
|
||||
\end{align}
|
||||
$$
|
||||
\mathbf{C_\bot} = \mathbf{C\, U\, D^{-1/2}}, \;
|
||||
\mathbf{U\, D\, V^\dag} = \mathbf{S}
|
||||
$$
|
||||
%}
|
||||
|
||||
*)
|
||||
|
@ -39,11 +39,9 @@ let run ~out =
|
||||
Simulation.of_filenames ~charge ~multiplicity ~nuclei:nuclei_file basis_file
|
||||
in
|
||||
|
||||
let _ =
|
||||
HartreeFock.make s
|
||||
in
|
||||
Printf.printf "Done.\n%!";
|
||||
()
|
||||
HartreeFock.make s
|
||||
|> HartreeFock.to_string
|
||||
|> print_endline
|
||||
|
||||
|
||||
let () =
|
||||
|
Loading…
Reference in New Issue
Block a user