10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-06-02 11:25:19 +02:00
QCaml/CI/CI.ml

139 lines
3.4 KiB
OCaml
Raw Normal View History

2019-02-22 00:18:32 +01:00
open Lacaml.D
2019-02-22 19:19:11 +01:00
module Ds = Determinant_space
2019-02-22 00:18:32 +01:00
type t =
{
2019-02-22 19:19:11 +01:00
det_space : Ds.t ;
2019-02-26 11:58:53 +01:00
m_H : Mat.t lazy_t ;
m_S2 : Mat.t lazy_t ;
2019-02-22 00:18:32 +01:00
eigensystem : (Mat.t * Vec.t) lazy_t;
}
let det_space t = t.det_space
2019-02-26 11:58:53 +01:00
let m_H t = Lazy.force t.m_H
2019-02-22 00:18:32 +01:00
2019-02-26 11:58:53 +01:00
let m_S2 t = Lazy.force t.m_S2
2019-02-22 19:19:11 +01:00
2019-02-22 00:18:32 +01:00
let eigensystem t = Lazy.force t.eigensystem
let eigenvectors t =
let (x,_) = eigensystem t in x
let eigenvalues t =
let (_,x) = eigensystem t in x
2019-02-22 19:19:11 +01:00
let h_integrals mo_basis =
2019-02-22 00:18:32 +01:00
let one_e_ints = MOBasis.one_e_ints mo_basis
and two_e_ints = MOBasis.two_e_ints mo_basis
in
2019-02-22 19:19:11 +01:00
( (fun i j _ -> one_e_ints.{i,j}),
(fun i j k l s s' ->
if s' = Spin.other s then
ERI.get_phys two_e_ints i j k l
else
(ERI.get_phys two_e_ints i j k l) -.
(ERI.get_phys two_e_ints i j l k)
) )
let h_ij mo_basis ki kj =
let integrals =
List.map (fun f -> f mo_basis)
[ h_integrals ]
in
CIMatrixElement.make integrals ki kj
|> List.hd
2019-02-22 00:18:32 +01:00
let make det_space =
2019-02-22 19:19:11 +01:00
let ndet = Ds.size det_space in
let det = Ds.determinants det_space in
let mo_basis = Ds.mo_basis det_space in
2019-02-25 14:37:20 +01:00
(*
2019-02-26 11:58:53 +01:00
let m_H = lazy (
2019-02-25 14:37:20 +01:00
Util.list_range 0 (ndet-1)
|> List.map (fun i -> let ki = det.(i) in
Array.init ndet (fun j -> let kj = det.(j) in
h_ij mo_basis ki kj
)
|> Vec.of_array)
|> Mat.of_col_vecs_list
2019-02-22 19:19:11 +01:00
)
in
2019-02-25 14:37:20 +01:00
*)
(*
2019-02-26 11:58:53 +01:00
let m_H = lazy (
2019-02-25 14:37:20 +01:00
let ntasks = int_of_float @@ sqrt @@ float_of_int ndet in
List.init ntasks (fun i ->
let m =
if i = (ntasks-1) then
(ndet - i*ntasks)
else
ntasks
in
List.init m (fun j -> i*ntasks + j)
)
|> Stream.of_list
|> Farm.run ~ordered:true
~f:(fun l ->
Printf.eprintf "Start\n%!";
List.map (fun i ->
let ki = det.(i) in
Printf.eprintf "%d / %d\n%!" i ndet;
Array.init ndet (fun j -> let kj = det.(j) in
h_ij mo_basis ki kj)
) l)
|> Util.stream_to_list
|> List.concat
|> List.map Vec.of_array
|> Mat.of_col_vecs_list
) in
*)
2019-02-26 11:58:53 +01:00
let m_H = lazy (
2019-02-25 14:37:20 +01:00
let h =
if Parallel.master then
Array.make_matrix ndet ndet 0.
|> Mat.of_array
else
Array.make_matrix 1 1 0.
|> Mat.of_array
in
List.init ndet (fun i -> i)
|> Stream.of_list
|> Farm.run ~ordered:false
~f:(fun i ->
let ki = det.(i) in
Printf.eprintf "%d / %d\n%!" i ndet;
List.init ndet (fun j ->
let kj = det.(j) in
let x = h_ij mo_basis ki kj in
if x <> 0. then Some (i,j,x) else None
)
|> Util.list_some
)
|> Util.stream_to_list
|> List.iter (fun l -> if Parallel.master then
List.iter (fun (i,j,x) -> h.{i+1,j+1} <- x) l);
Parallel.broadcast (lazy h)
) in
2019-02-26 11:58:53 +01:00
let m_S2 = lazy (
2019-02-22 19:19:11 +01:00
Array.init ndet (fun i -> let ki = det.(i) in
Array.init ndet (fun j -> let kj = det.(j) in
CIMatrixElement.make_s2 ki kj
))
|> Mat.of_array
2019-02-22 00:18:32 +01:00
)
in
let eigensystem = lazy (
2019-02-26 11:58:53 +01:00
let m_H = Lazy.force m_H in
2019-02-25 14:37:20 +01:00
Parallel.broadcast @@
2019-02-26 11:58:53 +01:00
lazy (Util.diagonalize_symm m_H)
2019-02-22 00:18:32 +01:00
)
in
2019-02-26 11:58:53 +01:00
{ det_space ; m_H ; m_S2 ; eigensystem }
2019-02-22 00:18:32 +01:00