2020-10-09 09:47:57 +02:00
|
|
|
open Common
|
|
|
|
open Linear_algebra
|
2020-10-10 10:59:09 +02:00
|
|
|
open Gaussian
|
2020-09-26 12:02:53 +02:00
|
|
|
|
|
|
|
module Am = Angular_momentum
|
|
|
|
module Bs = Basis
|
|
|
|
module Cs = Contracted_shell
|
|
|
|
module Ov = Overlap
|
|
|
|
|
2020-10-02 18:55:19 +02:00
|
|
|
type t = (Bs.t, Bs.t) Matrix.t
|
|
|
|
|
2020-09-26 12:02:53 +02:00
|
|
|
|
|
|
|
|
|
|
|
let make_canonical ~thresh ~basis ~cartesian ~overlap =
|
|
|
|
|
2020-10-07 17:54:15 +02:00
|
|
|
let overlap_matrix = overlap in
|
2020-09-26 12:02:53 +02:00
|
|
|
|
|
|
|
let make_canonical_spherical basis =
|
|
|
|
let ao_num = Bs.size basis in
|
2020-10-02 18:55:19 +02:00
|
|
|
let cart_sphe : (Bs.t, Bs.t) Matrix.t = Matrix.make ao_num ao_num 0.
|
2020-09-26 12:02:53 +02:00
|
|
|
and i = ref 0
|
|
|
|
and n = ref 0 in
|
|
|
|
Array.iter (fun shell ->
|
|
|
|
let submatrix =
|
|
|
|
Spherical_to_cartesian.matrix (Cs.ang_mom shell)
|
2020-10-02 18:55:19 +02:00
|
|
|
|> Matrix.relabel
|
2020-09-26 12:02:53 +02:00
|
|
|
in
|
|
|
|
Matrix.copy_inplace ~b:cart_sphe ~br:(!i+1) ~bc:(!n+1) submatrix;
|
|
|
|
i := !i + Matrix.dim1 submatrix;
|
|
|
|
n := !n + Matrix.dim2 submatrix;
|
|
|
|
) (Bs.contracted_shells basis);
|
2020-10-02 18:55:19 +02:00
|
|
|
let s = Matrix.gemm_tn ~m:!n cart_sphe overlap_matrix in
|
|
|
|
let overlap_matrix = Matrix.gemm_nn s ~n:!n cart_sphe in
|
2020-09-26 12:02:53 +02:00
|
|
|
let s = Orthonormalization.canonical_ortho ~thresh ~overlap:overlap_matrix (Matrix.identity !n) in
|
2020-10-02 18:55:19 +02:00
|
|
|
Matrix.gemm_nn cart_sphe ~k:!n s
|
2020-09-26 12:02:53 +02:00
|
|
|
in
|
|
|
|
|
|
|
|
if cartesian then
|
|
|
|
Orthonormalization.canonical_ortho ~thresh ~overlap:overlap_matrix (Matrix.identity @@ Matrix.dim1 overlap_matrix)
|
|
|
|
else
|
|
|
|
match basis with
|
|
|
|
| None -> invalid_arg
|
|
|
|
"Basis.t is required when cartesian=false in make_canonical"
|
|
|
|
| Some basis -> make_canonical_spherical basis
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let make_lowdin ~thresh ~overlap =
|
|
|
|
|
|
|
|
let u_vec, u_val =
|
2020-10-07 17:54:15 +02:00
|
|
|
Matrix.diagonalize_symm overlap
|
2020-09-26 12:02:53 +02:00
|
|
|
in
|
|
|
|
|
|
|
|
Vector.iter (fun x -> if x < thresh then
|
|
|
|
invalid_arg (__FILE__^": make_lowdin") ) u_val;
|
|
|
|
|
|
|
|
let u_val = Vector.reci (Vector.sqrt u_val) in
|
|
|
|
|
|
|
|
let u_vec' =
|
2020-10-02 15:49:09 +02:00
|
|
|
Matrix.init_cols (Matrix.dim1 u_vec) (Matrix.dim2 u_vec)
|
2020-10-17 19:02:37 +02:00
|
|
|
(fun i j -> u_vec%:(i,j) *. (u_val%.(j)) )
|
2020-09-26 12:02:53 +02:00
|
|
|
in
|
2020-10-02 18:55:19 +02:00
|
|
|
Matrix.gemm_nt u_vec' u_vec
|
2020-09-26 12:02:53 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let make ?(thresh=1.e-12) ?basis ~cartesian overlap =
|
|
|
|
(*
|
|
|
|
make_lowdin ~thresh ~overlap
|
|
|
|
*)
|
|
|
|
make_canonical ~thresh ~basis ~cartesian ~overlap
|
|
|
|
|