quantum_package/ocaml/Gto.ml

126 lines
3.0 KiB
OCaml
Raw Permalink Normal View History

2016-01-25 15:44:15 +01:00
open Qptypes
2017-08-18 19:43:52 +02:00
open Sexplib.Std
2014-08-13 17:54:32 +02:00
exception GTO_Read_Failure of string
exception End_Of_Basis
2014-08-13 17:54:32 +02:00
type fmt =
| Gamess
| Gaussian
2014-08-13 17:54:32 +02:00
type t =
{ sym : Symmetry.t ;
lc : ((GaussianPrimitive.t * AO_coef.t) list)
2017-08-18 18:28:33 +02:00
} [@@deriving sexp]
2016-01-25 15:44:15 +01:00
2014-08-13 17:54:32 +02:00
let of_prim_coef_list pc =
2017-08-18 19:43:52 +02:00
let (p,c) = List.hd pc in
let sym = p.GaussianPrimitive.sym in
2014-08-13 17:54:32 +02:00
let rec check = function
| [] -> `OK
| (p,c)::tl ->
if p.GaussianPrimitive.sym <> sym then
2014-08-13 17:54:32 +02:00
`Failed
else
check tl
in
match check pc with
| `Failed -> raise (Failure "Failed in of_prim_coef_list")
| `OK ->
{ sym = sym ;
lc = pc
}
2016-01-25 15:44:15 +01:00
2014-08-13 17:54:32 +02:00
let read_one in_channel =
(* Fetch number of lines to read on first line *)
2017-12-29 16:06:35 +01:00
let buffer =
try input_line in_channel with
| End_of_file -> raise End_Of_Basis
in
2017-08-18 19:43:52 +02:00
if ( (String_ext.strip buffer) = "" ) then
raise End_Of_Basis;
2014-08-13 17:54:32 +02:00
let sym_str = String.sub buffer 0 2 in
let n_str = String.sub buffer 2 ((String.length buffer)-2) in
2017-08-18 19:43:52 +02:00
let sym = Symmetry.of_string (String_ext.strip sym_str) in
let n = int_of_string (String_ext.strip n_str) in
2014-08-13 17:54:32 +02:00
(* Read all the primitives *)
let rec read_lines result = function
| 0 -> result
| i ->
begin
let line_buffer = input_line in_channel in
let buffer = line_buffer
2017-08-18 19:43:52 +02:00
|> String_ext.split ~on:' '
|> List.filter (fun x -> x <> "")
2014-08-13 17:54:32 +02:00
in
match buffer with
| [ j ; expo ; coef ] ->
begin
2017-08-18 19:43:52 +02:00
let coef =
Str.global_replace (Str.regexp "D") "e" coef
in
2014-10-27 01:14:18 +01:00
let p =
GaussianPrimitive.of_sym_expo sym
2017-08-18 19:43:52 +02:00
(AO_expo.of_float (float_of_string expo) )
and c = AO_coef.of_float (float_of_string coef) in
2014-08-13 17:54:32 +02:00
read_lines ( (p,c)::result) (i-1)
end
| _ -> raise (GTO_Read_Failure line_buffer)
end
in read_lines [] n
2014-10-25 21:24:21 +02:00
|> List.rev
2014-08-13 17:54:32 +02:00
|> of_prim_coef_list
2016-01-25 15:44:15 +01:00
2014-08-13 17:54:32 +02:00
(** Write the GTO in Gamess format *)
let to_string_gamess { sym = sym ; lc = lc } =
2014-10-26 12:46:17 +01:00
let result =
Printf.sprintf "%s %3d" (Symmetry.to_string sym) (List.length lc)
in
let rec do_work accu i = function
| [] -> List.rev accu
| (p,c)::tail ->
let p = AO_expo.to_float p.GaussianPrimitive.expo
2014-10-26 12:46:17 +01:00
and c = AO_coef.to_float c
in
let result =
Printf.sprintf "%3d %16f %16f" i p c
in
do_work (result::accu) (i+1) tail
in
(do_work [result] 1 lc)
2017-08-18 19:43:52 +02:00
|> String.concat "\n"
2016-01-25 15:44:15 +01:00
2014-10-26 12:46:17 +01:00
(** Write the GTO in Gaussian format *)
let to_string_gaussian { sym = sym ; lc = lc } =
let result =
Printf.sprintf "%s %3d 1.00" (Symmetry.to_string sym) (List.length lc)
in
let rec do_work accu i = function
| [] -> List.rev accu
| (p,c)::tail ->
let p = AO_expo.to_float p.GaussianPrimitive.expo
and c = AO_coef.to_float c
in
let result =
Printf.sprintf "%15.7f %15.7f" p c
in
do_work (result::accu) (i+1) tail
in
(do_work [result] 1 lc)
2017-08-18 19:43:52 +02:00
|> String.concat "\n"
(** Transform the gto to a string *)
let to_string ?(fmt=Gamess) =
match fmt with
| Gamess -> to_string_gamess
| Gaussian -> to_string_gaussian