10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-12-23 04:43:32 +01:00
QCaml/gaussian/lib/basis.ml

198 lines
5.4 KiB
OCaml
Raw Normal View History

2023-04-24 19:01:42 +02:00
type t =
2018-02-09 00:37:25 +01:00
{
2019-03-21 00:44:10 +01:00
size : int;
2020-09-26 12:02:53 +02:00
contracted_shells : Contracted_shell.t array ;
atomic_shells : Atomic_shell.t array lazy_t;
general_basis : General_basis.t ;
2018-02-09 00:37:25 +01:00
}
2020-09-26 12:02:53 +02:00
module As = Atomic_shell
module Cs = Contracted_shell
module Gb = General_basis
module Ps = Primitive_shell
2018-02-23 18:41:30 +01:00
2019-03-21 00:44:10 +01:00
let general_basis t = t.general_basis
2018-01-18 00:21:05 +01:00
2018-01-18 17:39:10 +01:00
(** Returns an array of the basis set per atom *)
2020-09-26 12:02:53 +02:00
let of_nuclei_and_general_basis nucl bas =
2018-03-20 14:11:31 +01:00
let index_ = ref 0 in
2023-04-24 19:01:42 +02:00
let contracted_shells =
2018-01-19 17:42:12 +01:00
Array.map (fun (e, center) ->
2018-03-20 14:11:31 +01:00
List.assoc e bas
2018-03-21 15:01:39 +01:00
|> Array.map (fun (ang_mom, shell) ->
2023-04-24 19:01:42 +02:00
let lc =
2018-03-14 16:22:08 +01:00
Array.map (fun Gb.{exponent ; coefficient} ->
2018-03-21 15:01:39 +01:00
coefficient, Ps.make ang_mom center exponent) shell
2018-02-06 18:12:19 +01:00
in
2018-03-20 14:11:31 +01:00
let result = Cs.make ~index:!index_ lc in
index_ := !index_ + Cs.size_of_shell result;
result
)
) nucl
2018-01-19 17:42:12 +01:00
|> Array.to_list
|> Array.concat
in
2018-03-20 15:16:24 +01:00
let atomic_shells = lazy(
2018-03-20 14:11:31 +01:00
let uniq_center_angmom =
2018-03-21 15:01:39 +01:00
Array.map (fun x -> Cs.center x, Cs.ang_mom x) contracted_shells
2018-03-20 14:11:31 +01:00
|> Array.to_list
|> List.sort_uniq compare
in
2023-04-24 19:01:42 +02:00
let csl =
2018-03-20 14:11:31 +01:00
Array.to_list contracted_shells
in
2018-03-21 15:01:39 +01:00
List.map (fun (center, ang_mom) ->
2023-04-24 19:01:42 +02:00
let a =
2018-03-21 15:01:39 +01:00
List.filter (fun x -> Cs.center x = center && Cs.ang_mom x = ang_mom) csl
2018-03-20 14:11:31 +01:00
|> Array.of_list
in
2018-03-20 15:16:24 +01:00
As.make ~index:(Cs.index a.(0)) a
2018-03-20 14:11:31 +01:00
) uniq_center_angmom
2018-03-20 15:16:24 +01:00
|> List.sort (fun x y -> compare (As.index x) (As.index y))
2018-03-20 14:11:31 +01:00
|> Array.of_list
) in
2019-03-21 00:44:10 +01:00
{ contracted_shells ; atomic_shells ; size = !index_;
2020-09-26 12:02:53 +02:00
general_basis = bas }
2018-03-20 14:11:31 +01:00
let size t = t.size
2018-03-20 14:11:31 +01:00
let atomic_shells t = Lazy.force t.atomic_shells
2018-03-20 14:11:31 +01:00
let contracted_shells t = t.contracted_shells
2018-02-09 00:37:25 +01:00
2018-01-18 00:21:05 +01:00
let to_string b =
2018-03-20 15:16:24 +01:00
let b = atomic_shells b in
2018-01-18 17:39:10 +01:00
let line ="
-----------------------------------------------------------------------
2023-04-24 19:01:42 +02:00
" in
2018-01-18 17:39:10 +01:00
"
Atomic Basis set
----------------
-----------------------------------------------------------------------
2018-01-19 17:42:12 +01:00
# Angular Coordinates (Bohr) Exponents Coefficients
Momentum X Y Z
2018-01-18 17:39:10 +01:00
-----------------------------------------------------------------------
"
2018-01-19 03:14:06 +01:00
^
2018-03-20 15:16:24 +01:00
( Array.map (fun p -> Format.(fprintf str_formatter "%a" As.pp p;
2018-03-16 00:23:47 +01:00
flush_str_formatter ())) b
2018-02-06 18:12:19 +01:00
|> Array.to_list
|> String.concat line
)
^ line
2017-12-30 19:06:07 +01:00
2018-02-23 18:41:30 +01:00
2023-04-24 19:01:42 +02:00
let of_nuclei_and_basis_filename ~nuclei filename =
let general_basis =
2020-09-26 12:02:53 +02:00
General_basis.read filename
2018-02-09 00:37:25 +01:00
in
2020-09-26 12:02:53 +02:00
of_nuclei_and_general_basis nuclei general_basis
2018-01-22 23:19:24 +01:00
2023-04-24 19:01:42 +02:00
let of_nuclei_and_basis_string ~nuclei str =
let general_basis =
2020-09-26 12:02:53 +02:00
General_basis.of_string str
2020-04-16 19:49:23 +02:00
in
2020-09-26 12:02:53 +02:00
of_nuclei_and_general_basis nuclei general_basis
2020-04-16 19:49:23 +02:00
2018-01-18 23:42:48 +01:00
2023-04-24 19:01:42 +02:00
let of_nuclei_and_basis_filenames ~nuclei filenames =
let general_basis =
2020-09-26 12:02:53 +02:00
General_basis.read_many filenames
in
2020-09-26 12:02:53 +02:00
of_nuclei_and_general_basis nuclei general_basis
2023-04-24 19:01:42 +02:00
let of_trexio f =
let nuclei = Particles.Nuclei.of_trexio f in
let shell_ang_mom = Trexio.read_basis_shell_ang_mom f
|> Array.map Common.Angular_momentum.of_int
in
let shell_index = Trexio.read_basis_shell_index f
|> Array.to_list
in
let nucleus_index = Trexio.read_basis_nucleus_index f
|> Array.to_list
in
let exponent = Trexio.read_basis_exponent f in
let coefficient = Trexio.read_basis_coefficient f in
let filter_indices ref_index full_array =
List.mapi (fun j idx ->
if idx = ref_index then Some j
else None) full_array
|> List.filter (function
| None -> false
| _ -> true)
|> List.map (function
| Some x -> x
| None -> assert false)
in
2023-06-16 18:27:23 +02:00
2023-04-24 19:01:42 +02:00
let index_ = ref 0 in
let contracted_shells =
Array.mapi (fun i (_,center) ->
let shell_indices = filter_indices i nucleus_index in
List.map (fun ishell ->
let prim_indices = filter_indices ishell shell_index in
let lc = List.map (fun k ->
coefficient.(k),
Ps.make shell_ang_mom.(ishell) center exponent.(k)) prim_indices
|> Array.of_list
in
let result = Cs.make ~index:!index_ lc in
index_ := !index_ + Cs.size_of_shell result;
result
) shell_indices
|> Array.of_list
) nuclei
|> Array.to_list
|> Array.concat
in
let atomic_shells = lazy(
let uniq_center_angmom =
Array.map (fun x -> Cs.center x, Cs.ang_mom x) contracted_shells
|> Array.to_list
|> List.sort_uniq compare
in
let csl =
Array.to_list contracted_shells
in
List.map (fun (center, ang_mom) ->
let a =
List.filter (fun x -> Cs.center x = center && Cs.ang_mom x = ang_mom) csl
|> Array.of_list
in
As.make ~index:(Cs.index a.(0)) a
) uniq_center_angmom
|> List.sort (fun x y -> compare (As.index x) (As.index y))
|> Array.of_list
) in
{ contracted_shells ; atomic_shells ; size = !index_;
general_basis = [];
}
2023-06-16 18:27:23 +02:00
let to_trexio _f _t =
failwith "Not implemented"
(*
Trexio.write_basis_type f "Gaussian" ;
Trexio.write_basis_shell_num f t.size;
let prim_num =
Array.fold_left (fun accu i -> accu + Array.length i) 0 t.contracted_shells
in
Trexio.read_basis_prim_num f prim_num;
let nucleus_index =
Array.map
in
let shell_factor = Trexio.read_basis_shell_factor f in
let prim_factor =
Trexio.read_basis_prim_factor f in
2023-04-24 19:01:42 +02:00
()
2023-06-16 18:27:23 +02:00
*)
2023-04-24 19:01:42 +02:00
2019-12-02 14:58:48 +01:00
let pp ppf t =
Format.fprintf ppf "@[%s@]" (to_string t)