2018-05-31 16:46:45 +02:00
|
|
|
open Lacaml.D
|
|
|
|
open Util
|
|
|
|
|
|
|
|
type guess =
|
|
|
|
| Hcore of Mat.t
|
|
|
|
| Huckel of Mat.t
|
2019-03-04 19:01:54 +01:00
|
|
|
| Matrix of Mat.t
|
2018-05-31 16:46:45 +02:00
|
|
|
|
|
|
|
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 =
|
2019-02-20 18:24:44 +01:00
|
|
|
let eN_ints = Ao.eN_ints ao_basis |> NucInt.matrix
|
|
|
|
and kin_ints = Ao.kin_ints ao_basis |> 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
|
2019-02-20 18:24:44 +01:00
|
|
|
let eN_ints = Ao.eN_ints ao_basis |> NucInt.matrix
|
|
|
|
and kin_ints = Ao.kin_ints ao_basis |> KinInt.matrix
|
2019-03-05 00:39:23 +01:00
|
|
|
in
|
|
|
|
let m_F =
|
|
|
|
Mat.add eN_ints kin_ints
|
|
|
|
in
|
|
|
|
let ao_num = Ao.basis ao_basis |> Basis.size
|
2019-02-20 18:24:44 +01:00
|
|
|
and overlap = Ao.overlap ao_basis |> Ov.matrix
|
2018-05-31 16:46:45 +02:00
|
|
|
in
|
2019-03-05 00:39:23 +01:00
|
|
|
let diag = Vec.init ao_num (fun i ->
|
|
|
|
m_F.{i,i} )
|
2018-05-31 16:46:45 +02:00
|
|
|
in
|
|
|
|
|
2018-06-13 17:49:58 +02:00
|
|
|
function
|
|
|
|
| 0 -> invalid_arg "Huckel guess needs a non-zero number of occupied MOs."
|
2019-03-05 00:39:23 +01:00
|
|
|
| nocc ->
|
|
|
|
Mat.init_cols ao_num ao_num (fun i j ->
|
|
|
|
if (i<>j) then
|
2019-03-05 01:12:13 +01:00
|
|
|
if (diag.{i} +. diag.{j}) < 0. then
|
2019-03-05 00:39:23 +01:00
|
|
|
c *. overlap.{i,j} *. (diag.{i} +. diag.{j}) +. m_F.{i,j} (*TODO Pseudo *)
|
|
|
|
else
|
|
|
|
m_F.{i,j} (*TODO Pseudo *)
|
|
|
|
else
|
|
|
|
diag.{i}
|
|
|
|
)
|
2018-06-13 17:49:58 +02:00
|
|
|
|
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)
|
2019-03-04 19:01:54 +01:00
|
|
|
| `Matrix m -> Matrix m
|
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
|
2019-02-20 18:24:44 +01:00
|
|
|
(AOBasis.eN_ints ao_basis |> NucInt.matrix)
|
|
|
|
(AOBasis.kin_ints ao_basis |> KinInt.matrix)
|
2018-07-04 20:24:51 +02:00
|
|
|
|> 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;
|
|
|
|
]
|
|
|
|
|