From b4ab7c39bdfea444477802b51d647952e8b397bc Mon Sep 17 00:00:00 2001 From: Anthony Scemama Date: Fri, 2 Feb 2018 10:10:05 +0100 Subject: [PATCH] Store ERI in a genarray --- Basis/ERI.ml | 70 ++++++++++++++++++++++++++++++++++++++++++++++------ _tags | 2 +- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/Basis/ERI.ml b/Basis/ERI.ml index 6f59e41..1edacad 100644 --- a/Basis/ERI.ml +++ b/Basis/ERI.ml @@ -2,6 +2,7 @@ open Util open Constants +open Bigarray (** (00|00)^m : Fundamental electron repulsion integral $ \int \int \phi_p(r1) 1/r_{12} \phi_q(r2) dr_1 dr_2 $ @@ -44,6 +45,19 @@ type n_cls = { n : int ; cls : Z.t array } *) exception NullIntegral +(* +(** Unique index for integral *) +let index i j k l = + let f i k = + let (p,r) = + if i <= k then (i,k) else (k,i) + in p+ (r*r-r)/2 + in + let p = f i k and q = f j l in + f p q +*) + + (** Write all integrals to a file with the convention *) let to_file ~filename basis = let to_int_tuple x = @@ -63,6 +77,8 @@ let to_file ~filename basis = Printf.printf "%d shells\n" (Array.length basis); (* Pre-compute diagonal integrals for Schwartz *) + let t0 = Unix.gettimeofday () in + let schwartz = Array.map (fun pair_array -> Array.map (fun pair -> let cls = @@ -81,7 +97,21 @@ let to_file ~filename basis = icount := !icount + 1; done; done; - Printf.printf "%d shell pairs\n" !icount; + Printf.printf "%d shell pairs computed in %f seconds\n" !icount (Unix.gettimeofday () -. t0); + + let eri_array = + + let n = ref 0 in + for i=0 to (Array.length basis) - 1 do + n := !n + (Array.length (basis.(i).Contracted_shell.powers)) + done; + let n = !n in + Genarray.create Float64 c_layout [| n ; n ; n ; n|] + in + Genarray.fill eri_array 0.; + + (* Compute ERIs *) + let t0 = Unix.gettimeofday () in let inn = ref 0 and out = ref 0 in @@ -147,12 +177,8 @@ let to_file ~filename basis = in if (abs_float value > cutoff) then (inn := !inn + 1; - (* - assert ((i_c, k_c, j_c, l_c) <> (-1,0,0,0)); - *) - Printf.fprintf oc "%4d %4d %4d %4d %20.12e\n" - i_c k_c j_c l_c value - ) + eri_array.{(i_c-1),(k_c-1),(j_c-1),(l_c-1)} <- value; + ) else out := !out + 1; ) basis.(l).Contracted_shell.powers @@ -165,6 +191,36 @@ let to_file ~filename basis = with NullIntegral -> () done; done; + + Printf.printf "Computed %d non-zero ERIs in %f seconds\n" !inn (Unix.gettimeofday () -. t0); + + (* Print ERIs *) + for i=0 to (Array.length basis) - 1 do + print_int basis.(i).Contracted_shell.indice ; print_newline (); + for j=0 to i do + for k=0 to i do + for l=0 to k do + (* Write the data in the output file *) + Array.iteri (fun i_c _ -> + let i_c = basis.(i).Contracted_shell.indice + i_c + 1 in + Array.iteri (fun j_c _ -> + let j_c = basis.(j).Contracted_shell.indice + j_c + 1 in + Array.iteri (fun k_c _ -> + let k_c = basis.(k).Contracted_shell.indice + k_c + 1 in + Array.iteri (fun l_c _ -> + let l_c = basis.(l).Contracted_shell.indice + l_c + 1 in + let value = eri_array.{(i_c-1),(k_c-1),(j_c-1),(l_c-1)} in + if (value <> 0.) then + Printf.fprintf oc "%4d %4d %4d %4d %20.12e\n" + i_c k_c j_c l_c value; + ) basis.(l).Contracted_shell.powers + ) basis.(k).Contracted_shell.powers + ) basis.(j).Contracted_shell.powers + ) basis.(i).Contracted_shell.powers; + done; + done; + done; + done; Printf.printf "In: %d Out:%d\n" !inn !out ; close_out oc diff --git a/_tags b/_tags index fa92e5c..870e647 100644 --- a/_tags +++ b/_tags @@ -1,3 +1,3 @@ -true: package(str,zarith) +true: package(str,unix,bigarray,zarith) <*.byte> : linkdep(Utils/math_functions.o), custom <*.native>: linkdep(Utils/math_functions.o)