10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-11-07 06:33:39 +01:00
QCaml/SCF/Guess.ml

81 lines
2.0 KiB
OCaml
Raw Normal View History

2018-05-31 16:46:45 +02:00
open Lacaml.D
open Util
type guess =
| Hcore of Mat.t
| Huckel of Mat.t
type t = guess
2018-06-13 17:49:58 +02:00
module Ao = AOBasis
2018-05-31 16:46:45 +02:00
module El = Electrons
2018-06-13 19:03:42 +02:00
module Ov = Overlap
2018-05-31 16:46:45 +02:00
2018-06-13 17:49:58 +02:00
let hcore_guess ao_basis =
2018-06-13 19:03:42 +02:00
let eN_ints = Lazy.force ao_basis.Ao.eN_ints |> NucInt.matrix
and kin_ints = Lazy.force ao_basis.Ao.kin_ints |> KinInt.matrix
2018-05-31 16:46:45 +02:00
in
Mat.add eN_ints kin_ints
2018-06-13 17:49:58 +02:00
let huckel_guess ao_basis =
2018-05-31 16:46:45 +02:00
let c = 0.5 *. 1.75 in
2018-06-13 17:49:58 +02:00
let ao_num = Basis.size ao_basis.Ao.basis in
2018-06-13 19:03:42 +02:00
let eN_ints = Lazy.force ao_basis.Ao.eN_ints |> NucInt.matrix
and kin_ints = Lazy.force ao_basis.Ao.kin_ints |> KinInt.matrix
and overlap = Lazy.force ao_basis.Ao.overlap |> Ov.matrix
2018-06-13 17:49:58 +02:00
and m_X = Lazy.force ao_basis.Ao.ortho
2018-05-31 16:46:45 +02:00
in
let diag = Array.init (ao_num+1) (fun i -> if i=0 then 0. else
eN_ints.{i,i} +. kin_ints.{i,i})
in
2018-06-13 17:49:58 +02:00
function
| 0 -> invalid_arg "Huckel guess needs a non-zero number of occupied MOs."
| nocc ->
2018-06-27 13:13:59 +02:00
let density = gemm ~alpha:2. ~transb:`T ~k:nocc m_X m_X in
let fock = Fock.make ~density ao_basis in
let m_F = fock.Fock.fock in
2018-06-13 17:49:58 +02:00
for j=1 to ao_num do
for i=1 to ao_num do
if (i <> j) then
m_F.{i,j} <- c *. overlap.{i,j} *. (diag.(i) +. diag.(j)) (*TODO Pseudo *)
done;
2018-05-31 16:46:45 +02:00
done;
2018-06-13 17:49:58 +02:00
m_F
2018-05-31 16:46:45 +02:00
2018-06-13 17:49:58 +02:00
let make ?(nocc=0) ~guess ao_basis =
2018-05-31 16:46:45 +02:00
match guess with
2018-06-13 17:49:58 +02:00
| `Hcore -> Hcore (hcore_guess ao_basis)
| `Huckel -> Huckel (huckel_guess ao_basis nocc)
2018-05-31 16:46:45 +02:00
2018-07-04 20:24:51 +02:00
let test_case ao_basis =
let test_hcore () =
match make ~guess:`Hcore ao_basis with
| Hcore matrix ->
let a = Lacaml.D.Mat.to_array matrix in
let reference =
Lacaml.D.Mat.add
(Lazy.force ao_basis.AOBasis.eN_ints |> NucInt.matrix)
(Lazy.force ao_basis.AOBasis.kin_ints |> KinInt.matrix)
|> Lacaml.D.Mat.to_array
in
Array.iteri (fun i x ->
2018-07-05 00:39:17 +02:00
let message =
Printf.sprintf "Guess line %d" (i)
in
Alcotest.(check (array (float 1.e-15))) message a.(i) x) reference
2018-07-04 20:24:51 +02:00
| _ -> assert false
in
[
"HCore", `Quick, test_hcore;
]