10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-11-14 10:03:39 +01:00
QCaml/Basis/Overlap.ml

152 lines
3.6 KiB
OCaml
Raw Normal View History

2018-01-22 23:19:24 +01:00
open Util
2018-02-03 23:26:20 +01:00
open Constants
2018-02-09 00:37:25 +01:00
open Lacaml.D
type t = Mat.t
2018-02-23 15:49:27 +01:00
module Am = Angular_momentum
module Bs = Basis
module Co = Coordinate
module Cs = Contracted_shell
module Csp = ContractedShellPair
module Sp = ShellPair
2018-01-22 23:19:24 +01:00
(** Computes all the overlap integrals of the contracted shell pair *)
2018-01-23 00:48:45 +01:00
let contracted_class shell_a shell_b : float Zmap.t =
2018-01-22 23:19:24 +01:00
let shell_p =
2018-02-23 15:49:27 +01:00
Csp.create shell_a shell_b
2018-01-22 23:19:24 +01:00
in
(* Pre-computation of integral class indices *)
let class_indices =
2018-02-23 15:49:27 +01:00
Am.zkey_array (Am.Doublet (shell_a.totAngMom, shell_b.totAngMom))
2018-01-22 23:19:24 +01:00
in
let contracted_class =
Array.make (Array.length class_indices) 0.
in
2018-02-09 19:41:22 +01:00
let sp =
2018-02-23 15:49:27 +01:00
shell_p.Csp.shell_pairs
2018-02-09 19:41:22 +01:00
in
let center_ab =
2018-02-23 15:49:27 +01:00
shell_p.Csp.center_ab
2018-02-09 19:41:22 +01:00
in
let norm_coef_scale =
2018-02-23 15:49:27 +01:00
shell_p.Csp.norm_coef_scale
2018-02-09 19:41:22 +01:00
in
2018-01-22 23:19:24 +01:00
(* Compute all integrals in the shell for each pair of significant shell pairs *)
2018-02-09 19:41:22 +01:00
for ab=0 to (Array.length sp - 1)
2018-01-22 23:19:24 +01:00
do
let coef_prod =
2018-02-23 15:49:27 +01:00
shell_p.Csp.coef.(ab)
in
(** Screening on thr product of coefficients *)
if (abs_float coef_prod) > 1.e-4*.cutoff then
begin
let expo_inv =
2018-02-23 15:49:27 +01:00
shell_p.Csp.expo_inv.(ab)
in
2018-02-09 19:41:22 +01:00
let center_pa =
2018-02-23 15:49:27 +01:00
sp.(ab).Sp.center_a
in
Array.iteri (fun i key ->
let (angMomA,angMomB) =
let a = Zkey.to_int_array Zkey.Kind_6 key in
( [| a.(0) ; a.(1) ; a.(2) |],
[| a.(3) ; a.(4) ; a.(5) |] )
2018-01-22 23:19:24 +01:00
in
let f k =
2018-02-13 17:36:25 +01:00
let xyz = match k with
2018-02-23 15:49:27 +01:00
| 0 -> Co.X
| 1 -> Co.Y
| _ -> Co.Z
2018-02-13 17:36:25 +01:00
in
Overlap_primitives.hvrr (angMomA.(k), angMomB.(k))
expo_inv
2018-02-23 15:49:27 +01:00
(Co.get xyz center_ab,
Co.get xyz center_pa)
2018-01-22 23:19:24 +01:00
in
let norm = norm_coef_scale.(i) in
let integral = chop norm (fun () -> (f 0)*.(f 1)*.(f 2)) in
contracted_class.(i) <- contracted_class.(i) +. coef_prod *. integral
) class_indices
end
2018-01-22 23:19:24 +01:00
done;
let result =
Zmap.create (Array.length contracted_class)
in
Array.iteri (fun i key -> Zmap.add result key contracted_class.(i)) class_indices;
result
2018-02-09 00:37:25 +01:00
(** Create overlap matrix *)
let of_basis basis =
2018-02-19 16:01:13 +01:00
let to_powers x =
2018-01-22 23:19:24 +01:00
let open Zkey in
2018-02-19 16:01:13 +01:00
match to_powers Kind_3 x with
2018-01-22 23:19:24 +01:00
| Three x -> x
| _ -> assert false
in
2018-02-23 15:49:27 +01:00
let n = basis.Bs.size
and shell = basis.Bs.contracted_shells
2018-02-09 00:37:25 +01:00
in
let result = Mat.create n n in
for j=0 to (Array.length shell) - 1 do
for i=0 to j do
2018-01-22 23:19:24 +01:00
(* Compute all the integrals of the class *)
let cls =
2018-02-09 00:37:25 +01:00
contracted_class shell.(i) shell.(j)
2018-01-22 23:19:24 +01:00
in
2018-02-09 00:37:25 +01:00
Array.iteri (fun j_c powers_j ->
2018-02-23 15:49:27 +01:00
let j_c = shell.(j).index + j_c + 1 in
2018-02-19 16:01:13 +01:00
let xj = to_powers powers_j in
2018-02-09 00:37:25 +01:00
Array.iteri (fun i_c powers_i ->
2018-02-23 15:49:27 +01:00
let i_c = shell.(i).index + i_c + 1 in
2018-02-19 16:01:13 +01:00
let xi = to_powers powers_i in
2018-01-22 23:19:24 +01:00
let key =
2018-02-19 16:01:13 +01:00
Zkey.of_powers (Zkey.Six (xi,xj))
2018-01-22 23:19:24 +01:00
in
let value =
2018-02-09 00:37:25 +01:00
try Zmap.find cls key
2018-01-22 23:19:24 +01:00
with Not_found -> failwith "Bug in overlap integrals"
in
2018-02-21 17:06:24 +01:00
result.{i_c,j_c} <- value;
result.{j_c,i_c} <- value;
2018-02-23 15:49:27 +01:00
) shell.(i).powers
) shell.(j).powers
2018-02-09 00:37:25 +01:00
done;
done;
Mat.detri result;
result
(** Write all overlap integrals to a file *)
let to_file ~filename overlap =
let oc = open_out filename in
let n =
Mat.dim1 overlap
in
for j=1 to n do
for i=1 to j do
if (abs_float overlap.{i,j} > cutoff) then
Printf.fprintf oc "%4d %4d %20.12e\n" i j overlap.{i,j}
2018-01-22 23:19:24 +01:00
done;
done;
close_out oc
2018-02-21 17:06:24 +01:00