diff --git a/README.md b/README.md
index 3349f561..babe44a8 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,12 @@
-# Quantum Package 2.0
+# Quantum Package 2.1
+[![DOI](https://zenodo.org/badge/167513335.svg)](https://zenodo.org/badge/latestdoi/167513335)
+
+
+
[*Quantum package 2.0: an open-source determinant-driven suite of programs*](https://pubs.acs.org/doi/10.1021/acs.jctc.9b00176)\
Y. Garniron, K. Gasperich, T. Applencourt, A. Benali, A. Ferté, J. Paquier, B. Pradines, R. Assaraf, P. Reinhardt, J. Toulouse, P. Barbaresco, N. Renon, G. David, J. P. Malrieu, M. Véril, M. Caffarel, P. F. Loos, E. Giner and A. Scemama\
[J. Chem. Theory Comput. 2019, 15, 6, 3591-3609](https://doi.org/10.1021/acs.jctc.9b00176)\
diff --git a/TODO b/TODO
index 046510ed..abdb618f 100644
--- a/TODO
+++ b/TODO
@@ -2,16 +2,8 @@
* Faire que le slave de Hartree-fock est le calcul des integrales AO en parallele
-# Web/doc
-
-* Creer une page web pas trop degueu et la mettre ici : http://lcpq.github.io/quantum_package
-
-* Creer une page avec la liste de tous les exectuables
-
-
# Exterieur
-* Molden format : http://cheminf.cmbi.ru.nl/molden/molden_format.html : read+write. Thomas est dessus
* Un module pour lire les integrales Moleculaires depuis un FCIDUMP
* Un module pour lire des integrales Atomiques (voir module de Mimi pour lire les AO Slater)
* Format Fchk (gaussian)
@@ -24,51 +16,22 @@
# User doc:
- * Videos:
- +) RHF
- * Renvoyer a la doc des modules : c'est pour les programmeurs au depart!
* Mettre le mp2 comme exercice
-
* Interfaces : molden/fcidump
- * Natural orbitals
- * Parameters for Hartree-Fock
- * Parameters for Davidson
- * Running in parallel
# Programmers doc:
* Example : Simple Hartree-Fock program from scratch
* Examples : subroutine example_module
+# enleverle psi_det_size for all complicated stuffs with dimension of psi_coef
+
# Config file for Cray
-# EZFIO sans fork
-
-Refaire les benchmarks
-
-# Documentation de qpsh
-
# Documentation de /etc
-# Toto
-Re-design de qp command
-
-Doc: plugins et qp_plugins
-
Ajouter les symetries dans devel
-<<<<<<< HEAD
-Compiler ezfio avec openmp
-
-# Parallelize i_H_psi
-=======
-
-# Parallelize i_H_psi
-<<<<<<< HEAD
-=======
-
-
->>>>>>> minor_modifs
IMPORTANT:
Davidson Diagonalization
diff --git a/configure b/configure
index 3b17f8ac..685cccfd 100755
--- a/configure
+++ b/configure
@@ -3,21 +3,24 @@
# Quantum Package configuration script
#
-# Force GCC instead of ICC for dependencies
-export CC=gcc
-
TEMP=$(getopt -o c:i:h -l config:,install:,help -n $0 -- "$@") || exit 1
eval set -- "$TEMP"
export QP_ROOT="$( cd "$(dirname "$0")" ; pwd -P )"
echo "QP_ROOT="$QP_ROOT
+unset CC
+unset CCXX
+
+# Force GCC instead of ICC for dependencies
+export CC=gcc
+
# When updating version, update also etc files
BATS_URL="https://github.com/bats-core/bats-core/archive/v1.1.0.tar.gz"
BUBBLE_URL="https://github.com/projectatomic/bubblewrap/releases/download/v0.3.3/bubblewrap-0.3.3.tar.xz"
DOCOPT_URL="https://github.com/docopt/docopt/archive/0.6.2.tar.gz"
-EZFIO_URL="https://gitlab.com/scemama/EZFIO/-/archive/v1.4.0/EZFIO-v1.4.0.tar.gz"
+EZFIO_URL="https://gitlab.com/scemama/EZFIO/-/archive/v1.6.1/EZFIO-v1.6.1.tar.gz"
F77ZMQ_URL="https://github.com/scemama/f77_zmq/archive/v4.2.5.tar.gz"
GMP_URL="ftp://ftp.gnu.org/gnu/gmp/gmp-6.1.2.tar.bz2"
IRPF90_URL="https://gitlab.com/scemama/irpf90/-/archive/v1.7.6/irpf90-v1.7.6.tar.gz"
diff --git a/data/basis/aug-cc-pvtz b/data/basis/aug-cc-pvtz
index b9d1788f..5a5fd369 100644
--- a/data/basis/aug-cc-pvtz
+++ b/data/basis/aug-cc-pvtz
@@ -92,52 +92,58 @@ F 1
1 0.0816000 1.0000000
BERYLLIUM
-S 9
- 1 6863.0000000 0.0002360
- 2 1030.0000000 0.0018260
- 3 234.7000000 0.0094520
- 4 66.5600000 0.0379570
- 5 21.6900000 0.1199650
- 6 7.7340000 0.2821620
- 7 2.9160000 0.4274040
- 8 1.1300000 0.2662780
- 9 0.1101000 -0.0072750
-S 9
- 1 6863.0000000 -0.0000430
- 2 1030.0000000 -0.0003330
- 3 234.7000000 -0.0017360
- 4 66.5600000 -0.0070120
- 5 21.6900000 -0.0231260
- 6 7.7340000 -0.0581380
- 7 2.9160000 -0.1145560
- 8 1.1300000 -0.1359080
- 9 0.1101000 0.5774410
+S 11
+1 6.863000E+03 2.360000E-04
+2 1.030000E+03 1.826000E-03
+3 2.347000E+02 9.452000E-03
+4 6.656000E+01 3.795700E-02
+5 2.169000E+01 1.199650E-01
+6 7.734000E+00 2.821620E-01
+7 2.916000E+00 4.274040E-01
+8 1.130000E+00 2.662780E-01
+9 2.577000E-01 1.819300E-02
+10 1.101000E-01 -7.275000E-03
+11 4.409000E-02 1.903000E-03
+S 11
+1 6.863000E+03 -4.300000E-05
+2 1.030000E+03 -3.330000E-04
+3 2.347000E+02 -1.736000E-03
+4 6.656000E+01 -7.012000E-03
+5 2.169000E+01 -2.312600E-02
+6 7.734000E+00 -5.813800E-02
+7 2.916000E+00 -1.145560E-01
+8 1.130000E+00 -1.359080E-01
+9 2.577000E-01 2.280260E-01
+10 1.101000E-01 5.774410E-01
+11 4.409000E-02 3.178730E-01
S 1
- 1 0.2577000 1.0000000
+1 2.577000E-01 1.000000E+00
S 1
- 1 0.0440900 1.0000000
+1 4.409000E-02 1.000000E+00
S 1
- 1 0.0150300 1.0000000
-P 3
- 1 7.4360000 0.0107360
- 2 1.5770000 0.0628540
- 3 0.4352000 0.2481800
+1 1.470000E-02 1.000000E+00
+P 5
+1 7.436000E+00 1.073600E-02
+2 1.577000E+00 6.285400E-02
+3 4.352000E-01 2.481800E-01
+4 1.438000E-01 5.236990E-01
+5 4.994000E-02 3.534250E-01
P 1
- 1 0.1438000 1.0000000
+1 1.438000E-01 1.000000E+00
P 1
- 1 0.0499400 1.0000000
+1 4.994000E-02 1.000000E+00
P 1
- 1 0.0070600 1.0000000
+1 9.300000E-03 1.000000E+00
D 1
- 1 0.3480000 1.0000000
+1 3.493000E-01 1.000000E+00
D 1
- 1 0.1803000 1.0000000
+1 1.724000E-01 1.000000E+00
D 1
- 1 0.0654000 1.0000000
+1 5.880000E-02 1.000000E+00
F 1
- 1 0.3250000 1.0000000
+1 3.423000E-01 1.0000000
F 1
- 1 0.1533000 1.0000000
+1 1.188000E-01 1.000000E+00
BORON
S 8
diff --git a/docs/source/research.bib b/docs/source/research.bib
index 145fd64e..a5f6d871 100644
--- a/docs/source/research.bib
+++ b/docs/source/research.bib
@@ -1,4 +1,14 @@
%%% ARXIV TO BE UPDATED %%%
+@article{Loos2019Oct,
+ author = {Loos, Pierre-François and Pradines, Barthélémy and Scemama, Anthony and Giner, Emmanuel and Toulouse, Julien},
+ title = {{A Density-Based Basis-Set Incompleteness Correction for GW Methods}},
+ journal = {arXiv},
+ year = {2019},
+ month = {Oct},
+ eprint = {1910.12238},
+ url = {https://arxiv.org/abs/1910.12238}
+}
+
@article{Hollett2019Aug,
author = {Hollett, Joshua W. and Loos, Pierre-Fran{\c{c}}ois},
title = {{Capturing static and dynamic correlation with $\Delta \text{NO}$-MP2 and $\Delta \text{NO}$-CCSD}},
diff --git a/ocaml/Input_bitmasks.ml b/ocaml/Input_bitmasks.ml
index 944a80ff..921b34da 100644
--- a/ocaml/Input_bitmasks.ml
+++ b/ocaml/Input_bitmasks.ml
@@ -6,10 +6,6 @@ module Bitmasks : sig
type t =
{ n_int : N_int_number.t;
bit_kind : Bit_kind.t;
- n_mask_gen : Bitmask_number.t;
- generators : int64 array;
- n_mask_cas : Bitmask_number.t;
- cas : int64 array;
} [@@deriving sexp]
;;
val read : unit -> t option
@@ -18,12 +14,7 @@ end = struct
type t =
{ n_int : N_int_number.t;
bit_kind : Bit_kind.t;
- n_mask_gen : Bitmask_number.t;
- generators : int64 array;
- n_mask_cas : Bitmask_number.t;
- cas : int64 array;
} [@@deriving sexp]
- ;;
let get_default = Qpackage.get_ezfio_default "bitmasks";;
@@ -36,7 +27,6 @@ end = struct
;
Ezfio.get_bitmasks_n_int ()
|> N_int_number.of_int
- ;;
let read_bit_kind () =
if not (Ezfio.has_bitmasks_bit_kind ()) then
@@ -46,89 +36,12 @@ end = struct
;
Ezfio.get_bitmasks_bit_kind ()
|> Bit_kind.of_int
- ;;
-
- let read_n_mask_gen () =
- if not (Ezfio.has_bitmasks_n_mask_gen ()) then
- Ezfio.set_bitmasks_n_mask_gen 1
- ;
- Ezfio.get_bitmasks_n_mask_gen ()
- |> Bitmask_number.of_int
- ;;
-
-
- let full_mask n_int =
- let range = "[1-"^
- (string_of_int (Ezfio.get_mo_basis_mo_num ()))^"]"
- in
- MO_class.create_active range
- |> MO_class.to_bitlist n_int
- ;;
-
- let read_generators () =
- if not (Ezfio.has_bitmasks_generators ()) then
- begin
- let n_int =
- read_n_int ()
- in
- let act =
- full_mask n_int
- in
- let result = [ act ; act ; act ; act ; act ; act ]
- |> List.map (fun x ->
- let y = Bitlist.to_int64_list x in y@y )
- |> List.concat
- in
- let generators = Ezfio.ezfio_array_of_list ~rank:4
- ~dim:([| (N_int_number.to_int n_int) ; 2; 6; 1|]) ~data:result
- in
- Ezfio.set_bitmasks_generators generators
- end;
- Ezfio.get_bitmasks_generators ()
- |> Ezfio.flattened_ezfio
- ;;
-
- let read_n_mask_cas () =
- if not (Ezfio.has_bitmasks_n_mask_cas ()) then
- Ezfio.set_bitmasks_n_mask_cas 1
- ;
- Ezfio.get_bitmasks_n_mask_cas ()
- |> Bitmask_number.of_int
- ;;
-
-
- let read_cas () =
- if not (Ezfio.has_bitmasks_cas ()) then
- begin
- let n_int =
- read_n_int ()
- in
- let act =
- full_mask n_int
- in
- let result = [ act ; act ]
- |> List.map (fun x ->
- let y = Bitlist.to_int64_list x in y@y )
- |> List.concat
- in
- let cas = Ezfio.ezfio_array_of_list ~rank:3
- ~dim:([| (N_int_number.to_int n_int) ; 2; 1|]) ~data:result
- in
- Ezfio.set_bitmasks_cas cas
- end;
- Ezfio.get_bitmasks_cas ()
- |> Ezfio.flattened_ezfio
- ;;
let read () =
if (Ezfio.has_mo_basis_mo_num ()) then
Some
{ n_int = read_n_int ();
bit_kind = read_bit_kind ();
- n_mask_gen = read_n_mask_gen ();
- generators = read_generators ();
- n_mask_cas = read_n_mask_cas ();
- cas = read_cas ();
}
else
None
@@ -138,21 +51,9 @@ end = struct
Printf.sprintf "
n_int = %s
bit_kind = %s
-n_mask_gen = %s
-generators = %s
-n_mask_cas = %s
-cas = %s
"
(N_int_number.to_string b.n_int)
(Bit_kind.to_string b.bit_kind)
- (Bitmask_number.to_string b.n_mask_gen)
- (Array.to_list b.generators
- |> List.map (fun x-> Int64.to_string x)
- |> String.concat ", ")
- (Bitmask_number.to_string b.n_mask_cas)
- (Array.to_list b.cas
- |> List.map (fun x-> Int64.to_string x)
- |> String.concat ", ")
end
diff --git a/ocaml/Input_determinants_by_hand.ml b/ocaml/Input_determinants_by_hand.ml
index 6c449c1b..9c316f8c 100644
--- a/ocaml/Input_determinants_by_hand.ml
+++ b/ocaml/Input_determinants_by_hand.ml
@@ -15,7 +15,7 @@ module Determinants_by_hand : sig
state_average_weight : Positive_float.t array;
} [@@deriving sexp]
val read : ?full:bool -> unit -> t option
- val write : t -> unit
+ val write : ?force:bool -> t -> unit
val to_string : t -> string
val to_rst : t -> Rst_string.t
val of_rst : Rst_string.t -> t option
@@ -318,22 +318,23 @@ end = struct
None
;;
- let write { n_int ;
- bit_kind ;
- n_det ;
- n_det_qp_edit ;
- expected_s2 ;
- psi_coef ;
- psi_det ;
- n_states ;
- state_average_weight ;
- } =
+ let write ?(force=false)
+ { n_int ;
+ bit_kind ;
+ n_det ;
+ n_det_qp_edit ;
+ expected_s2 ;
+ psi_coef ;
+ psi_det ;
+ n_states ;
+ state_average_weight ;
+ } =
write_n_int n_int ;
write_bit_kind bit_kind;
write_n_det n_det;
write_n_states n_states;
write_expected_s2 expected_s2;
- if n_det <= n_det_qp_edit then
+ if force || (n_det <= n_det_qp_edit) then
begin
write_n_det_qp_edit n_det;
write_psi_coef ~n_det:n_det ~n_states:n_states psi_coef ;
@@ -596,7 +597,7 @@ psi_det = %s
let new_det =
{ det with n_det = (Det_number.of_int n_det_new) }
in
- write new_det
+ write ~force:true new_det
;;
let extract_state istate =
@@ -628,7 +629,7 @@ psi_det = %s
let new_det =
{ det with n_states = (States_number.of_int 1) }
in
- write new_det
+ write ~force:true new_det
;;
let extract_states range =
@@ -665,6 +666,7 @@ psi_det = %s
det.psi_coef.(!state_shift+i) <-
det.psi_coef.(i+ishift)
done
+ ; Printf.printf "OK\n%!" ;
end;
state_shift := !state_shift + n_det
) sorted_list
@@ -672,7 +674,7 @@ psi_det = %s
let new_det =
{ det with n_states = (States_number.of_int @@ List.length sorted_list) }
in
- write new_det
+ write ~force:true new_det
;;
end
diff --git a/ocaml/Input_nuclei_by_hand.ml b/ocaml/Input_nuclei_by_hand.ml
index 520b4f05..f195a2de 100644
--- a/ocaml/Input_nuclei_by_hand.ml
+++ b/ocaml/Input_nuclei_by_hand.ml
@@ -175,7 +175,7 @@ nucl_coord = %s
nucl_num
) :: (
List.init nucl_num (fun i->
- Printf.sprintf " %-3s %d %s"
+ Printf.sprintf " %-3s %3d %s"
(b.nucl_label.(i) |> Element.to_string)
(b.nucl_charge.(i) |> Charge.to_int )
(b.nucl_coord.(i) |> Point3d.to_string ~units:Units.Angstrom) )
diff --git a/ocaml/Makefile b/ocaml/Makefile
index 6ff91273..978f7e87 100644
--- a/ocaml/Makefile
+++ b/ocaml/Makefile
@@ -80,7 +80,7 @@ git:
./create_git_sha1.sh
${QP_EZFIO}/Ocaml/ezfio.ml:
- $(NINJA) -C ${QP_EZFIO}
+ $(NINJA) -C ${QP_ROOT}/config ${QP_ROOT}/lib/libezfio_irp.a
qp_edit.ml: ../scripts/ezfio_interface/qp_edit_template
diff --git a/ocaml/qp_set_mo_class.ml b/ocaml/qp_set_mo_class.ml
index 942e2cc2..7ab861e2 100644
--- a/ocaml/qp_set_mo_class.ml
+++ b/ocaml/qp_set_mo_class.ml
@@ -106,96 +106,6 @@ let set ~core ~inact ~act ~virt ~del =
MO_class.to_string virt |> print_endline ;
MO_class.to_string del |> print_endline ;
- (* Create masks *)
- let ia = Excitation.create_single inact act
- and aa = Excitation.create_single act act
- and av = Excitation.create_single act virt
- in
- let single_excitations = [ ia ; aa ; av ]
- |> List.map (fun z ->
- let open Excitation in
- match z with
- | Single (x,y) ->
- ( MO_class.to_bitlist n_int (Hole.to_mo_class x),
- MO_class.to_bitlist n_int (Particle.to_mo_class y) )
- | Double _ -> assert false
- )
-
- and double_excitations = [
- Excitation.double_of_singles ia ia ;
- Excitation.double_of_singles ia aa ;
- Excitation.double_of_singles ia av ;
- Excitation.double_of_singles aa aa ;
- Excitation.double_of_singles aa av ;
- Excitation.double_of_singles av av ]
- |> List.map (fun x ->
- let open Excitation in
- match x with
- | Single _ -> assert false
- | Double (x,y,z,t) ->
- ( MO_class.to_bitlist n_int (Hole.to_mo_class x),
- MO_class.to_bitlist n_int (Particle.to_mo_class y) ,
- MO_class.to_bitlist n_int (Hole.to_mo_class z),
- MO_class.to_bitlist n_int (Particle.to_mo_class t) )
- )
- in
-
- let extract_hole (h,_) = h
- and extract_particle (_,p) = p
- and extract_hole1 (h,_,_,_) = h
- and extract_particle1 (_,p,_,_) = p
- and extract_hole2 (_,_,h,_) = h
- and extract_particle2 (_,_,_,p) = p
- in
- let init = Bitlist.zero n_int in
- let result = [
- List.map extract_hole single_excitations
- |> List.fold_left Bitlist.or_operator init;
- List.map extract_particle single_excitations
- |> List.fold_left Bitlist.or_operator init;
- List.map extract_hole1 double_excitations
- |> List.fold_left Bitlist.or_operator init;
- List.map extract_particle1 double_excitations
- |> List.fold_left Bitlist.or_operator init;
- List.map extract_hole2 double_excitations
- |> List.fold_left Bitlist.or_operator init;
- List.map extract_particle2 double_excitations
- |> List.fold_left Bitlist.or_operator init;
- ]
- in
-
- (* Debug masks in output
- List.iter ~f:(fun x-> print_endline (Bitlist.to_string x)) result;
- *)
-
- (* Write masks *)
- let result =
- List.map (fun x ->
- let y = Bitlist.to_int64_list x in y@y )
- result
- |> List.concat
- in
-
- Ezfio.set_bitmasks_n_int (N_int_number.to_int n_int);
- Ezfio.set_bitmasks_bit_kind 8;
- Ezfio.set_bitmasks_n_mask_gen 1;
- Ezfio.ezfio_array_of_list ~rank:4 ~dim:([| (N_int_number.to_int n_int) ; 2; 6; 1|]) ~data:result
- |> Ezfio.set_bitmasks_generators ;
-
- let result =
- let open Excitation in
- match aa with
- | Double _ -> assert false
- | Single (x,y) ->
- Bitlist.to_int64_list
- ( MO_class.to_bitlist n_int ( Hole.to_mo_class x) ) @
- Bitlist.to_int64_list
- ( MO_class.to_bitlist n_int (Particle.to_mo_class y) )
- in
- Ezfio.set_bitmasks_n_mask_cas 1;
- Ezfio.ezfio_array_of_list ~rank:3 ~dim:([| (N_int_number.to_int n_int) ; 2; 1|]) ~data:result
- |> Ezfio.set_bitmasks_cas;
-
let data =
Array.to_list mo_class
|> List.map (fun x -> match x with
diff --git a/ocaml/qp_tunnel.ml b/ocaml/qp_tunnel.ml
index 75112e66..e7322995 100644
--- a/ocaml/qp_tunnel.ml
+++ b/ocaml/qp_tunnel.ml
@@ -10,7 +10,6 @@ let localport = 42379
let in_time_sum = ref 1.e-9
and in_size_sum = ref 0.
-
let () =
let open Command_line in
begin
diff --git a/ocaml/qptypes_generator.ml b/ocaml/qptypes_generator.ml
index a63a19cc..2c54a218 100644
--- a/ocaml/qptypes_generator.ml
+++ b/ocaml/qptypes_generator.ml
@@ -78,9 +78,6 @@ let input_data = "
| _ -> raise (Invalid_argument \"Bit_kind should be (1|2|4|8).\")
end;
-* Bitmask_number : int
- assert (x > 0) ;
-
* MO_coef : float
* MO_occ : float
diff --git a/scripts/compilation/qp_create_ninja b/scripts/compilation/qp_create_ninja
index 7a148773..8381d1a2 100755
--- a/scripts/compilation/qp_create_ninja
+++ b/scripts/compilation/qp_create_ninja
@@ -839,21 +839,6 @@ if __name__ == "__main__":
l_module = d_binaries.keys()
- # ~#~#~#~#~#~#~#~#~#~#~#~#~#~#~ #
- # C h e c k _ c o h e r e n c y #
- # ~#~#~#~#~#~#~#~#~#~#~#~#~#~#~ #
-
- for module in dict_root_path.values():
-
- if module not in d_binaries:
- l_msg = ["{0} is a root module but does not contain a main file.",
- "- Create it in {0}",
- "- Or delete {0} `qp_module uninstall {0}`",
- "- Or install a module that needs {0} with a main "]
-
- print "\n".join(l_msg).format(module.rel)
- sys.exit(1)
-
# ~#~#~#~#~#~#~#~#~#~#~#~ #
# G l o b a l _ b u i l d #
# ~#~#~#~#~#~#~#~#~#~#~#~ #
diff --git a/scripts/ezfio_interface/qp_edit_template b/scripts/ezfio_interface/qp_edit_template
index d7c3fd32..4218456d 100644
--- a/scripts/ezfio_interface/qp_edit_template
+++ b/scripts/ezfio_interface/qp_edit_template
@@ -120,7 +120,7 @@ let set str s =
match s with
{write}
| Electrons -> write Electrons.(of_rst, write) s
- | Determinants_by_hand -> write Determinants_by_hand.(of_rst, write) s
+ | Determinants_by_hand -> write Determinants_by_hand.(of_rst, write ~force:false) s
| Nuclei_by_hand -> write Nuclei_by_hand.(of_rst, write) s
| Ao_basis -> () (* TODO *)
| Mo_basis -> () (* TODO *)
diff --git a/src/becke_numerical_grid/integration_radial.irp.f b/src/becke_numerical_grid/integration_radial.irp.f
index c1add0cf..44c83070 100644
--- a/src/becke_numerical_grid/integration_radial.irp.f
+++ b/src/becke_numerical_grid/integration_radial.irp.f
@@ -64,7 +64,7 @@
enddo
! Ga-Kr
- do i = 31, 36
+ do i = 31, 100
alpha_knowles(i) = 7.d0
enddo
diff --git a/src/bitmask/bitmask_cas_routines.irp.f b/src/bitmask/bitmask_cas_routines.irp.f
index c0c8cd11..4c3faebe 100644
--- a/src/bitmask/bitmask_cas_routines.irp.f
+++ b/src/bitmask/bitmask_cas_routines.irp.f
@@ -3,28 +3,28 @@ integer function number_of_holes(key_in)
BEGIN_DOC
! Function that returns the number of holes in the inact space
!
-! popcnt(
-! xor(
-! iand(
-! reunion_of_core_inact_bitmask(1,1),
-! xor(
-! key_in(1,1),
-! iand(
-! key_in(1,1),
-! cas_bitmask(1,1,1))
-! )
-! ),
-! reunion_of_core_inact_bitmask(1,1)) )
-!
-! (key_in && cas_bitmask)
-! +---------------------+
-! electrons in cas xor key_in
-! +---------------------------------+
-! electrons outside of cas && reunion_of_core_inact_bitmask
-! +------------------------------------------------------------------+
-! electrons in the core/inact space xor reunion_of_core_inact_bitmask
-! +---------------------------------------------------------------------------------+
-! holes
+ ! popcnt(
+ ! xor(
+ ! iand(
+ ! reunion_of_core_inact_bitmask(1,1),
+ ! xor(
+ ! key_in(1,1),
+ ! iand(
+ ! key_in(1,1),
+ ! act_bitmask(1,1))
+ ! )
+ ! ),
+ ! reunion_of_core_inact_bitmask(1,1)) )
+ !
+ ! (key_in && act_bitmask)
+ ! +---------------------+
+ ! electrons in cas xor key_in
+ ! +---------------------------------+
+ ! electrons outside of cas && reunion_of_core_inact_bitmask
+ ! +------------------------------------------------------------------+
+ ! electrons in the core/inact space xor reunion_of_core_inact_bitmask
+ ! +---------------------------------------------------------------------------------+
+ ! holes
END_DOC
implicit none
integer(bit_kind), intent(in) :: key_in(N_int,2)
@@ -33,74 +33,32 @@ integer function number_of_holes(key_in)
if(N_int == 1)then
number_of_holes = number_of_holes &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2)))), reunion_of_core_inact_bitmask(1,2)) )
else if(N_int == 2)then
number_of_holes = number_of_holes &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2)))), reunion_of_core_inact_bitmask(1,2)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1)))), reunion_of_core_inact_bitmask(2,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2)))), reunion_of_core_inact_bitmask(2,2)) )
else if(N_int == 3)then
number_of_holes = number_of_holes &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2)))), reunion_of_core_inact_bitmask(1,2)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1)))), reunion_of_core_inact_bitmask(2,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2)))), reunion_of_core_inact_bitmask(2,2)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),act_bitmask(3,1)))), reunion_of_core_inact_bitmask(3,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),act_bitmask(3,2)))), reunion_of_core_inact_bitmask(3,2)) )
else if(N_int == 4)then
number_of_holes = number_of_holes &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1)))), reunion_of_core_inact_bitmask(4,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1)))), reunion_of_core_inact_bitmask(4,2)) )
- else if(N_int == 5)then
- number_of_holes = number_of_holes &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1)))), reunion_of_core_inact_bitmask(4,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1)))), reunion_of_core_inact_bitmask(4,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,1), xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1)))), reunion_of_core_inact_bitmask(5,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,2), xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1)))), reunion_of_core_inact_bitmask(5,2)) )
- else if(N_int == 6)then
- number_of_holes = number_of_holes &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1)))), reunion_of_core_inact_bitmask(4,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1)))), reunion_of_core_inact_bitmask(4,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,1), xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1)))), reunion_of_core_inact_bitmask(5,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,2), xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1)))), reunion_of_core_inact_bitmask(5,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(6,1), xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1)))), reunion_of_core_inact_bitmask(6,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(6,2), xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1)))), reunion_of_core_inact_bitmask(6,2)) )
- else if(N_int == 7)then
- number_of_holes = number_of_holes &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1)))), reunion_of_core_inact_bitmask(4,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1)))), reunion_of_core_inact_bitmask(4,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,1), xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1)))), reunion_of_core_inact_bitmask(5,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,2), xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1)))), reunion_of_core_inact_bitmask(5,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(6,1), xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1)))), reunion_of_core_inact_bitmask(6,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(6,2), xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1)))), reunion_of_core_inact_bitmask(6,2)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(7,1), xor(key_in(7,1),iand(key_in(7,1),cas_bitmask(7,1,1)))), reunion_of_core_inact_bitmask(7,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(7,2), xor(key_in(7,2),iand(key_in(7,2),cas_bitmask(7,2,1)))), reunion_of_core_inact_bitmask(7,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2)))), reunion_of_core_inact_bitmask(1,2)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1)))), reunion_of_core_inact_bitmask(2,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2)))), reunion_of_core_inact_bitmask(2,2)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),act_bitmask(3,1)))), reunion_of_core_inact_bitmask(3,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),act_bitmask(3,2)))), reunion_of_core_inact_bitmask(3,2)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),act_bitmask(4,1)))), reunion_of_core_inact_bitmask(4,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),act_bitmask(4,2)))), reunion_of_core_inact_bitmask(4,2)) )
else
do i = 1, N_int
number_of_holes = number_of_holes &
@@ -111,11 +69,11 @@ integer function number_of_holes(key_in)
xor( &
key_in(i,1), & ! MOs of key_in not in the CAS
iand( & ! MOs of key_in in the CAS
- key_in(i,1), cas_bitmask(i,1,1) &
+ key_in(i,1), act_bitmask(i,1) &
) &
) &
), reunion_of_core_inact_bitmask(i,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(i,2), xor(key_in(i,2),iand(key_in(i,2),cas_bitmask(i,2,1)))), reunion_of_core_inact_bitmask(i,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(i,2), xor(key_in(i,2),iand(key_in(i,2),act_bitmask(i,2)))), reunion_of_core_inact_bitmask(i,2)) )
enddo
endif
end
@@ -131,97 +89,37 @@ integer function number_of_particles(key_in)
number_of_particles= 0
if(N_int == 1)then
number_of_particles= number_of_particles &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) )
+ + popcnt( iand( xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1))), virt_bitmask(1,1) )) &
+ + popcnt( iand( xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2))), virt_bitmask(1,2) ))
else if(N_int == 2)then
number_of_particles= number_of_particles &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) )
+ + popcnt( iand( xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1))), virt_bitmask(1,1) ) ) &
+ + popcnt( iand( xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2))), virt_bitmask(1,2) ) ) &
+ + popcnt( iand( xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1))), virt_bitmask(2,1) ) ) &
+ + popcnt( iand( xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2))), virt_bitmask(2,2) ) )
else if(N_int == 3)then
number_of_particles= number_of_particles &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) )
+ + popcnt( iand( xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1))), virt_bitmask(1,1) )) &
+ + popcnt( iand( xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2))), virt_bitmask(1,2) )) &
+ + popcnt( iand( xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1))), virt_bitmask(2,1) )) &
+ + popcnt( iand( xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2))), virt_bitmask(2,2) )) &
+ + popcnt( iand( xor(key_in(3,1),iand(key_in(3,1),act_bitmask(3,1))), virt_bitmask(3,1) )) &
+ + popcnt( iand( xor(key_in(3,2),iand(key_in(3,2),act_bitmask(3,2))), virt_bitmask(3,2) ))
else if(N_int == 4)then
number_of_particles= number_of_particles &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1))), virt_bitmask(4,1) ), virt_bitmask(4,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1))), virt_bitmask(4,2) ), virt_bitmask(4,2)) )
- else if(N_int == 5)then
- number_of_particles= number_of_particles &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1))), virt_bitmask(4,1) ), virt_bitmask(4,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1))), virt_bitmask(4,2) ), virt_bitmask(4,2)) ) &
- + popcnt( iand( iand( xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1))), virt_bitmask(5,1) ), virt_bitmask(5,1)) ) &
- + popcnt( iand( iand( xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1))), virt_bitmask(5,2) ), virt_bitmask(5,2)) )
- else if(N_int == 6)then
- number_of_particles= number_of_particles &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1))), virt_bitmask(4,1) ), virt_bitmask(4,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1))), virt_bitmask(4,2) ), virt_bitmask(4,2)) ) &
- + popcnt( iand( iand( xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1))), virt_bitmask(5,1) ), virt_bitmask(5,1)) ) &
- + popcnt( iand( iand( xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1))), virt_bitmask(5,2) ), virt_bitmask(5,2)) ) &
- + popcnt( iand( iand( xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1))), virt_bitmask(6,1) ), virt_bitmask(6,1)) ) &
- + popcnt( iand( iand( xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1))), virt_bitmask(6,2) ), virt_bitmask(6,2)) )
- else if(N_int == 7)then
- number_of_particles= number_of_particles &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1))), virt_bitmask(4,1) ), virt_bitmask(4,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1))), virt_bitmask(4,2) ), virt_bitmask(4,2)) ) &
- + popcnt( iand( iand( xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1))), virt_bitmask(5,1) ), virt_bitmask(5,1)) ) &
- + popcnt( iand( iand( xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1))), virt_bitmask(5,2) ), virt_bitmask(5,2)) ) &
- + popcnt( iand( iand( xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1))), virt_bitmask(6,1) ), virt_bitmask(6,1)) ) &
- + popcnt( iand( iand( xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1))), virt_bitmask(6,2) ), virt_bitmask(6,2)) ) &
- + popcnt( iand( iand( xor(key_in(7,1),iand(key_in(7,1),cas_bitmask(7,1,1))), virt_bitmask(7,1) ), virt_bitmask(7,1)) ) &
- + popcnt( iand( iand( xor(key_in(7,2),iand(key_in(7,2),cas_bitmask(7,2,1))), virt_bitmask(7,2) ), virt_bitmask(7,2)) )
- else if(N_int == 8)then
- number_of_particles= number_of_particles &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1))), virt_bitmask(4,1) ), virt_bitmask(4,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1))), virt_bitmask(4,2) ), virt_bitmask(4,2)) ) &
- + popcnt( iand( iand( xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1))), virt_bitmask(5,1) ), virt_bitmask(5,1)) ) &
- + popcnt( iand( iand( xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1))), virt_bitmask(5,2) ), virt_bitmask(5,2)) ) &
- + popcnt( iand( iand( xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1))), virt_bitmask(6,1) ), virt_bitmask(6,1)) ) &
- + popcnt( iand( iand( xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1))), virt_bitmask(6,2) ), virt_bitmask(6,2)) ) &
- + popcnt( iand( iand( xor(key_in(7,1),iand(key_in(7,1),cas_bitmask(7,1,1))), virt_bitmask(7,1) ), virt_bitmask(7,1)) ) &
- + popcnt( iand( iand( xor(key_in(7,2),iand(key_in(7,2),cas_bitmask(7,2,1))), virt_bitmask(7,2) ), virt_bitmask(7,2)) ) &
- + popcnt( iand( iand( xor(key_in(8,1),iand(key_in(8,1),cas_bitmask(8,1,1))), virt_bitmask(8,1) ), virt_bitmask(8,1)) ) &
- + popcnt( iand( iand( xor(key_in(8,2),iand(key_in(8,2),cas_bitmask(8,2,1))), virt_bitmask(8,2) ), virt_bitmask(8,2)) )
+ + popcnt( iand( xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1))), virt_bitmask(1,1) ) ) &
+ + popcnt( iand( xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2))), virt_bitmask(1,2) ) ) &
+ + popcnt( iand( xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1))), virt_bitmask(2,1) ) ) &
+ + popcnt( iand( xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2))), virt_bitmask(2,2) ) ) &
+ + popcnt( iand( xor(key_in(3,1),iand(key_in(3,1),act_bitmask(3,1))), virt_bitmask(3,1) ) ) &
+ + popcnt( iand( xor(key_in(3,2),iand(key_in(3,2),act_bitmask(3,2))), virt_bitmask(3,2) ) ) &
+ + popcnt( iand( xor(key_in(4,1),iand(key_in(4,1),act_bitmask(4,1))), virt_bitmask(4,1) ) ) &
+ + popcnt( iand( xor(key_in(4,2),iand(key_in(4,2),act_bitmask(4,2))), virt_bitmask(4,2) ) )
else
do i = 1, N_int
- number_of_particles= number_of_particles &
- + popcnt( iand( iand( xor(key_in(i,1),iand(key_in(i,1),cas_bitmask(i,1,1))), virt_bitmask(i,1) ), virt_bitmask(i,1)) ) &
- + popcnt( iand( iand( xor(key_in(i,2),iand(key_in(i,2),cas_bitmask(i,2,1))), virt_bitmask(i,2) ), virt_bitmask(i,2)) )
+ number_of_particles= number_of_particles &
+ + popcnt( iand( xor(key_in(i,1),iand(key_in(i,1),act_bitmask(i,1))), virt_bitmask(i,1) )) &
+ + popcnt( iand( xor(key_in(i,2),iand(key_in(i,2),act_bitmask(i,2))), virt_bitmask(i,2) ))
enddo
endif
end
@@ -230,7 +128,7 @@ logical function is_a_two_holes_two_particles(key_in)
BEGIN_DOC
! logical function that returns True if the determinant 'key_in'
! belongs to the 2h-2p excitation class of the DDCI space
- ! this is calculated using the CAS_bitmask that defines the active
+ ! this is calculated using the act_bitmask that defines the active
! orbital space, the inact_bitmasl that defines the inactive oribital space
! and the virt_bitmask that defines the virtual orbital space
END_DOC
@@ -246,174 +144,62 @@ logical function is_a_two_holes_two_particles(key_in)
i_diff = 0
if(N_int == 1)then
i_diff = i_diff &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2)))), reunion_of_core_inact_bitmask(1,2)) ) &
+ + popcnt( iand( xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1))), virt_bitmask(1,1) ) ) &
+ + popcnt( iand( xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2))), virt_bitmask(1,2) ) )
else if(N_int == 2)then
i_diff = i_diff &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2)))), reunion_of_core_inact_bitmask(1,2)) ) &
+ + popcnt( iand( xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1))), virt_bitmask(1,1) ) ) &
+ + popcnt( iand( xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2))), virt_bitmask(1,2) ) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1)))), reunion_of_core_inact_bitmask(2,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2)))), reunion_of_core_inact_bitmask(2,2)) ) &
+ + popcnt( iand( xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1))), virt_bitmask(2,1) )) &
+ + popcnt( iand( xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2))), virt_bitmask(2,2) ))
else if(N_int == 3)then
i_diff = i_diff &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2)))), reunion_of_core_inact_bitmask(1,2)) ) &
+ + popcnt( iand( xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1))), virt_bitmask(1,1) ) ) &
+ + popcnt( iand( xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2))), virt_bitmask(1,2) ) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1)))), reunion_of_core_inact_bitmask(2,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2)))), reunion_of_core_inact_bitmask(2,2)) ) &
+ + popcnt( iand( xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1))), virt_bitmask(2,1) ) ) &
+ + popcnt( iand( xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2))), virt_bitmask(2,2) ) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),act_bitmask(3,1)))), reunion_of_core_inact_bitmask(3,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),act_bitmask(3,2)))), reunion_of_core_inact_bitmask(3,2)) ) &
+ + popcnt( iand( xor(key_in(3,1),iand(key_in(3,1),act_bitmask(3,1))), virt_bitmask(3,1) ) ) &
+ + popcnt( iand( xor(key_in(3,2),iand(key_in(3,2),act_bitmask(3,2))), virt_bitmask(3,2) ) )
else if(N_int == 4)then
i_diff = i_diff &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1)))), reunion_of_core_inact_bitmask(4,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1)))), reunion_of_core_inact_bitmask(4,2)) ) &
- + popcnt( iand( iand( xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1))), virt_bitmask(4,1) ), virt_bitmask(4,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1))), virt_bitmask(4,2) ), virt_bitmask(4,2)) )
- else if(N_int == 5)then
- i_diff = i_diff &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1)))), reunion_of_core_inact_bitmask(4,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1)))), reunion_of_core_inact_bitmask(4,2)) ) &
- + popcnt( iand( iand( xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1))), virt_bitmask(4,1) ), virt_bitmask(4,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1))), virt_bitmask(4,2) ), virt_bitmask(4,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,1), xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1)))), reunion_of_core_inact_bitmask(5,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,2), xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1)))), reunion_of_core_inact_bitmask(5,2)) ) &
- + popcnt( iand( iand( xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1))), virt_bitmask(5,1) ), virt_bitmask(5,1)) ) &
- + popcnt( iand( iand( xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1))), virt_bitmask(5,2) ), virt_bitmask(5,2)) )
- else if(N_int == 6)then
- i_diff = i_diff &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1)))), reunion_of_core_inact_bitmask(4,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1)))), reunion_of_core_inact_bitmask(4,2)) ) &
- + popcnt( iand( iand( xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1))), virt_bitmask(4,1) ), virt_bitmask(4,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1))), virt_bitmask(4,2) ), virt_bitmask(4,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,1), xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1)))), reunion_of_core_inact_bitmask(5,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,2), xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1)))), reunion_of_core_inact_bitmask(5,2)) ) &
- + popcnt( iand( iand( xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1))), virt_bitmask(5,1) ), virt_bitmask(5,1)) ) &
- + popcnt( iand( iand( xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1))), virt_bitmask(5,2) ), virt_bitmask(5,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(6,1), xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1)))), reunion_of_core_inact_bitmask(6,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(6,2), xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1)))), reunion_of_core_inact_bitmask(6,2)) ) &
- + popcnt( iand( iand( xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1))), virt_bitmask(6,1) ), virt_bitmask(6,1)) ) &
- + popcnt( iand( iand( xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1))), virt_bitmask(6,2) ), virt_bitmask(6,2)) )
- else if(N_int == 7)then
- i_diff = i_diff &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1)))), reunion_of_core_inact_bitmask(4,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1)))), reunion_of_core_inact_bitmask(4,2)) ) &
- + popcnt( iand( iand( xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1))), virt_bitmask(4,1) ), virt_bitmask(4,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1))), virt_bitmask(4,2) ), virt_bitmask(4,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,1), xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1)))), reunion_of_core_inact_bitmask(5,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,2), xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1)))), reunion_of_core_inact_bitmask(5,2)) ) &
- + popcnt( iand( iand( xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1))), virt_bitmask(5,1) ), virt_bitmask(5,1)) ) &
- + popcnt( iand( iand( xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1))), virt_bitmask(5,2) ), virt_bitmask(5,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(6,1), xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1)))), reunion_of_core_inact_bitmask(6,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(6,2), xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1)))), reunion_of_core_inact_bitmask(6,2)) ) &
- + popcnt( iand( iand( xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1))), virt_bitmask(6,1) ), virt_bitmask(6,1)) ) &
- + popcnt( iand( iand( xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1))), virt_bitmask(6,2) ), virt_bitmask(6,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(7,1), xor(key_in(7,1),iand(key_in(7,1),cas_bitmask(7,1,1)))), reunion_of_core_inact_bitmask(7,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(7,2), xor(key_in(7,2),iand(key_in(7,2),cas_bitmask(7,2,1)))), reunion_of_core_inact_bitmask(7,2)) ) &
- + popcnt( iand( iand( xor(key_in(7,1),iand(key_in(7,1),cas_bitmask(7,1,1))), virt_bitmask(7,1) ), virt_bitmask(7,1)) ) &
- + popcnt( iand( iand( xor(key_in(7,2),iand(key_in(7,2),cas_bitmask(7,2,1))), virt_bitmask(7,2) ), virt_bitmask(7,2)) )
- else if(N_int == 8)then
- i_diff = i_diff &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) ) &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1)))), reunion_of_core_inact_bitmask(2,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1)))), reunion_of_core_inact_bitmask(2,2)) ) &
- + popcnt( iand( iand( xor(key_in(2,1),iand(key_in(2,1),cas_bitmask(2,1,1))), virt_bitmask(2,1) ), virt_bitmask(2,1)) ) &
- + popcnt( iand( iand( xor(key_in(2,2),iand(key_in(2,2),cas_bitmask(2,2,1))), virt_bitmask(2,2) ), virt_bitmask(2,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1)))), reunion_of_core_inact_bitmask(3,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1)))), reunion_of_core_inact_bitmask(3,2)) ) &
- + popcnt( iand( iand( xor(key_in(3,1),iand(key_in(3,1),cas_bitmask(3,1,1))), virt_bitmask(3,1) ), virt_bitmask(3,1)) ) &
- + popcnt( iand( iand( xor(key_in(3,2),iand(key_in(3,2),cas_bitmask(3,2,1))), virt_bitmask(3,2) ), virt_bitmask(3,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1)))), reunion_of_core_inact_bitmask(4,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1)))), reunion_of_core_inact_bitmask(4,2)) ) &
- + popcnt( iand( iand( xor(key_in(4,1),iand(key_in(4,1),cas_bitmask(4,1,1))), virt_bitmask(4,1) ), virt_bitmask(4,1)) ) &
- + popcnt( iand( iand( xor(key_in(4,2),iand(key_in(4,2),cas_bitmask(4,2,1))), virt_bitmask(4,2) ), virt_bitmask(4,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,1), xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1)))), reunion_of_core_inact_bitmask(5,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(5,2), xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1)))), reunion_of_core_inact_bitmask(5,2)) ) &
- + popcnt( iand( iand( xor(key_in(5,1),iand(key_in(5,1),cas_bitmask(5,1,1))), virt_bitmask(5,1) ), virt_bitmask(5,1)) ) &
- + popcnt( iand( iand( xor(key_in(5,2),iand(key_in(5,2),cas_bitmask(5,2,1))), virt_bitmask(5,2) ), virt_bitmask(5,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(6,1), xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1)))), reunion_of_core_inact_bitmask(6,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(6,2), xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1)))), reunion_of_core_inact_bitmask(6,2)) ) &
- + popcnt( iand( iand( xor(key_in(6,1),iand(key_in(6,1),cas_bitmask(6,1,1))), virt_bitmask(6,1) ), virt_bitmask(6,1)) ) &
- + popcnt( iand( iand( xor(key_in(6,2),iand(key_in(6,2),cas_bitmask(6,2,1))), virt_bitmask(6,2) ), virt_bitmask(6,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(7,1), xor(key_in(7,1),iand(key_in(7,1),cas_bitmask(7,1,1)))), reunion_of_core_inact_bitmask(7,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(7,2), xor(key_in(7,2),iand(key_in(7,2),cas_bitmask(7,2,1)))), reunion_of_core_inact_bitmask(7,2)) ) &
- + popcnt( iand( iand( xor(key_in(7,1),iand(key_in(7,1),cas_bitmask(7,1,1))), virt_bitmask(7,1) ), virt_bitmask(7,1)) ) &
- + popcnt( iand( iand( xor(key_in(7,2),iand(key_in(7,2),cas_bitmask(7,2,1))), virt_bitmask(7,2) ), virt_bitmask(7,2)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(8,1), xor(key_in(8,1),iand(key_in(8,1),cas_bitmask(8,1,1)))), reunion_of_core_inact_bitmask(8,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(8,2), xor(key_in(8,2),iand(key_in(8,2),cas_bitmask(8,2,1)))), reunion_of_core_inact_bitmask(8,2)) ) &
- + popcnt( iand( iand( xor(key_in(8,1),iand(key_in(8,1),cas_bitmask(8,1,1))), virt_bitmask(8,1) ), virt_bitmask(8,1)) ) &
- + popcnt( iand( iand( xor(key_in(8,2),iand(key_in(8,2),cas_bitmask(8,2,1))), virt_bitmask(8,2) ), virt_bitmask(8,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1)))), reunion_of_core_inact_bitmask(1,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2)))), reunion_of_core_inact_bitmask(1,2)) ) &
+ + popcnt( iand( xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1))), virt_bitmask(1,1) ) ) &
+ + popcnt( iand( xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2))), virt_bitmask(1,2) ) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,1), xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1)))), reunion_of_core_inact_bitmask(2,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(2,2), xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2)))), reunion_of_core_inact_bitmask(2,2)) ) &
+ + popcnt( iand( xor(key_in(2,1),iand(key_in(2,1),act_bitmask(2,1))), virt_bitmask(2,1) ) ) &
+ + popcnt( iand( xor(key_in(2,2),iand(key_in(2,2),act_bitmask(2,2))), virt_bitmask(2,2) ) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,1), xor(key_in(3,1),iand(key_in(3,1),act_bitmask(3,1)))), reunion_of_core_inact_bitmask(3,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(3,2), xor(key_in(3,2),iand(key_in(3,2),act_bitmask(3,2)))), reunion_of_core_inact_bitmask(3,2)) ) &
+ + popcnt( iand( xor(key_in(3,1),iand(key_in(3,1),act_bitmask(3,1))), virt_bitmask(3,1) ) ) &
+ + popcnt( iand( xor(key_in(4,2),iand(key_in(3,2),act_bitmask(3,2))), virt_bitmask(3,2) ) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,1), xor(key_in(4,1),iand(key_in(4,1),act_bitmask(4,1)))), reunion_of_core_inact_bitmask(4,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(4,2), xor(key_in(4,2),iand(key_in(4,2),act_bitmask(4,2)))), reunion_of_core_inact_bitmask(4,2)) ) &
+ + popcnt( iand( xor(key_in(4,1),iand(key_in(4,1),act_bitmask(4,1))), virt_bitmask(4,1) ) ) &
+ + popcnt( iand( xor(key_in(4,2),iand(key_in(4,2),act_bitmask(4,2))), virt_bitmask(4,2) ) )
else
do i = 1, N_int
i_diff = i_diff &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(i,1), xor(key_in(i,1),iand(key_in(i,1),cas_bitmask(i,1,1)))), reunion_of_core_inact_bitmask(i,1)) ) &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(i,2), xor(key_in(i,2),iand(key_in(i,2),cas_bitmask(i,2,1)))), reunion_of_core_inact_bitmask(i,2)) ) &
- + popcnt( iand( iand( xor(key_in(i,1),iand(key_in(i,1),cas_bitmask(i,1,1))), virt_bitmask(i,1) ), virt_bitmask(i,1)) ) &
- + popcnt( iand( iand( xor(key_in(i,2),iand(key_in(i,2),cas_bitmask(i,2,1))), virt_bitmask(i,2) ), virt_bitmask(i,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(i,1), xor(key_in(i,1),iand(key_in(i,1),act_bitmask(i,1)))), reunion_of_core_inact_bitmask(i,1)) ) &
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(i,2), xor(key_in(i,2),iand(key_in(i,2),act_bitmask(i,2)))), reunion_of_core_inact_bitmask(i,2)) ) &
+ + popcnt( iand( xor(key_in(i,1),iand(key_in(i,1),act_bitmask(i,1))), virt_bitmask(i,1) )) &
+ + popcnt( iand( xor(key_in(i,2),iand(key_in(i,2),act_bitmask(i,2))), virt_bitmask(i,2) ))
enddo
endif
is_a_two_holes_two_particles = (i_diff >3)
@@ -434,8 +220,8 @@ integer function number_of_holes_verbose(key_in)
print*,'jey_in = '
call debug_det(key_in,N_int)
number_of_holes_verbose = 0
- key_tmp(1,1) = xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))
- key_tmp(1,2) = xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,1,1)))
+ key_tmp(1,1) = xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1)))
+ key_tmp(1,2) = xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,1)))
call debug_det(key_tmp,N_int)
key_tmp(1,1) = iand(key_tmp(1,1),reunion_of_core_inact_bitmask(1,1))
key_tmp(1,2) = iand(key_tmp(1,2),reunion_of_core_inact_bitmask(1,2))
@@ -446,8 +232,8 @@ integer function number_of_holes_verbose(key_in)
! number_of_holes_verbose = number_of_holes_verbose + popcnt(key_tmp(1,1)) &
! + popcnt(key_tmp(1,2))
number_of_holes_verbose = number_of_holes_verbose &
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
- + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1)))), reunion_of_core_inact_bitmask(1,2)) )
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,1), xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1)))), reunion_of_core_inact_bitmask(1,1)) )&
+ + popcnt( xor( iand(reunion_of_core_inact_bitmask(1,2), xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2)))), reunion_of_core_inact_bitmask(1,2)) )
print*,'----------------------'
end
@@ -464,8 +250,8 @@ integer function number_of_particles_verbose(key_in)
print*,'jey_in = '
call debug_det(key_in,N_int)
number_of_particles_verbose = 0
- key_tmp(1,1) = xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,1,1)))
- key_tmp(1,2) = xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,1,1)))
+ key_tmp(1,1) = xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,1)))
+ key_tmp(1,2) = xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,1)))
call debug_det(key_tmp,N_int)
key_tmp(1,1) = iand(key_tmp(1,2),virt_bitmask(1,2))
key_tmp(1,2) = iand(key_tmp(1,2),virt_bitmask(1,2))
@@ -476,18 +262,16 @@ integer function number_of_particles_verbose(key_in)
! number_of_particles_verbose = number_of_particles_verbose + popcnt(key_tmp(1,1)) &
! + popcnt(key_tmp(1,2))
number_of_particles_verbose = number_of_particles_verbose &
- + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),cas_bitmask(1,1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
- + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),cas_bitmask(1,2,1))), virt_bitmask(1,2) ), virt_bitmask(1,2)) )
+ + popcnt( iand( iand( xor(key_in(1,1),iand(key_in(1,1),act_bitmask(1,1))), virt_bitmask(1,1) ), virt_bitmask(1,1)) ) &
+ + popcnt( iand( iand( xor(key_in(1,2),iand(key_in(1,2),act_bitmask(1,2))), virt_bitmask(1,2) ), virt_bitmask(1,2)) )
end
logical function is_a_1h1p(key_in)
implicit none
integer(bit_kind), intent(in) :: key_in(N_int,2)
integer :: number_of_particles, number_of_holes
- is_a_1h1p = .False.
- if(number_of_holes(key_in).eq.1 .and. number_of_particles(key_in).eq.1)then
- is_a_1h1p = .True.
- endif
+
+ is_a_1h1p = (number_of_holes(key_in) == 1) .and. (number_of_particles(key_in) == 1)
end
@@ -495,10 +279,8 @@ logical function is_a_1h2p(key_in)
implicit none
integer(bit_kind), intent(in) :: key_in(N_int,2)
integer :: number_of_particles, number_of_holes
- is_a_1h2p = .False.
- if(number_of_holes(key_in).eq.1 .and. number_of_particles(key_in).eq.2)then
- is_a_1h2p = .True.
- endif
+
+ is_a_1h2p = (number_of_holes(key_in) == 1) .and. (number_of_particles(key_in) == 2)
end
@@ -506,10 +288,8 @@ logical function is_a_2h1p(key_in)
implicit none
integer(bit_kind), intent(in) :: key_in(N_int,2)
integer :: number_of_particles, number_of_holes
- is_a_2h1p = .False.
- if(number_of_holes(key_in).eq.2 .and. number_of_particles(key_in).eq.1)then
- is_a_2h1p = .True.
- endif
+
+ is_a_2h1p = (number_of_holes(key_in) == 2) .and. (number_of_particles(key_in) == 1)
end
@@ -517,10 +297,8 @@ logical function is_a_1h(key_in)
implicit none
integer(bit_kind), intent(in) :: key_in(N_int,2)
integer :: number_of_particles, number_of_holes
- is_a_1h = .False.
- if(number_of_holes(key_in).eq.1 .and. number_of_particles(key_in).eq.0)then
- is_a_1h = .True.
- endif
+
+ is_a_1h = (number_of_holes(key_in) == 1) .and. (number_of_particles(key_in) == 0)
end
@@ -528,10 +306,8 @@ logical function is_a_1p(key_in)
implicit none
integer(bit_kind), intent(in) :: key_in(N_int,2)
integer :: number_of_particles, number_of_holes
- is_a_1p = .False.
- if(number_of_holes(key_in).eq.0 .and. number_of_particles(key_in).eq.1)then
- is_a_1p = .True.
- endif
+
+ is_a_1p = (number_of_holes(key_in) == 0) .and. (number_of_particles(key_in) == 1)
end
@@ -539,10 +315,8 @@ logical function is_a_2p(key_in)
implicit none
integer(bit_kind), intent(in) :: key_in(N_int,2)
integer :: number_of_particles, number_of_holes
- is_a_2p = .False.
- if(number_of_holes(key_in).eq.0 .and. number_of_particles(key_in).eq.2)then
- is_a_2p = .True.
- endif
+
+ is_a_2p = (number_of_holes(key_in) == 0) .and. (number_of_particles(key_in) == 2)
end
@@ -550,10 +324,8 @@ logical function is_a_2h(key_in)
implicit none
integer(bit_kind), intent(in) :: key_in(N_int,2)
integer :: number_of_particles, number_of_holes
- is_a_2h = .False.
- if(number_of_holes(key_in).eq.2 .and. number_of_particles(key_in).eq.0)then
- is_a_2h = .True.
- endif
+
+ is_a_2h = (number_of_holes(key_in) == 2) .and. (number_of_particles(key_in) == 0)
end
diff --git a/src/bitmask/bitmasks.ezfio_config b/src/bitmask/bitmasks.ezfio_config
index c133d8fe..dfb95c83 100644
--- a/src/bitmask/bitmasks.ezfio_config
+++ b/src/bitmask/bitmasks.ezfio_config
@@ -1,8 +1,4 @@
bitmasks
N_int integer
bit_kind integer
- N_mask_gen integer
- generators integer*8 (bitmasks_N_int*bitmasks_bit_kind/8,2,6,bitmasks_N_mask_gen)
- N_mask_cas integer
- cas integer*8 (bitmasks_N_int*bitmasks_bit_kind/8,2,bitmasks_N_mask_cas)
diff --git a/src/bitmask/bitmasks.irp.f b/src/bitmask/bitmasks.irp.f
index d425dda6..91617397 100644
--- a/src/bitmask/bitmasks.irp.f
+++ b/src/bitmask/bitmasks.irp.f
@@ -11,7 +11,7 @@ BEGIN_PROVIDER [ integer, N_int ]
if (N_int > N_int_max) then
stop 'N_int > N_int_max'
endif
-
+
END_PROVIDER
@@ -20,7 +20,7 @@ BEGIN_PROVIDER [ integer(bit_kind), full_ijkl_bitmask, (N_int) ]
BEGIN_DOC
! Bitmask to include all possible MOs
END_DOC
-
+
integer :: i,j,k
k=0
do j=1,N_int
@@ -37,34 +37,34 @@ END_PROVIDER
BEGIN_PROVIDER [ integer(bit_kind), full_ijkl_bitmask_4, (N_int,4) ]
implicit none
- integer :: i
+ integer :: i
do i=1,N_int
- full_ijkl_bitmask_4(i,1) = full_ijkl_bitmask(i)
- full_ijkl_bitmask_4(i,2) = full_ijkl_bitmask(i)
- full_ijkl_bitmask_4(i,3) = full_ijkl_bitmask(i)
- full_ijkl_bitmask_4(i,4) = full_ijkl_bitmask(i)
+ full_ijkl_bitmask_4(i,1) = full_ijkl_bitmask(i)
+ full_ijkl_bitmask_4(i,2) = full_ijkl_bitmask(i)
+ full_ijkl_bitmask_4(i,3) = full_ijkl_bitmask(i)
+ full_ijkl_bitmask_4(i,4) = full_ijkl_bitmask(i)
enddo
END_PROVIDER
BEGIN_PROVIDER [ integer(bit_kind), core_inact_act_bitmask_4, (N_int,4) ]
implicit none
- integer :: i
+ integer :: i
do i=1,N_int
- core_inact_act_bitmask_4(i,1) = reunion_of_core_inact_act_bitmask(i,1)
- core_inact_act_bitmask_4(i,2) = reunion_of_core_inact_act_bitmask(i,1)
- core_inact_act_bitmask_4(i,3) = reunion_of_core_inact_act_bitmask(i,1)
- core_inact_act_bitmask_4(i,4) = reunion_of_core_inact_act_bitmask(i,1)
+ core_inact_act_bitmask_4(i,1) = reunion_of_core_inact_act_bitmask(i,1)
+ core_inact_act_bitmask_4(i,2) = reunion_of_core_inact_act_bitmask(i,1)
+ core_inact_act_bitmask_4(i,3) = reunion_of_core_inact_act_bitmask(i,1)
+ core_inact_act_bitmask_4(i,4) = reunion_of_core_inact_act_bitmask(i,1)
enddo
END_PROVIDER
BEGIN_PROVIDER [ integer(bit_kind), virt_bitmask_4, (N_int,4) ]
implicit none
- integer :: i
+ integer :: i
do i=1,N_int
- virt_bitmask_4(i,1) = virt_bitmask(i,1)
- virt_bitmask_4(i,2) = virt_bitmask(i,1)
- virt_bitmask_4(i,3) = virt_bitmask(i,1)
- virt_bitmask_4(i,4) = virt_bitmask(i,1)
+ virt_bitmask_4(i,1) = virt_bitmask(i,1)
+ virt_bitmask_4(i,2) = virt_bitmask(i,1)
+ virt_bitmask_4(i,3) = virt_bitmask(i,1)
+ virt_bitmask_4(i,4) = virt_bitmask(i,1)
enddo
END_PROVIDER
@@ -78,491 +78,165 @@ BEGIN_PROVIDER [ integer(bit_kind), HF_bitmask, (N_int,2)]
END_DOC
integer :: i,j,n
integer :: occ(elec_alpha_num)
-
+
HF_bitmask = 0_bit_kind
do i=1,elec_alpha_num
- occ(i) = i
+ occ(i) = i
enddo
call list_to_bitstring( HF_bitmask(1,1), occ, elec_alpha_num, N_int)
! elec_alpha_num <= elec_beta_num, so occ is already OK.
call list_to_bitstring( HF_bitmask(1,2), occ, elec_beta_num, N_int)
-
+
END_PROVIDER
BEGIN_PROVIDER [ integer(bit_kind), ref_bitmask, (N_int,2)]
- implicit none
- BEGIN_DOC
-! Reference bit mask, used in Slater rules, chosen as Hartree-Fock bitmask
- END_DOC
- ref_bitmask = HF_bitmask
-END_PROVIDER
-
-BEGIN_PROVIDER [ integer, N_generators_bitmask ]
- implicit none
- BEGIN_DOC
- ! Number of bitmasks for generators
- END_DOC
- logical :: exists
- PROVIDE ezfio_filename N_int
-
- if (mpi_master) then
- call ezfio_has_bitmasks_N_mask_gen(exists)
- if (exists) then
- call ezfio_get_bitmasks_N_mask_gen(N_generators_bitmask)
- integer :: N_int_check
- integer :: bit_kind_check
- call ezfio_get_bitmasks_bit_kind(bit_kind_check)
- if (bit_kind_check /= bit_kind) then
- print *, bit_kind_check, bit_kind
- print *, 'Error: bit_kind is not correct in EZFIO file'
- endif
- call ezfio_get_bitmasks_N_int(N_int_check)
- if (N_int_check /= N_int) then
- print *, N_int_check, N_int
- print *, 'Error: N_int is not correct in EZFIO file'
- endif
- else
- N_generators_bitmask = 1
- endif
- ASSERT (N_generators_bitmask > 0)
- call write_int(6,N_generators_bitmask,'N_generators_bitmask')
- endif
- IRP_IF MPI_DEBUG
- print *, irp_here, mpi_rank
- call MPI_BARRIER(MPI_COMM_WORLD, ierr)
- IRP_ENDIF
- IRP_IF MPI
- include 'mpif.h'
- integer :: ierr
- call MPI_BCAST( N_generators_bitmask, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
- if (ierr /= MPI_SUCCESS) then
- stop 'Unable to read N_generators_bitmask with MPI'
- endif
- IRP_ENDIF
-
-
-END_PROVIDER
-
-
-BEGIN_PROVIDER [ integer, N_generators_bitmask_restart ]
- implicit none
- BEGIN_DOC
- ! Number of bitmasks for generators
- END_DOC
- logical :: exists
- PROVIDE ezfio_filename N_int
-
- if (mpi_master) then
- call ezfio_has_bitmasks_N_mask_gen(exists)
- if (exists) then
- call ezfio_get_bitmasks_N_mask_gen(N_generators_bitmask_restart)
- integer :: N_int_check
- integer :: bit_kind_check
- call ezfio_get_bitmasks_bit_kind(bit_kind_check)
- if (bit_kind_check /= bit_kind) then
- print *, bit_kind_check, bit_kind
- print *, 'Error: bit_kind is not correct in EZFIO file'
- endif
- call ezfio_get_bitmasks_N_int(N_int_check)
- if (N_int_check /= N_int) then
- print *, N_int_check, N_int
- print *, 'Error: N_int is not correct in EZFIO file'
- endif
- else
- N_generators_bitmask_restart = 1
- endif
- ASSERT (N_generators_bitmask_restart > 0)
- call write_int(6,N_generators_bitmask_restart,'N_generators_bitmask_restart')
- endif
- IRP_IF MPI_DEBUG
- print *, irp_here, mpi_rank
- call MPI_BARRIER(MPI_COMM_WORLD, ierr)
- IRP_ENDIF
- IRP_IF MPI
- include 'mpif.h'
- integer :: ierr
- call MPI_BCAST( N_generators_bitmask_restart, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
- if (ierr /= MPI_SUCCESS) then
- stop 'Unable to read N_generators_bitmask_restart with MPI'
- endif
- IRP_ENDIF
-
-
+ implicit none
+ BEGIN_DOC
+ ! Reference bit mask, used in Slater rules, chosen as Hartree-Fock bitmask
+ END_DOC
+ ref_bitmask = HF_bitmask
END_PROVIDER
-
-BEGIN_PROVIDER [ integer(bit_kind), generators_bitmask_restart, (N_int,2,6,N_generators_bitmask_restart) ]
- implicit none
- BEGIN_DOC
- ! Bitmasks for generator determinants.
- ! (N_int, alpha/beta, hole/particle, generator).
- !
- ! 3rd index is :
- !
- ! * 1 : hole for single exc
- !
- ! * 2 : particle for single exc
- !
- ! * 3 : hole for 1st exc of double
- !
- ! * 4 : particle for 1st exc of double
- !
- ! * 5 : hole for 2nd exc of double
- !
- ! * 6 : particle for 2nd exc of double
- !
- END_DOC
- logical :: exists
- PROVIDE ezfio_filename full_ijkl_bitmask N_generators_bitmask N_int
- PROVIDE generators_bitmask_restart
-
- if (mpi_master) then
- call ezfio_has_bitmasks_generators(exists)
- if (exists) then
- call ezfio_get_bitmasks_generators(generators_bitmask_restart)
- else
- integer :: k, ispin
- do k=1,N_generators_bitmask
- do ispin=1,2
- do i=1,N_int
- generators_bitmask_restart(i,ispin,s_hole ,k) = full_ijkl_bitmask(i)
- generators_bitmask_restart(i,ispin,s_part ,k) = full_ijkl_bitmask(i)
- generators_bitmask_restart(i,ispin,d_hole1,k) = full_ijkl_bitmask(i)
- generators_bitmask_restart(i,ispin,d_part1,k) = full_ijkl_bitmask(i)
- generators_bitmask_restart(i,ispin,d_hole2,k) = full_ijkl_bitmask(i)
- generators_bitmask_restart(i,ispin,d_part2,k) = full_ijkl_bitmask(i)
- enddo
- enddo
- enddo
- endif
-
- integer :: i
- do k=1,N_generators_bitmask
- do ispin=1,2
+BEGIN_PROVIDER [ integer(bit_kind), generators_bitmask, (N_int,2,6) ]
+ implicit none
+ BEGIN_DOC
+ ! Bitmasks for generator determinants.
+ ! (N_int, alpha/beta, hole/particle, generator).
+ !
+ ! 3rd index is :
+ !
+ ! * 1 : hole for single exc
+ !
+ ! * 2 : particle for single exc
+ !
+ ! * 3 : hole for 1st exc of double
+ !
+ ! * 4 : particle for 1st exc of double
+ !
+ ! * 5 : hole for 2nd exc of double
+ !
+ ! * 6 : particle for 2nd exc of double
+ !
+ END_DOC
+ logical :: exists
+ PROVIDE ezfio_filename full_ijkl_bitmask
+
+ integer :: ispin, i
+ do ispin=1,2
do i=1,N_int
- generators_bitmask_restart(i,ispin,s_hole ,k) = iand(full_ijkl_bitmask(i),generators_bitmask_restart(i,ispin,s_hole,k) )
- generators_bitmask_restart(i,ispin,s_part ,k) = iand(full_ijkl_bitmask(i),generators_bitmask_restart(i,ispin,s_part,k) )
- generators_bitmask_restart(i,ispin,d_hole1,k) = iand(full_ijkl_bitmask(i),generators_bitmask_restart(i,ispin,d_hole1,k) )
- generators_bitmask_restart(i,ispin,d_part1,k) = iand(full_ijkl_bitmask(i),generators_bitmask_restart(i,ispin,d_part1,k) )
- generators_bitmask_restart(i,ispin,d_hole2,k) = iand(full_ijkl_bitmask(i),generators_bitmask_restart(i,ispin,d_hole2,k) )
- generators_bitmask_restart(i,ispin,d_part2,k) = iand(full_ijkl_bitmask(i),generators_bitmask_restart(i,ispin,d_part2,k) )
+ generators_bitmask(i,ispin,s_hole ) = reunion_of_inact_act_bitmask(i,ispin)
+ generators_bitmask(i,ispin,s_part ) = reunion_of_act_virt_bitmask(i,ispin)
+ generators_bitmask(i,ispin,d_hole1) = reunion_of_inact_act_bitmask(i,ispin)
+ generators_bitmask(i,ispin,d_part1) = reunion_of_act_virt_bitmask(i,ispin)
+ generators_bitmask(i,ispin,d_hole2) = reunion_of_inact_act_bitmask(i,ispin)
+ generators_bitmask(i,ispin,d_part2) = reunion_of_act_virt_bitmask(i,ispin)
enddo
- enddo
enddo
- endif
- IRP_IF MPI_DEBUG
- print *, irp_here, mpi_rank
- call MPI_BARRIER(MPI_COMM_WORLD, ierr)
- IRP_ENDIF
- IRP_IF MPI
- include 'mpif.h'
- integer :: ierr
- call MPI_BCAST( generators_bitmask_restart, N_int*2*6*N_generators_bitmask_restart, MPI_BIT_KIND, 0, MPI_COMM_WORLD, ierr)
- if (ierr /= MPI_SUCCESS) then
- stop 'Unable to read generators_bitmask_restart with MPI'
- endif
- IRP_ENDIF
-
+
END_PROVIDER
-
-BEGIN_PROVIDER [ integer(bit_kind), generators_bitmask, (N_int,2,6,N_generators_bitmask) ]
- implicit none
- BEGIN_DOC
- ! Bitmasks for generator determinants.
- ! (N_int, alpha/beta, hole/particle, generator).
- !
- ! 3rd index is :
- !
- ! * 1 : hole for single exc
- !
- ! * 2 : particle for single exc
- !
- ! * 3 : hole for 1st exc of double
- !
- ! * 4 : particle for 1st exc of double
- !
- ! * 5 : hole for 2nd exc of double
- !
- ! * 6 : particle for 2nd exc of double
- !
- END_DOC
- logical :: exists
- PROVIDE ezfio_filename full_ijkl_bitmask N_generators_bitmask
-
-if (mpi_master) then
- call ezfio_has_bitmasks_generators(exists)
- if (exists) then
- call ezfio_get_bitmasks_generators(generators_bitmask)
- else
- integer :: k, ispin, i
- do k=1,N_generators_bitmask
- do ispin=1,2
- do i=1,N_int
- generators_bitmask(i,ispin,s_hole ,k) = full_ijkl_bitmask(i)
- generators_bitmask(i,ispin,s_part ,k) = full_ijkl_bitmask(i)
- generators_bitmask(i,ispin,d_hole1,k) = full_ijkl_bitmask(i)
- generators_bitmask(i,ispin,d_part1,k) = full_ijkl_bitmask(i)
- generators_bitmask(i,ispin,d_hole2,k) = full_ijkl_bitmask(i)
- generators_bitmask(i,ispin,d_part2,k) = full_ijkl_bitmask(i)
- enddo
- enddo
- enddo
- endif
-
- do k=1,N_generators_bitmask
- do ispin=1,2
- do i=1,N_int
- generators_bitmask(i,ispin,s_hole ,k) = iand(full_ijkl_bitmask(i),generators_bitmask(i,ispin,s_hole,k) )
- generators_bitmask(i,ispin,s_part ,k) = iand(full_ijkl_bitmask(i),generators_bitmask(i,ispin,s_part,k) )
- generators_bitmask(i,ispin,d_hole1,k) = iand(full_ijkl_bitmask(i),generators_bitmask(i,ispin,d_hole1,k) )
- generators_bitmask(i,ispin,d_part1,k) = iand(full_ijkl_bitmask(i),generators_bitmask(i,ispin,d_part1,k) )
- generators_bitmask(i,ispin,d_hole2,k) = iand(full_ijkl_bitmask(i),generators_bitmask(i,ispin,d_hole2,k) )
- generators_bitmask(i,ispin,d_part2,k) = iand(full_ijkl_bitmask(i),generators_bitmask(i,ispin,d_part2,k) )
- enddo
- enddo
- enddo
- endif
- IRP_IF MPI_DEBUG
- print *, irp_here, mpi_rank
- call MPI_BARRIER(MPI_COMM_WORLD, ierr)
- IRP_ENDIF
- IRP_IF MPI
- include 'mpif.h'
- integer :: ierr
- call MPI_BCAST( generators_bitmask, N_int*2*6*N_generators_bitmask, MPI_BIT_KIND, 0, MPI_COMM_WORLD, ierr)
- if (ierr /= MPI_SUCCESS) then
- stop 'Unable to read generators_bitmask with MPI'
- endif
- IRP_ENDIF
-
-END_PROVIDER
-
-BEGIN_PROVIDER [ integer, N_cas_bitmask ]
- implicit none
- BEGIN_DOC
- ! Number of bitmasks for CAS
- END_DOC
- logical :: exists
- PROVIDE ezfio_filename
- PROVIDE N_cas_bitmask N_int
- if (mpi_master) then
- call ezfio_has_bitmasks_N_mask_cas(exists)
- if (exists) then
- call ezfio_get_bitmasks_N_mask_cas(N_cas_bitmask)
- integer :: N_int_check
- integer :: bit_kind_check
- call ezfio_get_bitmasks_bit_kind(bit_kind_check)
- if (bit_kind_check /= bit_kind) then
- print *, bit_kind_check, bit_kind
- print *, 'Error: bit_kind is not correct in EZFIO file'
- endif
- call ezfio_get_bitmasks_N_int(N_int_check)
- if (N_int_check /= N_int) then
- print *, N_int_check, N_int
- print *, 'Error: N_int is not correct in EZFIO file'
- endif
- else
- N_cas_bitmask = 1
- endif
- call write_int(6,N_cas_bitmask,'N_cas_bitmask')
- endif
- ASSERT (N_cas_bitmask > 0)
- IRP_IF MPI_DEBUG
- print *, irp_here, mpi_rank
- call MPI_BARRIER(MPI_COMM_WORLD, ierr)
- IRP_ENDIF
- IRP_IF MPI
- include 'mpif.h'
- integer :: ierr
- call MPI_BCAST( N_cas_bitmask, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
- if (ierr /= MPI_SUCCESS) then
- stop 'Unable to read N_cas_bitmask with MPI'
- endif
- IRP_ENDIF
-
-END_PROVIDER
-
-BEGIN_PROVIDER [ integer(bit_kind), cas_bitmask, (N_int,2,N_cas_bitmask) ]
- implicit none
- BEGIN_DOC
- ! Bitmasks for CAS reference determinants. (N_int, alpha/beta, CAS reference)
- END_DOC
- logical :: exists
- integer :: i,i_part,i_gen,j,k
- PROVIDE ezfio_filename generators_bitmask_restart full_ijkl_bitmask
- PROVIDE n_generators_bitmask HF_bitmask
-
- if (mpi_master) then
- call ezfio_has_bitmasks_cas(exists)
- if (exists) then
- call ezfio_get_bitmasks_cas(cas_bitmask)
- else
- if(N_generators_bitmask == 1)then
- do j=1, N_cas_bitmask
- do i=1, N_int
- cas_bitmask(i,1,j) = iand(not(HF_bitmask(i,1)),full_ijkl_bitmask(i))
- cas_bitmask(i,2,j) = iand(not(HF_bitmask(i,2)),full_ijkl_bitmask(i))
- enddo
- enddo
- else
- i_part = 2
- i_gen = 1
- do j=1, N_cas_bitmask
- do i=1, N_int
- cas_bitmask(i,1,j) = generators_bitmask_restart(i,1,i_part,i_gen)
- cas_bitmask(i,2,j) = generators_bitmask_restart(i,2,i_part,i_gen)
- enddo
- enddo
- endif
- endif
- do i=1,N_cas_bitmask
- do j = 1, N_cas_bitmask
- do k=1,N_int
- cas_bitmask(k,j,i) = iand(cas_bitmask(k,j,i),full_ijkl_bitmask(k))
- enddo
- enddo
+BEGIN_PROVIDER [ integer(bit_kind), reunion_of_core_inact_bitmask, (N_int,2)]
+ implicit none
+ BEGIN_DOC
+ ! Reunion of the core and inactive and virtual bitmasks
+ END_DOC
+ integer :: i
+ do i = 1, N_int
+ reunion_of_core_inact_bitmask(i,1) = ior(core_bitmask(i,1),inact_bitmask(i,1))
+ reunion_of_core_inact_bitmask(i,2) = ior(core_bitmask(i,2),inact_bitmask(i,2))
enddo
- write(*,*) 'Read CAS bitmask'
- endif
- IRP_IF MPI_DEBUG
- print *, irp_here, mpi_rank
- call MPI_BARRIER(MPI_COMM_WORLD, ierr)
- IRP_ENDIF
- IRP_IF MPI
- include 'mpif.h'
- integer :: ierr
- call MPI_BCAST( cas_bitmask, N_int*2*N_cas_bitmask, MPI_BIT_KIND, 0, MPI_COMM_WORLD, ierr)
- if (ierr /= MPI_SUCCESS) then
- stop 'Unable to read cas_bitmask with MPI'
- endif
- IRP_ENDIF
-
-
END_PROVIDER
- BEGIN_PROVIDER [ integer, n_core_inact_orb ]
- implicit none
- integer :: i
- n_core_inact_orb = 0
- do i = 1, N_int
- n_core_inact_orb += popcnt(reunion_of_core_inact_bitmask(i,1))
- enddo
- ENd_PROVIDER
- BEGIN_PROVIDER [ integer(bit_kind), reunion_of_core_inact_bitmask, (N_int,2)]
- implicit none
- BEGIN_DOC
- ! Reunion of the core and inactive and virtual bitmasks
- END_DOC
- integer :: i
- do i = 1, N_int
- reunion_of_core_inact_bitmask(i,1) = ior(core_bitmask(i,1),inact_bitmask(i,1))
- reunion_of_core_inact_bitmask(i,2) = ior(core_bitmask(i,2),inact_bitmask(i,2))
- enddo
- END_PROVIDER
+BEGIN_PROVIDER [integer(bit_kind), reunion_of_inact_act_bitmask, (N_int,2)]
+ implicit none
+ BEGIN_DOC
+ ! Reunion of the inactive and active bitmasks
+ END_DOC
+ integer :: i,j
+
+ do i = 1, N_int
+ reunion_of_inact_act_bitmask(i,1) = ior(inact_bitmask(i,1),act_bitmask(i,1))
+ reunion_of_inact_act_bitmask(i,2) = ior(inact_bitmask(i,2),act_bitmask(i,2))
+ enddo
+END_PROVIDER
+
+BEGIN_PROVIDER [integer(bit_kind), reunion_of_act_virt_bitmask, (N_int,2)]
+ implicit none
+ BEGIN_DOC
+ ! Reunion of the inactive and active bitmasks
+ END_DOC
+ integer :: i,j
+
+ do i = 1, N_int
+ reunion_of_act_virt_bitmask(i,1) = ior(virt_bitmask(i,1),act_bitmask(i,1))
+ reunion_of_act_virt_bitmask(i,2) = ior(virt_bitmask(i,2),act_bitmask(i,2))
+ enddo
+END_PROVIDER
- BEGIN_PROVIDER [integer(bit_kind), reunion_of_core_inact_act_bitmask, (N_int,2)]
- implicit none
- BEGIN_DOC
- ! Reunion of the core, inactive and active bitmasks
- END_DOC
- integer :: i,j
-
- do i = 1, N_int
- reunion_of_core_inact_act_bitmask(i,1) = ior(reunion_of_core_inact_bitmask(i,1),act_bitmask(i,1))
- reunion_of_core_inact_act_bitmask(i,2) = ior(reunion_of_core_inact_bitmask(i,2),act_bitmask(i,2))
- enddo
- END_PROVIDER
+BEGIN_PROVIDER [integer(bit_kind), reunion_of_core_inact_act_bitmask, (N_int,2)]
+ implicit none
+ BEGIN_DOC
+ ! Reunion of the core, inactive and active bitmasks
+ END_DOC
+ integer :: i,j
+
+ do i = 1, N_int
+ reunion_of_core_inact_act_bitmask(i,1) = ior(reunion_of_core_inact_bitmask(i,1),act_bitmask(i,1))
+ reunion_of_core_inact_act_bitmask(i,2) = ior(reunion_of_core_inact_bitmask(i,2),act_bitmask(i,2))
+ enddo
+END_PROVIDER
- BEGIN_PROVIDER [ integer(bit_kind), reunion_of_bitmask, (N_int,2)]
- implicit none
- BEGIN_DOC
- ! Reunion of the inactive, active and virtual bitmasks
- END_DOC
- integer :: i,j
- do i = 1, N_int
- reunion_of_bitmask(i,1) = ior(ior(cas_bitmask(i,1,1),inact_bitmask(i,1)),virt_bitmask(i,1))
- reunion_of_bitmask(i,2) = ior(ior(cas_bitmask(i,2,1),inact_bitmask(i,2)),virt_bitmask(i,2))
- enddo
- END_PROVIDER
+BEGIN_PROVIDER [ integer(bit_kind), reunion_of_bitmask, (N_int,2)]
+ implicit none
+ BEGIN_DOC
+ ! Reunion of the inactive, active and virtual bitmasks
+ END_DOC
+ integer :: i,j
+ do i = 1, N_int
+ reunion_of_bitmask(i,1) = ior(ior(act_bitmask(i,1),inact_bitmask(i,1)),virt_bitmask(i,1))
+ reunion_of_bitmask(i,2) = ior(ior(act_bitmask(i,2),inact_bitmask(i,2)),virt_bitmask(i,2))
+ enddo
+END_PROVIDER
BEGIN_PROVIDER [ integer(bit_kind), inact_virt_bitmask, (N_int,2)]
&BEGIN_PROVIDER [ integer(bit_kind), core_inact_virt_bitmask, (N_int,2)]
- implicit none
- BEGIN_DOC
- ! Reunion of the inactive and virtual bitmasks
- END_DOC
- integer :: i,j
- do i = 1, N_int
- inact_virt_bitmask(i,1) = ior(inact_bitmask(i,1),virt_bitmask(i,1))
- inact_virt_bitmask(i,2) = ior(inact_bitmask(i,2),virt_bitmask(i,2))
- core_inact_virt_bitmask(i,1) = ior(core_bitmask(i,1),inact_virt_bitmask(i,1))
- core_inact_virt_bitmask(i,2) = ior(core_bitmask(i,2),inact_virt_bitmask(i,2))
- enddo
- END_PROVIDER
-
-BEGIN_PROVIDER [ integer, i_bitmask_gen ]
- implicit none
- BEGIN_DOC
- ! Current bitmask for the generators
- END_DOC
- i_bitmask_gen = 1
+ implicit none
+ BEGIN_DOC
+ ! Reunion of the inactive and virtual bitmasks
+ END_DOC
+ integer :: i,j
+ do i = 1, N_int
+ inact_virt_bitmask(i,1) = ior(inact_bitmask(i,1),virt_bitmask(i,1))
+ inact_virt_bitmask(i,2) = ior(inact_bitmask(i,2),virt_bitmask(i,2))
+ core_inact_virt_bitmask(i,1) = ior(core_bitmask(i,1),inact_virt_bitmask(i,1))
+ core_inact_virt_bitmask(i,2) = ior(core_bitmask(i,2),inact_virt_bitmask(i,2))
+ enddo
END_PROVIDER
- BEGIN_PROVIDER [ integer(bit_kind), unpaired_alpha_electrons, (N_int)]
- implicit none
- BEGIN_DOC
- ! Bitmask reprenting the unpaired alpha electrons in the HF_bitmask
- END_DOC
- integer :: i
- unpaired_alpha_electrons = 0_bit_kind
- do i = 1, N_int
- unpaired_alpha_electrons(i) = xor(HF_bitmask(i,1),HF_bitmask(i,2))
- enddo
- END_PROVIDER
-
- BEGIN_PROVIDER [integer(bit_kind), closed_shell_ref_bitmask, (N_int,2)]
- implicit none
- integer :: i,j
- do i = 1, N_int
- closed_shell_ref_bitmask(i,1) = ior(ref_bitmask(i,1),cas_bitmask(i,1,1))
- closed_shell_ref_bitmask(i,2) = ior(ref_bitmask(i,2),cas_bitmask(i,2,1))
- enddo
- END_PROVIDER
-
-
- BEGIN_PROVIDER [ integer(bit_kind), reunion_of_cas_inact_bitmask, (N_int,2)]
- implicit none
- BEGIN_DOC
- ! Reunion of the inactive, active and virtual bitmasks
- END_DOC
- integer :: i,j
- do i = 1, N_int
- reunion_of_cas_inact_bitmask(i,1) = ior(act_bitmask(i,1),inact_bitmask(i,1))
- reunion_of_cas_inact_bitmask(i,2) = ior(act_bitmask(i,2),inact_bitmask(i,2))
- enddo
- END_PROVIDER
-
-
- BEGIN_PROVIDER [integer, n_core_orb_allocate]
- implicit none
- n_core_orb_allocate = max(n_core_orb,1)
- END_PROVIDER
-
- BEGIN_PROVIDER [integer, n_inact_orb_allocate]
- implicit none
- n_inact_orb_allocate = max(n_inact_orb,1)
- END_PROVIDER
-
- BEGIN_PROVIDER [integer, n_virt_orb_allocate]
- implicit none
- n_virt_orb_allocate = max(n_virt_orb,1)
- END_PROVIDER
+BEGIN_PROVIDER [ integer(bit_kind), unpaired_alpha_electrons, (N_int)]
+ implicit none
+ BEGIN_DOC
+ ! Bitmask reprenting the unpaired alpha electrons in the HF_bitmask
+ END_DOC
+ integer :: i
+ unpaired_alpha_electrons = 0_bit_kind
+ do i = 1, N_int
+ unpaired_alpha_electrons(i) = xor(HF_bitmask(i,1),HF_bitmask(i,2))
+ enddo
+END_PROVIDER
+BEGIN_PROVIDER [integer(bit_kind), closed_shell_ref_bitmask, (N_int,2)]
+ implicit none
+ integer :: i,j
+ do i = 1, N_int
+ closed_shell_ref_bitmask(i,1) = ior(ref_bitmask(i,1),act_bitmask(i,1))
+ closed_shell_ref_bitmask(i,2) = ior(ref_bitmask(i,2),act_bitmask(i,2))
+ enddo
+END_PROVIDER
diff --git a/src/bitmask/bitmasks_routines.irp.f b/src/bitmask/bitmasks_routines.irp.f
index 378a3dcd..5c4bf347 100644
--- a/src/bitmask/bitmasks_routines.irp.f
+++ b/src/bitmask/bitmasks_routines.irp.f
@@ -33,7 +33,7 @@ subroutine bitstring_to_list( string, list, n_elements, Nint)
use bitmasks
implicit none
BEGIN_DOC
- ! Gives the inidices(+1) of the bits set to 1 in the bit string
+ ! Gives the indices(+1) of the bits set to 1 in the bit string
END_DOC
integer, intent(in) :: Nint
integer(bit_kind), intent(in) :: string(Nint)
@@ -213,3 +213,34 @@ subroutine print_spindet(string,Nint)
print *, trim(output(1))
end
+
+logical function is_integer_in_string(bite,string,Nint)
+ use bitmasks
+ implicit none
+ integer, intent(in) :: bite,Nint
+ integer(bit_kind), intent(in) :: string(Nint)
+ integer(bit_kind) :: string_bite(Nint)
+ integer :: i,itot,itot_and
+ character*(2048) :: output(1)
+ string_bite = 0_bit_kind
+ call set_bit_to_integer(bite,string_bite,Nint)
+ itot = 0
+ itot_and = 0
+ is_integer_in_string = .False.
+!print*,''
+!print*,''
+!print*,'bite = ',bite
+!call bitstring_to_str( output(1), string_bite, Nint )
+! print *, trim(output(1))
+!call bitstring_to_str( output(1), string, Nint )
+! print *, trim(output(1))
+ do i = 1, Nint
+ itot += popcnt(string(i))
+ itot_and += popcnt(ior(string(i),string_bite(i)))
+ enddo
+!print*,'itot,itot_and',itot,itot_and
+ if(itot == itot_and)then
+ is_integer_in_string = .True.
+ endif
+!pause
+end
diff --git a/src/bitmask/core_inact_act_virt.irp.f b/src/bitmask/core_inact_act_virt.irp.f
index f830da4e..d30e989f 100644
--- a/src/bitmask/core_inact_act_virt.irp.f
+++ b/src/bitmask/core_inact_act_virt.irp.f
@@ -1,246 +1,415 @@
use bitmasks
+BEGIN_PROVIDER [ integer, n_core_orb]
+ implicit none
+ BEGIN_DOC
+ ! Number of core MOs
+ END_DOC
+ integer :: i
+
+ n_core_orb = 0
+ do i = 1, mo_num
+ if(mo_class(i) == 'Core')then
+ n_core_orb += 1
+ endif
+ enddo
+
+ call write_int(6,n_core_orb, 'Number of core MOs')
+
+END_PROVIDER
- BEGIN_PROVIDER [ integer, n_core_orb]
- &BEGIN_PROVIDER [ integer, n_inact_orb ]
- &BEGIN_PROVIDER [ integer, n_act_orb]
- &BEGIN_PROVIDER [ integer, n_virt_orb ]
- &BEGIN_PROVIDER [ integer, n_del_orb ]
- implicit none
- BEGIN_DOC
- ! inact_bitmask : Bitmask of the inactive orbitals which are supposed to be doubly excited
- ! in post CAS methods
- ! n_inact_orb : Number of inactive orbitals
- ! virt_bitmask : Bitmaks of vritual orbitals which are supposed to be recieve electrons
- ! in post CAS methods
- ! n_virt_orb : Number of virtual orbitals
- ! list_inact : List of the inactive orbitals which are supposed to be doubly excited
- ! in post CAS methods
- ! list_virt : List of vritual orbitals which are supposed to be recieve electrons
- ! in post CAS methods
- ! list_inact_reverse : reverse list of inactive orbitals
- ! list_inact_reverse(i) = 0 ::> not an inactive
- ! list_inact_reverse(i) = k ::> IS the kth inactive
- ! list_virt_reverse : reverse list of virtual orbitals
- ! list_virt_reverse(i) = 0 ::> not an virtual
- ! list_virt_reverse(i) = k ::> IS the kth virtual
- ! list_act(i) = index of the ith active orbital
- !
- ! list_act_reverse : reverse list of active orbitals
- ! list_act_reverse(i) = 0 ::> not an active
- ! list_act_reverse(i) = k ::> IS the kth active orbital
- END_DOC
- logical :: exists
- integer :: j,i
+BEGIN_PROVIDER [ integer, n_inact_orb ]
+ implicit none
+ BEGIN_DOC
+ ! Number of inactive MOs
+ END_DOC
+ integer :: i
+
+ n_inact_orb = 0
+ do i = 1, mo_num
+ if (mo_class(i) == 'Inactive')then
+ n_inact_orb += 1
+ endif
+ enddo
+
+ call write_int(6,n_inact_orb,'Number of inactive MOs')
+
+END_PROVIDER
- n_core_orb = 0
- n_inact_orb = 0
- n_act_orb = 0
- n_virt_orb = 0
- n_del_orb = 0
- do i = 1, mo_num
- if(mo_class(i) == 'Core')then
- n_core_orb += 1
- else if (mo_class(i) == 'Inactive')then
- n_inact_orb += 1
- else if (mo_class(i) == 'Active')then
- n_act_orb += 1
- else if (mo_class(i) == 'Virtual')then
- n_virt_orb += 1
- else if (mo_class(i) == 'Deleted')then
- n_del_orb += 1
- endif
- enddo
+BEGIN_PROVIDER [ integer, n_act_orb]
+ implicit none
+ BEGIN_DOC
+ ! Number of active MOs
+ END_DOC
+ integer :: i
+
+ n_act_orb = 0
+ do i = 1, mo_num
+ if (mo_class(i) == 'Active')then
+ n_act_orb += 1
+ endif
+ enddo
+
+ call write_int(6,n_act_orb, 'Number of active MOs')
+
+END_PROVIDER
+
+BEGIN_PROVIDER [ integer, n_virt_orb ]
+ implicit none
+ BEGIN_DOC
+ ! Number of virtual MOs
+ END_DOC
+ integer :: i
+
+ n_virt_orb = 0
+ do i = 1, mo_num
+ if (mo_class(i) == 'Virtual')then
+ n_virt_orb += 1
+ endif
+ enddo
+
+ call write_int(6,n_virt_orb, 'Number of virtual MOs')
+
+END_PROVIDER
+
+BEGIN_PROVIDER [ integer, n_del_orb ]
+ implicit none
+ BEGIN_DOC
+ ! Number of deleted MOs
+ END_DOC
+ integer :: i
+
+ n_del_orb = 0
+ do i = 1, mo_num
+ if (mo_class(i) == 'Deleted')then
+ n_del_orb += 1
+ endif
+ enddo
+
+ call write_int(6,n_del_orb, 'Number of deleted MOs')
+
+END_PROVIDER
- call write_int(6,n_core_orb, 'Number of core MOs')
- call write_int(6,n_inact_orb,'Number of inactive MOs')
- call write_int(6,n_act_orb, 'Number of active MOs')
- call write_int(6,n_virt_orb, 'Number of virtual MOs')
- call write_int(6,n_del_orb, 'Number of deleted MOs')
+BEGIN_PROVIDER [ integer, n_core_inact_orb ]
+ implicit none
+ BEGIN_DOC
+ ! n_core + n_inact
+ END_DOC
+ integer :: i
+ n_core_inact_orb = 0
+ do i = 1, N_int
+ n_core_inact_orb += popcnt(reunion_of_core_inact_bitmask(i,1))
+ enddo
+END_PROVIDER
+BEGIN_PROVIDER [integer, n_inact_act_orb ]
+ implicit none
+ BEGIN_DOC
+ ! n_inact + n_act
+ END_DOC
+ n_inact_act_orb = (n_inact_orb+n_act_orb)
+END_PROVIDER
+
+BEGIN_PROVIDER [integer, dim_list_core_orb]
+ implicit none
+ BEGIN_DOC
+ ! dimensions for the allocation of list_core.
+ ! it is at least 1
+ END_DOC
+ dim_list_core_orb = max(n_core_orb,1)
+END_PROVIDER
+
+BEGIN_PROVIDER [integer, dim_list_inact_orb]
+ implicit none
+ BEGIN_DOC
+ ! dimensions for the allocation of list_inact.
+ ! it is at least 1
+ END_DOC
+ dim_list_inact_orb = max(n_inact_orb,1)
+END_PROVIDER
+
+BEGIN_PROVIDER [integer, dim_list_core_inact_orb]
+ implicit none
+ BEGIN_DOC
+ ! dimensions for the allocation of list_core.
+ ! it is at least 1
+ END_DOC
+ dim_list_core_inact_orb = max(n_core_inact_orb,1)
+END_PROVIDER
+
+BEGIN_PROVIDER [integer, dim_list_act_orb]
+ implicit none
+ BEGIN_DOC
+ ! dimensions for the allocation of list_act.
+ ! it is at least 1
+ END_DOC
+ dim_list_act_orb = max(n_act_orb,1)
+END_PROVIDER
+
+BEGIN_PROVIDER [integer, dim_list_virt_orb]
+ implicit none
+ BEGIN_DOC
+ ! dimensions for the allocation of list_virt.
+ ! it is at least 1
+ END_DOC
+ dim_list_virt_orb = max(n_virt_orb,1)
+END_PROVIDER
+
+BEGIN_PROVIDER [integer, dim_list_del_orb]
+ implicit none
+ BEGIN_DOC
+ ! dimensions for the allocation of list_del.
+ ! it is at least 1
+ END_DOC
+ dim_list_del_orb = max(n_del_orb,1)
+END_PROVIDER
+
+BEGIN_PROVIDER [integer, n_core_inact_act_orb ]
+ implicit none
+ BEGIN_DOC
+ ! Number of core inactive and active MOs
+ END_DOC
+ n_core_inact_act_orb = (n_core_orb + n_inact_orb + n_act_orb)
+END_PROVIDER
+
+
+
+
+ BEGIN_PROVIDER [ integer(bit_kind), core_bitmask , (N_int,2) ]
+ implicit none
+ BEGIN_DOC
+ ! Bitmask identifying the core MOs
+ END_DOC
+ core_bitmask = 0_bit_kind
+ if(n_core_orb > 0)then
+ call list_to_bitstring( core_bitmask(1,1), list_core, n_core_orb, N_int)
+ call list_to_bitstring( core_bitmask(1,2), list_core, n_core_orb, N_int)
+ endif
+ END_PROVIDER
+
+ BEGIN_PROVIDER [ integer(bit_kind), inact_bitmask, (N_int,2) ]
+ implicit none
+ BEGIN_DOC
+ ! Bitmask identifying the inactive MOs
+ END_DOC
+ inact_bitmask = 0_bit_kind
+ if(n_inact_orb > 0)then
+ call list_to_bitstring( inact_bitmask(1,1), list_inact, n_inact_orb, N_int)
+ call list_to_bitstring( inact_bitmask(1,2), list_inact, n_inact_orb, N_int)
+ endif
+ END_PROVIDER
+
+ BEGIN_PROVIDER [ integer(bit_kind), act_bitmask , (N_int,2) ]
+ implicit none
+ BEGIN_DOC
+ ! Bitmask identifying the active MOs
+ END_DOC
+ act_bitmask = 0_bit_kind
+ if(n_act_orb > 0)then
+ call list_to_bitstring( act_bitmask(1,1), list_act, n_act_orb, N_int)
+ call list_to_bitstring( act_bitmask(1,2), list_act, n_act_orb, N_int)
+ endif
+ END_PROVIDER
+
+ BEGIN_PROVIDER [ integer(bit_kind), virt_bitmask , (N_int,2) ]
+ implicit none
+ BEGIN_DOC
+ ! Bitmask identifying the virtual MOs
+ END_DOC
+ virt_bitmask = 0_bit_kind
+ if(n_virt_orb > 0)then
+ call list_to_bitstring( virt_bitmask(1,1), list_virt, n_virt_orb, N_int)
+ call list_to_bitstring( virt_bitmask(1,2), list_virt, n_virt_orb, N_int)
+ endif
+ END_PROVIDER
+
+ BEGIN_PROVIDER [ integer(bit_kind), del_bitmask , (N_int,2) ]
+ implicit none
+ BEGIN_DOC
+ ! Bitmask identifying the deleted MOs
+ END_DOC
+
+ del_bitmask = 0_bit_kind
+
+ if(n_del_orb > 0)then
+ call list_to_bitstring( del_bitmask(1,1), list_del, n_del_orb, N_int)
+ call list_to_bitstring( del_bitmask(1,2), list_del, n_del_orb, N_int)
+ endif
+
END_PROVIDER
- BEGIN_PROVIDER [integer, dim_list_core_orb]
-&BEGIN_PROVIDER [integer, dim_list_inact_orb]
-&BEGIN_PROVIDER [integer, dim_list_virt_orb]
-&BEGIN_PROVIDER [integer, dim_list_act_orb]
-&BEGIN_PROVIDER [integer, dim_list_del_orb]
- implicit none
- BEGIN_DOC
-! dimensions for the allocation of list_inact, list_virt, list_core and list_act
-! it is at least 1
- END_DOC
- dim_list_core_orb = max(n_core_orb,1)
- dim_list_inact_orb = max(n_inact_orb,1)
- dim_list_virt_orb = max(n_virt_orb,1)
- dim_list_act_orb = max(n_act_orb,1)
- dim_list_del_orb = max(n_del_orb,1)
-END_PROVIDER
-
- BEGIN_PROVIDER [ integer, list_inact, (dim_list_inact_orb)]
-&BEGIN_PROVIDER [ integer, list_virt, (dim_list_virt_orb)]
-&BEGIN_PROVIDER [ integer, list_inact_reverse, (mo_num)]
-&BEGIN_PROVIDER [ integer, list_virt_reverse, (mo_num)]
-&BEGIN_PROVIDER [ integer, list_del_reverse, (mo_num)]
-&BEGIN_PROVIDER [ integer, list_del, (mo_num)]
-&BEGIN_PROVIDER [integer, list_core, (dim_list_core_orb)]
-&BEGIN_PROVIDER [integer, list_core_reverse, (mo_num)]
-&BEGIN_PROVIDER [integer, list_act, (dim_list_act_orb)]
-&BEGIN_PROVIDER [integer, list_act_reverse, (mo_num)]
-&BEGIN_PROVIDER [ integer(bit_kind), core_bitmask, (N_int,2)]
-&BEGIN_PROVIDER [ integer(bit_kind), inact_bitmask, (N_int,2) ]
-&BEGIN_PROVIDER [ integer(bit_kind), act_bitmask, (N_int,2) ]
-&BEGIN_PROVIDER [ integer(bit_kind), virt_bitmask, (N_int,2) ]
-&BEGIN_PROVIDER [ integer(bit_kind), del_bitmask, (N_int,2) ]
- implicit none
- BEGIN_DOC
- ! inact_bitmask : Bitmask of the inactive orbitals which are supposed to be doubly excited
- ! in post CAS methods
- ! n_inact_orb : Number of inactive orbitals
- ! virt_bitmask : Bitmaks of vritual orbitals which are supposed to be recieve electrons
- ! in post CAS methods
- ! n_virt_orb : Number of virtual orbitals
- ! list_inact : List of the inactive orbitals which are supposed to be doubly excited
- ! in post CAS methods
- ! list_virt : List of vritual orbitals which are supposed to be recieve electrons
- ! in post CAS methods
- ! list_inact_reverse : reverse list of inactive orbitals
- ! list_inact_reverse(i) = 0 ::> not an inactive
- ! list_inact_reverse(i) = k ::> IS the kth inactive
- ! list_virt_reverse : reverse list of virtual orbitals
- ! list_virt_reverse(i) = 0 ::> not an virtual
- ! list_virt_reverse(i) = k ::> IS the kth virtual
- ! list_act(i) = index of the ith active orbital
- !
- ! list_act_reverse : reverse list of active orbitals
- ! list_act_reverse(i) = 0 ::> not an active
- ! list_act_reverse(i) = k ::> IS the kth active orbital
- END_DOC
- logical :: exists
- integer :: j,i
- integer :: n_core_orb_tmp, n_inact_orb_tmp, n_act_orb_tmp, n_virt_orb_tmp,n_del_orb_tmp
- integer :: list_core_tmp(N_int*bit_kind_size)
- integer :: list_inact_tmp(N_int*bit_kind_size)
- integer :: list_act_tmp(N_int*bit_kind_size)
- integer :: list_virt_tmp(N_int*bit_kind_size)
- integer :: list_del_tmp(N_int*bit_kind_size)
- list_core = 0
- list_inact = 0
- list_act = 0
- list_virt = 0
- list_del = 0
- list_core_reverse = 0
- list_inact_reverse = 0
- list_act_reverse = 0
- list_virt_reverse = 0
- list_del_reverse = 0
- n_core_orb_tmp = 0
- n_inact_orb_tmp = 0
- n_act_orb_tmp = 0
- n_virt_orb_tmp = 0
- n_del_orb_tmp = 0
- do i = 1, mo_num
- if(mo_class(i) == 'Core')then
- n_core_orb_tmp += 1
- list_core(n_core_orb_tmp) = i
- list_core_tmp(n_core_orb_tmp) = i
- list_core_reverse(i) = n_core_orb_tmp
- else if (mo_class(i) == 'Inactive')then
- n_inact_orb_tmp += 1
- list_inact(n_inact_orb_tmp) = i
- list_inact_tmp(n_inact_orb_tmp) = i
- list_inact_reverse(i) = n_inact_orb_tmp
- else if (mo_class(i) == 'Active')then
- n_act_orb_tmp += 1
- list_act(n_act_orb_tmp) = i
- list_act_tmp(n_act_orb_tmp) = i
- list_act_reverse(i) = n_act_orb_tmp
- else if (mo_class(i) == 'Virtual')then
- n_virt_orb_tmp += 1
- list_virt(n_virt_orb_tmp) = i
- list_virt_tmp(n_virt_orb_tmp) = i
- list_virt_reverse(i) = n_virt_orb_tmp
- else if (mo_class(i) == 'Deleted')then
- n_del_orb_tmp += 1
- list_del(n_del_orb_tmp) = i
- list_del_tmp(n_del_orb_tmp) = i
- list_del_reverse(i) = n_del_orb_tmp
- endif
- enddo
-
- if(n_core_orb.ne.0)then
- call list_to_bitstring( core_bitmask(1,1), list_core, n_core_orb, N_int)
- call list_to_bitstring( core_bitmask(1,2), list_core, n_core_orb, N_int)
- endif
- if(n_inact_orb.ne.0)then
- call list_to_bitstring( inact_bitmask(1,1), list_inact, n_inact_orb, N_int)
- call list_to_bitstring( inact_bitmask(1,2), list_inact, n_inact_orb, N_int)
- endif
- if(n_act_orb.ne.0)then
- call list_to_bitstring( act_bitmask(1,1), list_act, n_act_orb, N_int)
- call list_to_bitstring( act_bitmask(1,2), list_act, n_act_orb, N_int)
- endif
- if(n_virt_orb.ne.0)then
- call list_to_bitstring( virt_bitmask(1,1), list_virt, n_virt_orb, N_int)
- call list_to_bitstring( virt_bitmask(1,2), list_virt, n_virt_orb, N_int)
- endif
- if(n_del_orb.ne.0)then
- call list_to_bitstring( del_bitmask(1,1), list_del, n_del_orb, N_int)
- call list_to_bitstring( del_bitmask(1,2), list_del, n_del_orb, N_int)
- endif
-END_PROVIDER
+
+ BEGIN_PROVIDER [ integer, list_core , (dim_list_core_orb) ]
+&BEGIN_PROVIDER [ integer, list_core_reverse, (mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! List of MO indices which are in the core.
+ END_DOC
+ integer :: i, n
+ list_core = 0
+ list_core_reverse = 0
-BEGIN_PROVIDER [integer, n_inact_act_orb ]
- implicit none
- n_inact_act_orb = (n_inact_orb+n_act_orb)
+ n=0
+ do i = 1, mo_num
+ if(mo_class(i) == 'Core')then
+ n += 1
+ list_core(n) = i
+ list_core_reverse(i) = n
+ endif
+ enddo
+ print *, 'Core MOs:'
+ print *, list_core(1:n_core_orb)
+
+END_PROVIDER
+
+ BEGIN_PROVIDER [ integer, list_inact , (dim_list_inact_orb) ]
+&BEGIN_PROVIDER [ integer, list_inact_reverse, (mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! List of MO indices which are inactive.
+ END_DOC
+ integer :: i, n
+ list_inact = 0
+ list_inact_reverse = 0
-END_PROVIDER
+ n=0
+ do i = 1, mo_num
+ if (mo_class(i) == 'Inactive')then
+ n += 1
+ list_inact(n) = i
+ list_inact_reverse(i) = n
+ endif
+ enddo
+ print *, 'Inactive MOs:'
+ print *, list_inact(1:n_inact_orb)
+
+END_PROVIDER
+
+ BEGIN_PROVIDER [ integer, list_virt , (dim_list_virt_orb) ]
+&BEGIN_PROVIDER [ integer, list_virt_reverse, (mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! List of MO indices which are virtual
+ END_DOC
+ integer :: i, n
+ list_virt = 0
+ list_virt_reverse = 0
-BEGIN_PROVIDER [integer, list_inact_act, (n_inact_act_orb)]
- integer :: i,itmp
- itmp = 0
- do i = 1, n_inact_orb
- itmp += 1
- list_inact_act(itmp) = list_inact(i)
- enddo
- do i = 1, n_act_orb
- itmp += 1
- list_inact_act(itmp) = list_act(i)
- enddo
-END_PROVIDER
+ n=0
+ do i = 1, mo_num
+ if (mo_class(i) == 'Virtual')then
+ n += 1
+ list_virt(n) = i
+ list_virt_reverse(i) = n
+ endif
+ enddo
+ print *, 'Virtual MOs:'
+ print *, list_virt(1:n_virt_orb)
+
+END_PROVIDER
+
+ BEGIN_PROVIDER [ integer, list_del , (dim_list_del_orb) ]
+&BEGIN_PROVIDER [ integer, list_del_reverse, (mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! List of MO indices which are deleted.
+ END_DOC
+ integer :: i, n
+ list_del = 0
+ list_del_reverse = 0
-BEGIN_PROVIDER [integer, n_core_inact_act_orb ]
- implicit none
- n_core_inact_act_orb = (n_core_orb + n_inact_orb + n_act_orb)
+ n=0
+ do i = 1, mo_num
+ if (mo_class(i) == 'Deleted')then
+ n += 1
+ list_del(n) = i
+ list_del_reverse(i) = n
+ endif
+ enddo
+ print *, 'Deleted MOs:'
+ print *, list_del(1:n_del_orb)
+
+END_PROVIDER
+
+ BEGIN_PROVIDER [ integer, list_act , (dim_list_act_orb) ]
+&BEGIN_PROVIDER [ integer, list_act_reverse, (mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! List of MO indices which are in the active.
+ END_DOC
+ integer :: i, n
+ list_act = 0
+ list_act_reverse = 0
-END_PROVIDER
+ n=0
+ do i = 1, mo_num
+ if (mo_class(i) == 'Active')then
+ n += 1
+ list_act(n) = i
+ list_act_reverse(i) = n
+ endif
+ enddo
+ print *, 'Active MOs:'
+ print *, list_act(1:n_act_orb)
+
+END_PROVIDER
+
- BEGIN_PROVIDER [integer, list_core_inact_act, (n_core_inact_act_orb)]
-&BEGIN_PROVIDER [ integer, list_core_inact_act_reverse, (n_core_inact_act_orb)]
- integer :: i,itmp
- itmp = 0
- do i = 1, n_core_orb
- itmp += 1
- list_core_inact_act(itmp) = list_core(i)
- enddo
- do i = 1, n_inact_orb
- itmp += 1
- list_core_inact_act(itmp) = list_inact(i)
- enddo
- do i = 1, n_act_orb
- itmp += 1
- list_core_inact_act(itmp) = list_act(i)
- enddo
-
- integer :: occ_inact(N_int*bit_kind_size)
- occ_inact = 0
- call bitstring_to_list(reunion_of_core_inact_act_bitmask(1,1), occ_inact(1), itest, N_int)
- list_inact_reverse = 0
- do i = 1, n_core_inact_act_orb
- list_core_inact_act_reverse(occ_inact(i)) = i
- enddo
-END_PROVIDER
+
+ BEGIN_PROVIDER [ integer, list_core_inact , (dim_list_core_inact_orb) ]
+&BEGIN_PROVIDER [ integer, list_core_inact_reverse, (mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! List of indices of the core and inactive MOs
+ END_DOC
+ integer :: i,itmp
+ call bitstring_to_list(reunion_of_core_inact_bitmask(1,1), list_core_inact, itmp, N_int)
+ list_core_inact_reverse = 0
+ ASSERT (itmp == n_core_inact_orb)
+ do i = 1, n_core_inact_orb
+ list_core_inact_reverse(list_core_inact(i)) = i
+ enddo
+ print *, 'Core and Inactive MOs:'
+ print *, list_core_inact(1:n_core_inact_orb)
+END_PROVIDER
+
+
+ BEGIN_PROVIDER [ integer, list_core_inact_act , (n_core_inact_act_orb) ]
+&BEGIN_PROVIDER [ integer, list_core_inact_act_reverse, (mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! List of indices of the core inactive and active MOs
+ END_DOC
+ integer :: i,itmp
+ call bitstring_to_list(reunion_of_core_inact_act_bitmask(1,1), list_core_inact_act, itmp, N_int)
+ list_core_inact_act_reverse = 0
+ ASSERT (itmp == n_core_inact_act_orb)
+ do i = 1, n_core_inact_act_orb
+ list_core_inact_act_reverse(list_core_inact_act(i)) = i
+ enddo
+ print *, 'Core, Inactive and Active MOs:'
+ print *, list_core_inact_act(1:n_core_inact_act_orb)
+END_PROVIDER
+
+
+ BEGIN_PROVIDER [ integer, list_inact_act , (n_inact_act_orb) ]
+&BEGIN_PROVIDER [ integer, list_inact_act_reverse, (mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! List of indices of the inactive and active MOs
+ END_DOC
+ integer :: i,itmp
+ call bitstring_to_list(reunion_of_inact_act_bitmask(1,1), list_inact_act, itmp, N_int)
+ list_inact_act_reverse = 0
+ ASSERT (itmp == n_inact_act_orb)
+ do i = 1, n_inact_act_orb
+ list_inact_act_reverse(list_inact_act(i)) = i
+ enddo
+ print *, 'Inactive and Active MOs:'
+ print *, list_inact_act(1:n_inact_act_orb)
+END_PROVIDER
+
diff --git a/src/bitmask/modify_bitmasks.irp.f b/src/bitmask/modify_bitmasks.irp.f
index fa660680..834be6c8 100644
--- a/src/bitmask/modify_bitmasks.irp.f
+++ b/src/bitmask/modify_bitmasks.irp.f
@@ -1,26 +1,5 @@
use bitmasks
-subroutine initialize_bitmask_to_restart_ones
- implicit none
- integer :: i,j,k,l,m
- integer :: ispin
- BEGIN_DOC
- ! Initialization of the generators_bitmask to the restart bitmask
- END_DOC
- do i = 1, N_int
- do k=1,N_generators_bitmask
- do ispin=1,2
- generators_bitmask(i,ispin,s_hole ,k) = generators_bitmask_restart(i,ispin,s_hole ,k)
- generators_bitmask(i,ispin,s_part ,k) = generators_bitmask_restart(i,ispin,s_part ,k)
- generators_bitmask(i,ispin,d_hole1,k) = generators_bitmask_restart(i,ispin,d_hole1,k)
- generators_bitmask(i,ispin,d_part1,k) = generators_bitmask_restart(i,ispin,d_part1,k)
- generators_bitmask(i,ispin,d_hole2,k) = generators_bitmask_restart(i,ispin,d_hole2,k)
- generators_bitmask(i,ispin,d_part2,k) = generators_bitmask_restart(i,ispin,d_part2,k)
- enddo
- enddo
- enddo
-end
-
subroutine modify_bitmasks_for_hole(i_hole)
implicit none
@@ -33,26 +12,22 @@ subroutine modify_bitmasks_for_hole(i_hole)
END_DOC
! Set to Zero the holes
- do k=1,N_generators_bitmask
- do l = 1, 3
+ do l = 1, 3
i = index_holes_bitmask(l)
do ispin=1,2
do j = 1, N_int
- generators_bitmask(j,ispin,i,k) = 0_bit_kind
+ generators_bitmask(j,ispin,i) = 0_bit_kind
enddo
enddo
- enddo
enddo
k = shiftr(i_hole-1,bit_kind_shift)+1
j = i_hole-shiftl(k-1,bit_kind_shift)-1
- do m = 1, N_generators_bitmask
- do l = 1, 3
+ do l = 1, 3
i = index_holes_bitmask(l)
do ispin=1,2
- generators_bitmask(k,ispin,i,m) = ibset(generators_bitmask(k,ispin,i,m),j)
+ generators_bitmask(k,ispin,i) = ibset(generators_bitmask(k,ispin,i),j)
enddo
- enddo
enddo
end
@@ -69,13 +44,11 @@ subroutine modify_bitmasks_for_hole_in_out(i_hole)
k = shiftr(i_hole-1,bit_kind_shift)+1
j = i_hole-shiftl(k-1,bit_kind_shift)-1
- do m = 1, N_generators_bitmask
- do l = 1, 3
+ do l = 1, 3
i = index_holes_bitmask(l)
do ispin=1,2
- generators_bitmask(k,ispin,i,m) = ibset(generators_bitmask(k,ispin,i,m),j)
+ generators_bitmask(k,ispin,i) = ibset(generators_bitmask(k,ispin,i),j)
enddo
- enddo
enddo
end
@@ -91,75 +64,67 @@ subroutine modify_bitmasks_for_particl(i_part)
END_DOC
! Set to Zero the particles
- do k=1,N_generators_bitmask
- do l = 1, 3
+ do l = 1, 3
i = index_particl_bitmask(l)
- do ispin=1,2
+ do ispin=1,2
do j = 1, N_int
- generators_bitmask(j,ispin,i,k) = 0_bit_kind
+ generators_bitmask(j,ispin,i) = 0_bit_kind
enddo
- enddo
enddo
enddo
k = shiftr(i_part-1,bit_kind_shift)+1
j = i_part-shiftl(k-1,bit_kind_shift)-1
- do m = 1, N_generators_bitmask
- do l = 1, 3
+ do l = 1, 3
i = index_particl_bitmask(l)
do ispin=1,2
- generators_bitmask(k,ispin,i,m) = ibset(generators_bitmask(k,ispin,i,m),j)
+ generators_bitmask(k,ispin,i) = ibset(generators_bitmask(k,ispin,i),j)
enddo
- enddo
enddo
end
-subroutine set_bitmask_particl_as_input(input_bimask)
+subroutine set_bitmask_particl_as_input(input_bitmask)
implicit none
- integer(bit_kind), intent(in) :: input_bimask(N_int,2)
+ integer(bit_kind), intent(in) :: input_bitmask(N_int,2)
integer :: i,j,k,l,m
integer :: ispin
BEGIN_DOC
! set the generators_bitmask for the particles
-! as the input_bimask
+! as the input_bitmask
END_DOC
- do k=1,N_generators_bitmask
- do l = 1, 3
+ do l = 1, 3
i = index_particl_bitmask(l)
- do ispin=1,2
+ do ispin=1,2
do j = 1, N_int
- generators_bitmask(j,ispin,i,k) = input_bimask(j,ispin)
+ generators_bitmask(j,ispin,i) = input_bitmask(j,ispin)
enddo
enddo
- enddo
enddo
touch generators_bitmask
end
-subroutine set_bitmask_hole_as_input(input_bimask)
+subroutine set_bitmask_hole_as_input(input_bitmask)
implicit none
- integer(bit_kind), intent(in) :: input_bimask(N_int,2)
+ integer(bit_kind), intent(in) :: input_bitmask(N_int,2)
integer :: i,j,k,l,m
integer :: ispin
BEGIN_DOC
! set the generators_bitmask for the holes
-! as the input_bimask
+! as the input_bitmask
END_DOC
- do k=1,N_generators_bitmask
- do l = 1, 3
+ do l = 1, 3
i = index_holes_bitmask(l)
do ispin=1,2
do j = 1, N_int
- generators_bitmask(j,ispin,i,k) = input_bimask(j,ispin)
+ generators_bitmask(j,ispin,i) = input_bitmask(j,ispin)
enddo
enddo
- enddo
enddo
touch generators_bitmask
@@ -173,11 +138,10 @@ subroutine print_generators_bitmasks_holes
allocate(key_tmp(N_int,2))
do l = 1, 3
- k = 1
- i = index_holes_bitmask(l)
+ i = index_holes_bitmask(l)
do j = 1, N_int
- key_tmp(j,1) = generators_bitmask(j,1,i,k)
- key_tmp(j,2) = generators_bitmask(j,2,i,k)
+ key_tmp(j,1) = generators_bitmask(j,1,i)
+ key_tmp(j,2) = generators_bitmask(j,2,i)
enddo
print*,''
print*,'index hole = ',i
@@ -195,57 +159,10 @@ subroutine print_generators_bitmasks_particles
allocate(key_tmp(N_int,2))
do l = 1, 3
- k = 1
- i = index_particl_bitmask(l)
+ i = index_particl_bitmask(l)
do j = 1, N_int
- key_tmp(j,1) = generators_bitmask(j,1,i,k)
- key_tmp(j,2) = generators_bitmask(j,2,i,k)
- enddo
- print*,''
- print*,'index particl ',i
- call print_det(key_tmp,N_int)
- print*,''
- enddo
- deallocate(key_tmp)
-
-end
-
-subroutine print_generators_bitmasks_holes_for_one_generator(i_gen)
- implicit none
- integer, intent(in) :: i_gen
- integer :: i,j,k,l
- integer(bit_kind),allocatable :: key_tmp(:,:)
-
- allocate(key_tmp(N_int,2))
- do l = 1, 3
- k = i_gen
- i = index_holes_bitmask(l)
- do j = 1, N_int
- key_tmp(j,1) = generators_bitmask(j,1,i,k)
- key_tmp(j,2) = generators_bitmask(j,2,i,k)
- enddo
- print*,''
- print*,'index hole = ',i
- call print_det(key_tmp,N_int)
- print*,''
- enddo
- deallocate(key_tmp)
-
-end
-
-subroutine print_generators_bitmasks_particles_for_one_generator(i_gen)
- implicit none
- integer, intent(in) :: i_gen
- integer :: i,j,k,l
- integer(bit_kind),allocatable :: key_tmp(:,:)
-
- allocate(key_tmp(N_int,2))
- do l = 1, 3
- k = i_gen
- i = index_particl_bitmask(l)
- do j = 1, N_int
- key_tmp(j,1) = generators_bitmask(j,1,i,k)
- key_tmp(j,2) = generators_bitmask(j,2,i,k)
+ key_tmp(j,1) = generators_bitmask(j,1,i)
+ key_tmp(j,2) = generators_bitmask(j,2,i)
enddo
print*,''
print*,'index particl ',i
@@ -257,7 +174,7 @@ subroutine print_generators_bitmasks_particles_for_one_generator(i_gen)
end
- BEGIN_PROVIDER [integer, index_holes_bitmask, (3)]
+BEGIN_PROVIDER [integer, index_holes_bitmask, (3)]
implicit none
BEGIN_DOC
! Index of the holes in the generators_bitmasks
diff --git a/src/casscf/50.casscf.bats b/src/casscf/50.casscf.bats
new file mode 100644
index 00000000..a0db725d
--- /dev/null
+++ b/src/casscf/50.casscf.bats
@@ -0,0 +1,49 @@
+#!/usr/bin/env bats
+
+source $QP_ROOT/tests/bats/common.bats.sh
+source $QP_ROOT/quantum_package.rc
+
+
+function run_stoch() {
+ thresh=$2
+ test_exe casscf || skip
+ qp set perturbation do_pt2 True
+ qp set determinants n_det_max $3
+ qp set davidson threshold_davidson 1.e-10
+ qp set davidson n_states_diag 4
+ qp run casscf | tee casscf.out
+ energy1="$(ezfio get casscf energy_pt2 | tr '[]' ' ' | cut -d ',' -f 1)"
+ eq $energy1 $1 $thresh
+}
+
+@test "F2" { # 18.0198s
+ rm -rf f2_casscf
+ qp_create_ezfio -b aug-cc-pvdz ../input/f2.zmt -o f2_casscf
+ qp set_file f2_casscf
+ qp run scf
+ qp set_mo_class --core="[1-6,8-9]" --act="[7,10]" --virt="[11-46]"
+ run_stoch -198.773366970 1.e-4 100000
+}
+
+@test "N2" { # 18.0198s
+ rm -rf n2_casscf
+ qp_create_ezfio -b aug-cc-pvdz ../input/n2.xyz -o n2_casscf
+ qp set_file n2_casscf
+ qp run scf
+ qp set_mo_class --core="[1-4]" --act="[5-10]" --virt="[11-46]"
+ run_stoch -109.0961643162 1.e-4 100000
+}
+
+@test "N2_stretched" {
+ rm -rf n2_stretched_casscf
+ qp_create_ezfio -b aug-cc-pvdz -m 7 ../input/n2_stretched.xyz -o n2_stretched_casscf
+ qp set_file n2_stretched_casscf
+ qp run scf | tee scf.out
+ qp set_mo_class --core="[1-4]" --act="[5-10]" --virt="[11-46]"
+ qp set electrons elec_alpha_num 7
+ qp set electrons elec_beta_num 7
+ run_stoch -108.7860471300 1.e-4 100000
+#
+
+}
+
diff --git a/src/casscf/EZFIO.cfg b/src/casscf/EZFIO.cfg
new file mode 100644
index 00000000..4e4d3d3a
--- /dev/null
+++ b/src/casscf/EZFIO.cfg
@@ -0,0 +1,31 @@
+[energy]
+type: double precision
+doc: Calculated Selected |FCI| energy
+interface: ezfio
+size: (determinants.n_states)
+
+[energy_pt2]
+type: double precision
+doc: Calculated |FCI| energy + |PT2|
+interface: ezfio
+size: (determinants.n_states)
+
+[cisd_guess]
+type: logical
+doc: If true, the CASSCF starts with a CISD wave function
+interface: ezfio,provider,ocaml
+default: True
+
+[state_following_casscf]
+type: logical
+doc: If |true|, the CASSCF will try to follow the guess CI vector and orbitals
+interface: ezfio,provider,ocaml
+default: False
+
+
+[level_shift_casscf]
+type: Positive_float
+doc: Energy shift on the virtual MOs to improve SCF convergence
+interface: ezfio,provider,ocaml
+default: 0.005
+
diff --git a/src/casscf/MORALITY b/src/casscf/MORALITY
new file mode 100644
index 00000000..9701a647
--- /dev/null
+++ b/src/casscf/MORALITY
@@ -0,0 +1 @@
+the CASCF can be obtained if a proper guess is given to the WF part
diff --git a/src/casscf/NEED b/src/casscf/NEED
new file mode 100644
index 00000000..d9da718e
--- /dev/null
+++ b/src/casscf/NEED
@@ -0,0 +1,4 @@
+cipsi
+selectors_full
+generators_cas
+two_body_rdm
diff --git a/src/casscf/README.rst b/src/casscf/README.rst
new file mode 100644
index 00000000..08bfd95b
--- /dev/null
+++ b/src/casscf/README.rst
@@ -0,0 +1,5 @@
+======
+casscf
+======
+
+|CASSCF| program with the CIPSI algorithm.
diff --git a/src/casscf/bavard.irp.f b/src/casscf/bavard.irp.f
new file mode 100644
index 00000000..463c3ea4
--- /dev/null
+++ b/src/casscf/bavard.irp.f
@@ -0,0 +1,6 @@
+! -*- F90 -*-
+BEGIN_PROVIDER [logical, bavard]
+! bavard=.true.
+ bavard=.false.
+END_PROVIDER
+
diff --git a/src/casscf/bielec.irp.f b/src/casscf/bielec.irp.f
new file mode 100644
index 00000000..0a44f994
--- /dev/null
+++ b/src/casscf/bielec.irp.f
@@ -0,0 +1,155 @@
+BEGIN_PROVIDER [real*8, bielec_PQxx, (mo_num, mo_num,n_core_inact_act_orb,n_core_inact_act_orb)]
+ BEGIN_DOC
+ ! bielec_PQxx : integral (pq|xx) with p,q arbitrary, x core or active
+ ! indices are unshifted orbital numbers
+ END_DOC
+ implicit none
+ integer :: i,j,ii,jj,p,q,i3,j3,t3,v3
+ real*8 :: mo_two_e_integral
+
+ bielec_PQxx(:,:,:,:) = 0.d0
+ PROVIDE mo_two_e_integrals_in_map
+
+ !$OMP PARALLEL DEFAULT(NONE) &
+ !$OMP PRIVATE(i,ii,j,jj,i3,j3) &
+ !$OMP SHARED(n_core_inact_orb,list_core_inact,mo_num,bielec_PQxx, &
+ !$OMP n_act_orb,mo_integrals_map,list_act)
+
+ !$OMP DO
+ do i=1,n_core_inact_orb
+ ii=list_core_inact(i)
+ do j=i,n_core_inact_orb
+ jj=list_core_inact(j)
+ call get_mo_two_e_integrals_i1j1(ii,jj,mo_num,bielec_PQxx(1,1,i,j),mo_integrals_map)
+ bielec_PQxx(:,:,j,i)=bielec_PQxx(:,:,i,j)
+ end do
+ do j=1,n_act_orb
+ jj=list_act(j)
+ j3=j+n_core_inact_orb
+ call get_mo_two_e_integrals_i1j1(ii,jj,mo_num,bielec_PQxx(1,1,i,j3),mo_integrals_map)
+ bielec_PQxx(:,:,j3,i)=bielec_PQxx(:,:,i,j3)
+ end do
+ end do
+ !$OMP END DO
+
+
+ !$OMP DO
+ do i=1,n_act_orb
+ ii=list_act(i)
+ i3=i+n_core_inact_orb
+ do j=i,n_act_orb
+ jj=list_act(j)
+ j3=j+n_core_inact_orb
+ call get_mo_two_e_integrals_i1j1(ii,jj,mo_num,bielec_PQxx(1,1,i3,j3),mo_integrals_map)
+ bielec_PQxx(:,:,j3,i3)=bielec_PQxx(:,:,i3,j3)
+ end do
+ end do
+ !$OMP END DO
+
+ !$OMP END PARALLEL
+
+END_PROVIDER
+
+
+
+BEGIN_PROVIDER [real*8, bielec_PxxQ, (mo_num,n_core_inact_act_orb,n_core_inact_act_orb, mo_num)]
+ BEGIN_DOC
+ ! bielec_PxxQ : integral (px|xq) with p,q arbitrary, x core or active
+ ! indices are unshifted orbital numbers
+ END_DOC
+ implicit none
+ integer :: i,j,ii,jj,p,q,i3,j3,t3,v3
+ double precision, allocatable :: integrals_array(:,:)
+ real*8 :: mo_two_e_integral
+
+ PROVIDE mo_two_e_integrals_in_map
+ bielec_PxxQ = 0.d0
+
+ !$OMP PARALLEL DEFAULT(NONE) &
+ !$OMP PRIVATE(i,ii,j,jj,i3,j3,integrals_array) &
+ !$OMP SHARED(n_core_inact_orb,list_core_inact,mo_num,bielec_PxxQ, &
+ !$OMP n_act_orb,mo_integrals_map,list_act)
+
+ allocate(integrals_array(mo_num,mo_num))
+
+ !$OMP DO
+ do i=1,n_core_inact_orb
+ ii=list_core_inact(i)
+ do j=i,n_core_inact_orb
+ jj=list_core_inact(j)
+ call get_mo_two_e_integrals_ij(ii,jj,mo_num,integrals_array,mo_integrals_map)
+ do q=1,mo_num
+ do p=1,mo_num
+ bielec_PxxQ(p,i,j,q)=integrals_array(p,q)
+ bielec_PxxQ(p,j,i,q)=integrals_array(q,p)
+ end do
+ end do
+ end do
+ do j=1,n_act_orb
+ jj=list_act(j)
+ j3=j+n_core_inact_orb
+ call get_mo_two_e_integrals_ij(ii,jj,mo_num,integrals_array,mo_integrals_map)
+ do q=1,mo_num
+ do p=1,mo_num
+ bielec_PxxQ(p,i,j3,q)=integrals_array(p,q)
+ bielec_PxxQ(p,j3,i,q)=integrals_array(q,p)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO
+
+
+ ! (ip|qj)
+ !$OMP DO
+ do i=1,n_act_orb
+ ii=list_act(i)
+ i3=i+n_core_inact_orb
+ do j=i,n_act_orb
+ jj=list_act(j)
+ j3=j+n_core_inact_orb
+ call get_mo_two_e_integrals_ij(ii,jj,mo_num,integrals_array,mo_integrals_map)
+ do q=1,mo_num
+ do p=1,mo_num
+ bielec_PxxQ(p,i3,j3,q)=integrals_array(p,q)
+ bielec_PxxQ(p,j3,i3,q)=integrals_array(q,p)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO
+
+ deallocate(integrals_array)
+ !$OMP END PARALLEL
+
+END_PROVIDER
+
+
+BEGIN_PROVIDER [real*8, bielecCI, (n_act_orb,n_act_orb,n_act_orb, mo_num)]
+ BEGIN_DOC
+ ! bielecCI : integrals (tu|vp) with p arbitrary, tuv active
+ ! index p runs over the whole basis, t,u,v only over the active orbitals
+ END_DOC
+ implicit none
+ integer :: i,j,k,p,t,u,v
+ double precision, external :: mo_two_e_integral
+ PROVIDE mo_two_e_integrals_in_map
+
+ !$OMP PARALLEL DO DEFAULT(NONE) &
+ !$OMP PRIVATE(i,j,k,p,t,u,v) &
+ !$OMP SHARED(mo_num,n_act_orb,list_act,bielecCI)
+ do p=1,mo_num
+ do j=1,n_act_orb
+ u=list_act(j)
+ do k=1,n_act_orb
+ v=list_act(k)
+ do i=1,n_act_orb
+ t=list_act(i)
+ bielecCI(i,k,j,p) = mo_two_e_integral(t,u,v,p)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+
+END_PROVIDER
diff --git a/src/casscf/bielec_natorb.irp.f b/src/casscf/bielec_natorb.irp.f
new file mode 100644
index 00000000..9968530c
--- /dev/null
+++ b/src/casscf/bielec_natorb.irp.f
@@ -0,0 +1,369 @@
+ BEGIN_PROVIDER [real*8, bielec_PQxx_no, (mo_num, mo_num,n_core_inact_act_orb,n_core_inact_act_orb)]
+ BEGIN_DOC
+ ! integral (pq|xx) in the basis of natural MOs
+ ! indices are unshifted orbital numbers
+ END_DOC
+ implicit none
+ integer :: i,j,k,l,t,u,p,q
+ double precision, allocatable :: f(:,:,:), d(:,:,:)
+
+
+
+ !$OMP PARALLEL DEFAULT(NONE) &
+ !$OMP PRIVATE(j,k,l,p,d,f) &
+ !$OMP SHARED(n_core_inact_act_orb,mo_num,n_act_orb,n_core_inact_orb, &
+ !$OMP bielec_PQxx_no,bielec_PQxx,list_act,natorbsCI)
+
+ allocate (f(n_act_orb,mo_num,n_core_inact_act_orb), &
+ d(n_act_orb,mo_num,n_core_inact_act_orb))
+
+ !$OMP DO
+ do l=1,n_core_inact_act_orb
+ bielec_PQxx_no(:,:,:,l) = bielec_PQxx(:,:,:,l)
+
+ do k=1,n_core_inact_act_orb
+ do j=1,mo_num
+ do p=1,n_act_orb
+ f(p,j,k)=bielec_PQxx_no(list_act(p),j,k,l)
+ end do
+ end do
+ end do
+ call dgemm('T','N',n_act_orb,mo_num*n_core_inact_act_orb,n_act_orb,1.d0, &
+ natorbsCI, size(natorbsCI,1), &
+ f, n_act_orb, &
+ 0.d0, &
+ d, n_act_orb)
+ do k=1,n_core_inact_act_orb
+ do j=1,mo_num
+ do p=1,n_act_orb
+ bielec_PQxx_no(list_act(p),j,k,l)=d(p,j,k)
+ end do
+ end do
+
+ do j=1,mo_num
+ do p=1,n_act_orb
+ f(p,j,k)=bielec_PQxx_no(j,list_act(p),k,l)
+ end do
+ end do
+ end do
+ call dgemm('T','N',n_act_orb,mo_num*n_core_inact_act_orb,n_act_orb,1.d0, &
+ natorbsCI, n_act_orb, &
+ f, n_act_orb, &
+ 0.d0, &
+ d, n_act_orb)
+ do k=1,n_core_inact_act_orb
+ do p=1,n_act_orb
+ do j=1,mo_num
+ bielec_PQxx_no(j,list_act(p),k,l)=d(p,j,k)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO NOWAIT
+
+ deallocate (f,d)
+
+ allocate (f(mo_num,mo_num,n_act_orb),d(mo_num,mo_num,n_act_orb))
+
+ !$OMP DO
+ do l=1,n_core_inact_act_orb
+
+ do p=1,n_act_orb
+ do k=1,mo_num
+ do j=1,mo_num
+ f(j,k,p) = bielec_PQxx_no(j,k,n_core_inact_orb+p,l)
+ end do
+ end do
+ end do
+ call dgemm('N','N',mo_num*mo_num,n_act_orb,n_act_orb,1.d0, &
+ f, mo_num*mo_num, &
+ natorbsCI, n_act_orb, &
+ 0.d0, &
+ d, mo_num*mo_num)
+ do p=1,n_act_orb
+ do k=1,mo_num
+ do j=1,mo_num
+ bielec_PQxx_no(j,k,n_core_inact_orb+p,l)=d(j,k,p)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO NOWAIT
+
+ !$OMP BARRIER
+
+ !$OMP DO
+ do l=1,n_core_inact_act_orb
+ do p=1,n_act_orb
+ do k=1,mo_num
+ do j=1,mo_num
+ f(j,k,p) = bielec_PQxx_no(j,k,l,n_core_inact_orb+p)
+ end do
+ end do
+ end do
+ call dgemm('N','N',mo_num*mo_num,n_act_orb,n_act_orb,1.d0, &
+ f, mo_num*mo_num, &
+ natorbsCI, n_act_orb, &
+ 0.d0, &
+ d, mo_num*mo_num)
+ do p=1,n_act_orb
+ do k=1,mo_num
+ do j=1,mo_num
+ bielec_PQxx_no(j,k,l,n_core_inact_orb+p)=d(j,k,p)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO
+
+ deallocate (f,d)
+ !$OMP END PARALLEL
+
+END_PROVIDER
+
+
+
+BEGIN_PROVIDER [real*8, bielec_PxxQ_no, (mo_num,n_core_inact_act_orb,n_core_inact_act_orb, mo_num)]
+ BEGIN_DOC
+ ! integral (px|xq) in the basis of natural MOs
+ ! indices are unshifted orbital numbers
+ END_DOC
+ implicit none
+ integer :: i,j,k,l,t,u,p,q
+ double precision, allocatable :: f(:,:,:), d(:,:,:)
+
+ !$OMP PARALLEL DEFAULT(NONE) &
+ !$OMP PRIVATE(j,k,l,p,d,f) &
+ !$OMP SHARED(n_core_inact_act_orb,mo_num,n_act_orb,n_core_inact_orb, &
+ !$OMP bielec_PxxQ_no,bielec_PxxQ,list_act,natorbsCI)
+
+
+ allocate (f(n_act_orb,n_core_inact_act_orb,n_core_inact_act_orb), &
+ d(n_act_orb,n_core_inact_act_orb,n_core_inact_act_orb))
+
+ !$OMP DO
+ do j=1,mo_num
+ bielec_PxxQ_no(:,:,:,j) = bielec_PxxQ(:,:,:,j)
+ do l=1,n_core_inact_act_orb
+ do k=1,n_core_inact_act_orb
+ do p=1,n_act_orb
+ f(p,k,l) = bielec_PxxQ_no(list_act(p),k,l,j)
+ end do
+ end do
+ end do
+ call dgemm('T','N',n_act_orb,n_core_inact_act_orb**2,n_act_orb,1.d0, &
+ natorbsCI, size(natorbsCI,1), &
+ f, n_act_orb, &
+ 0.d0, &
+ d, n_act_orb)
+ do l=1,n_core_inact_act_orb
+ do k=1,n_core_inact_act_orb
+ do p=1,n_act_orb
+ bielec_PxxQ_no(list_act(p),k,l,j)=d(p,k,l)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO NOWAIT
+
+ deallocate (f,d)
+
+ allocate (f(n_act_orb,mo_num,n_core_inact_act_orb), &
+ d(n_act_orb,mo_num,n_core_inact_act_orb))
+
+ !$OMP DO
+ do k=1,mo_num
+ do l=1,n_core_inact_act_orb
+ do j=1,mo_num
+ do p=1,n_act_orb
+ f(p,j,l) = bielec_PxxQ_no(j,n_core_inact_orb+p,l,k)
+ end do
+ end do
+ end do
+ call dgemm('T','N',n_act_orb,mo_num*n_core_inact_act_orb,n_act_orb,1.d0, &
+ natorbsCI, size(natorbsCI,1), &
+ f, n_act_orb, &
+ 0.d0, &
+ d, n_act_orb)
+ do l=1,n_core_inact_act_orb
+ do j=1,mo_num
+ do p=1,n_act_orb
+ bielec_PxxQ_no(j,n_core_inact_orb+p,l,k)=d(p,j,l)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO NOWAIT
+
+ deallocate(f,d)
+
+ allocate(f(mo_num,n_core_inact_act_orb,n_act_orb), &
+ d(mo_num,n_core_inact_act_orb,n_act_orb) )
+
+ !$OMP DO
+ do k=1,mo_num
+ do p=1,n_act_orb
+ do l=1,n_core_inact_act_orb
+ do j=1,mo_num
+ f(j,l,p) = bielec_PxxQ_no(j,l,n_core_inact_orb+p,k)
+ end do
+ end do
+ end do
+ call dgemm('N','N',mo_num*n_core_inact_act_orb,n_act_orb,n_act_orb,1.d0, &
+ f, mo_num*n_core_inact_act_orb, &
+ natorbsCI, size(natorbsCI,1), &
+ 0.d0, &
+ d, mo_num*n_core_inact_act_orb)
+ do p=1,n_act_orb
+ do l=1,n_core_inact_act_orb
+ do j=1,mo_num
+ bielec_PxxQ_no(j,l,n_core_inact_orb+p,k)=d(j,l,p)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO NOWAIT
+
+ !$OMP BARRIER
+
+ !$OMP DO
+ do l=1,n_core_inact_act_orb
+ do p=1,n_act_orb
+ do k=1,n_core_inact_act_orb
+ do j=1,mo_num
+ f(j,k,p) = bielec_PxxQ_no(j,k,l,n_core_inact_orb+p)
+ end do
+ end do
+ end do
+ call dgemm('N','N',mo_num*n_core_inact_act_orb,n_act_orb,n_act_orb,1.d0, &
+ f, mo_num*n_core_inact_act_orb, &
+ natorbsCI, size(natorbsCI,1), &
+ 0.d0, &
+ d, mo_num*n_core_inact_act_orb)
+ do p=1,n_act_orb
+ do k=1,n_core_inact_act_orb
+ do j=1,mo_num
+ bielec_PxxQ_no(j,k,l,n_core_inact_orb+p)=d(j,k,p)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO NOWAIT
+ deallocate(f,d)
+ !$OMP END PARALLEL
+
+END_PROVIDER
+
+
+BEGIN_PROVIDER [real*8, bielecCI_no, (n_act_orb,n_act_orb,n_act_orb, mo_num)]
+ BEGIN_DOC
+ ! integrals (tu|vp) in the basis of natural MOs
+ ! index p runs over the whole basis, t,u,v only over the active orbitals
+ END_DOC
+ implicit none
+ integer :: i,j,k,l,t,u,p,q
+ double precision, allocatable :: f(:,:,:), d(:,:,:)
+
+ !$OMP PARALLEL DEFAULT(NONE) &
+ !$OMP PRIVATE(j,k,l,p,d,f) &
+ !$OMP SHARED(n_core_inact_act_orb,mo_num,n_act_orb,n_core_inact_orb, &
+ !$OMP bielecCI_no,bielecCI,list_act,natorbsCI)
+
+ allocate (f(n_act_orb,n_act_orb,mo_num), &
+ d(n_act_orb,n_act_orb,mo_num))
+
+ !$OMP DO
+ do l=1,mo_num
+ bielecCI_no(:,:,:,l) = bielecCI(:,:,:,l)
+ do k=1,n_act_orb
+ do j=1,n_act_orb
+ do p=1,n_act_orb
+ f(p,j,k)=bielecCI_no(p,j,k,l)
+ end do
+ end do
+ end do
+ call dgemm('T','N',n_act_orb,n_act_orb*n_act_orb,n_act_orb,1.d0, &
+ natorbsCI, size(natorbsCI,1), &
+ f, n_act_orb, &
+ 0.d0, &
+ d, n_act_orb)
+ do k=1,n_act_orb
+ do j=1,n_act_orb
+ do p=1,n_act_orb
+ bielecCI_no(p,j,k,l)=d(p,j,k)
+ end do
+ end do
+
+ do j=1,n_act_orb
+ do p=1,n_act_orb
+ f(p,j,k)=bielecCI_no(j,p,k,l)
+ end do
+ end do
+ end do
+ call dgemm('T','N',n_act_orb,n_act_orb*n_act_orb,n_act_orb,1.d0, &
+ natorbsCI, n_act_orb, &
+ f, n_act_orb, &
+ 0.d0, &
+ d, n_act_orb)
+ do k=1,n_act_orb
+ do p=1,n_act_orb
+ do j=1,n_act_orb
+ bielecCI_no(j,p,k,l)=d(p,j,k)
+ end do
+ end do
+ end do
+
+ do p=1,n_act_orb
+ do k=1,n_act_orb
+ do j=1,n_act_orb
+ f(j,k,p)=bielecCI_no(j,k,p,l)
+ end do
+ end do
+ end do
+ call dgemm('N','N',n_act_orb*n_act_orb,n_act_orb,n_act_orb,1.d0, &
+ f, n_act_orb*n_act_orb, &
+ natorbsCI, n_act_orb, &
+ 0.d0, &
+ d, n_act_orb*n_act_orb)
+
+ do p=1,n_act_orb
+ do k=1,n_act_orb
+ do j=1,n_act_orb
+ bielecCI_no(j,k,p,l)=d(j,k,p)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO
+
+ !$OMP DO
+ do l=1,n_act_orb
+ do p=1,n_act_orb
+ do k=1,n_act_orb
+ do j=1,n_act_orb
+ f(j,k,p)=bielecCI_no(j,k,l,list_act(p))
+ end do
+ end do
+ end do
+ call dgemm('N','N',n_act_orb*n_act_orb,n_act_orb,n_act_orb,1.d0, &
+ f, n_act_orb*n_act_orb, &
+ natorbsCI, n_act_orb, &
+ 0.d0, &
+ d, n_act_orb*n_act_orb)
+
+ do p=1,n_act_orb
+ do k=1,n_act_orb
+ do j=1,n_act_orb
+ bielecCI_no(j,k,l,list_act(p))=d(j,k,p)
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO
+
+ deallocate(d,f)
+ !$OMP END PARALLEL
+
+
+END_PROVIDER
+
diff --git a/src/casscf/casscf.irp.f b/src/casscf/casscf.irp.f
new file mode 100644
index 00000000..d83aa271
--- /dev/null
+++ b/src/casscf/casscf.irp.f
@@ -0,0 +1,57 @@
+program casscf
+ implicit none
+ BEGIN_DOC
+! TODO : Put the documentation of the program here
+ END_DOC
+ call reorder_orbitals_for_casscf
+ no_vvvv_integrals = .True.
+ pt2_max = 0.02
+ SOFT_TOUCH no_vvvv_integrals pt2_max
+ call run_stochastic_cipsi
+ call run
+end
+
+subroutine run
+ implicit none
+ double precision :: energy_old, energy
+ logical :: converged,state_following_casscf_save
+ integer :: iteration
+ converged = .False.
+
+ energy = 0.d0
+ mo_label = "MCSCF"
+ iteration = 1
+ state_following_casscf_save = state_following_casscf
+ state_following_casscf = .True.
+ touch state_following_casscf
+ do while (.not.converged)
+ call run_stochastic_cipsi
+ energy_old = energy
+ energy = eone+etwo+ecore
+
+ call write_time(6)
+ call write_int(6,iteration,'CAS-SCF iteration')
+ call write_double(6,energy,'CAS-SCF energy')
+ call write_double(6,energy_improvement, 'Predicted energy improvement')
+
+ converged = dabs(energy_improvement) < thresh_scf
+ pt2_max = dabs(energy_improvement / pt2_relative_error)
+
+ mo_coef = NewOrbs
+ mo_occ = occnum
+ call save_mos
+ iteration += 1
+ N_det = max(N_det/2 ,N_states)
+ psi_det = psi_det_sorted
+ psi_coef = psi_coef_sorted
+ read_wf = .True.
+ call clear_mo_map
+ SOFT_TOUCH mo_coef N_det pt2_max psi_det psi_coef
+ if(iteration .gt. 3)then
+ state_following_casscf = state_following_casscf_save
+ touch state_following_casscf
+ endif
+
+ enddo
+
+end
diff --git a/src/casscf/class.irp.f b/src/casscf/class.irp.f
new file mode 100644
index 00000000..7360a661
--- /dev/null
+++ b/src/casscf/class.irp.f
@@ -0,0 +1,12 @@
+ BEGIN_PROVIDER [ logical, do_only_1h1p ]
+&BEGIN_PROVIDER [ logical, do_only_cas ]
+&BEGIN_PROVIDER [ logical, do_ddci ]
+ implicit none
+ BEGIN_DOC
+ ! In the CAS case, all those are always false except do_only_cas
+ END_DOC
+ do_only_cas = .True.
+ do_only_1h1p = .False.
+ do_ddci = .False.
+END_PROVIDER
+
diff --git a/src/casscf/densities.irp.f b/src/casscf/densities.irp.f
new file mode 100644
index 00000000..3d1ff0f9
--- /dev/null
+++ b/src/casscf/densities.irp.f
@@ -0,0 +1,67 @@
+use bitmasks
+
+BEGIN_PROVIDER [real*8, D0tu, (n_act_orb,n_act_orb) ]
+ implicit none
+ BEGIN_DOC
+ ! the first-order density matrix in the basis of the starting MOs.
+ ! matrix is state averaged.
+ END_DOC
+ integer :: t,u
+
+ do u=1,n_act_orb
+ do t=1,n_act_orb
+ D0tu(t,u) = one_e_dm_mo_alpha_average( list_act(t), list_act(u) ) + &
+ one_e_dm_mo_beta_average ( list_act(t), list_act(u) )
+ enddo
+ enddo
+
+END_PROVIDER
+
+BEGIN_PROVIDER [real*8, P0tuvx, (n_act_orb,n_act_orb,n_act_orb,n_act_orb) ]
+ BEGIN_DOC
+ ! The second-order density matrix in the basis of the starting MOs ONLY IN THE RANGE OF ACTIVE MOS
+ ! The values are state averaged
+ !
+ ! We use the spin-free generators of mono-excitations
+ ! E_pq destroys q and creates p
+ ! D_pq = <0|E_pq|0> = D_qp
+ ! P_pqrs = 1/2 <0|E_pq E_rs - delta_qr E_ps|0>
+ !
+ ! P0tuvx(p,q,r,s) = chemist notation : 1/2 <0|E_pq E_rs - delta_qr E_ps|0>
+ END_DOC
+ implicit none
+ integer :: t,u,v,x
+ integer :: tt,uu,vv,xx
+ integer :: mu,nu,istate,ispin,jspin,ihole,ipart,jhole,jpart
+ integer :: ierr
+ real*8 :: phase1,phase11,phase12,phase2,phase21,phase22
+ integer :: nu1,nu2,nu11,nu12,nu21,nu22
+ integer :: ierr1,ierr2,ierr11,ierr12,ierr21,ierr22
+ real*8 :: cI_mu(N_states),term
+ integer(bit_kind), dimension(N_int,2) :: det_mu, det_mu_ex
+ integer(bit_kind), dimension(N_int,2) :: det_mu_ex1, det_mu_ex11, det_mu_ex12
+ integer(bit_kind), dimension(N_int,2) :: det_mu_ex2, det_mu_ex21, det_mu_ex22
+
+ if (bavard) then
+ write(6,*) ' providing the 2 body RDM on the active part'
+ endif
+
+ P0tuvx= 0.d0
+ do istate=1,N_states
+ do x = 1, n_act_orb
+ xx = list_act(x)
+ do v = 1, n_act_orb
+ vv = list_act(v)
+ do u = 1, n_act_orb
+ uu = list_act(u)
+ do t = 1, n_act_orb
+ tt = list_act(t)
+ P0tuvx(t,u,v,x) = state_av_act_two_rdm_spin_trace_mo(t,v,u,x)
+! P0tuvx(t,u,v,x) = act_two_rdm_spin_trace_mo(t,v,u,x)
+ enddo
+ enddo
+ enddo
+ enddo
+ enddo
+
+END_PROVIDER
diff --git a/src/casscf/det_manip.irp.f b/src/casscf/det_manip.irp.f
new file mode 100644
index 00000000..d8c309a4
--- /dev/null
+++ b/src/casscf/det_manip.irp.f
@@ -0,0 +1,125 @@
+use bitmasks
+
+subroutine do_signed_mono_excitation(key1,key2,nu,ihole,ipart, &
+ ispin,phase,ierr)
+ BEGIN_DOC
+ ! we create the mono-excitation, and determine, if possible,
+ ! the phase and the number in the list of determinants
+ END_DOC
+ implicit none
+ integer(bit_kind) :: key1(N_int,2),key2(N_int,2)
+ integer(bit_kind), allocatable :: keytmp(:,:)
+ integer :: exc(0:2,2,2),ihole,ipart,ierr,nu,ispin
+ real*8 :: phase
+ logical :: found
+ allocate(keytmp(N_int,2))
+
+ nu=-1
+ phase=1.D0
+ ierr=0
+ call det_copy(key1,key2,N_int)
+ ! write(6,*) ' key2 before excitation ',ihole,' -> ',ipart,' spin = ',ispin
+ ! call print_det(key2,N_int)
+ call do_single_excitation(key2,ihole,ipart,ispin,ierr)
+ ! write(6,*) ' key2 after ',ihole,' -> ',ipart,' spin = ',ispin
+ ! call print_det(key2,N_int)
+ ! write(6,*) ' excitation ',ihole,' -> ',ipart,' gives ierr = ',ierr
+ if (ierr.eq.1) then
+ ! excitation is possible
+ ! get the phase
+ call get_single_excitation(key1,key2,exc,phase,N_int)
+ ! get the number in the list
+ found=.false.
+ nu=0
+
+ !TODO BOTTLENECK
+ do while (.not.found)
+ nu+=1
+ if (nu.gt.N_det) then
+ ! the determinant is possible, but not in the list
+ found=.true.
+ nu=-1
+ else
+ call det_extract(keytmp,nu,N_int)
+ integer :: i,ii
+ found=.true.
+ do ii=1,2
+ do i=1,N_int
+ if (keytmp(i,ii).ne.key2(i,ii)) then
+ found=.false.
+ end if
+ end do
+ end do
+ end if
+ end do
+ end if
+ !
+ ! we found the new string, the phase, and possibly the number in the list
+ !
+end subroutine do_signed_mono_excitation
+
+subroutine det_extract(key,nu,Nint)
+ BEGIN_DOC
+ ! extract a determinant from the list of determinants
+ END_DOC
+ implicit none
+ integer :: ispin,i,nu,Nint
+ integer(bit_kind) :: key(Nint,2)
+ do ispin=1,2
+ do i=1,Nint
+ key(i,ispin)=psi_det(i,ispin,nu)
+ end do
+ end do
+end subroutine det_extract
+
+subroutine det_copy(key1,key2,Nint)
+ use bitmasks ! you need to include the bitmasks_module.f90 features
+ BEGIN_DOC
+ ! copy a determinant from key1 to key2
+ END_DOC
+ implicit none
+ integer :: ispin,i,Nint
+ integer(bit_kind) :: key1(Nint,2),key2(Nint,2)
+ do ispin=1,2
+ do i=1,Nint
+ key2(i,ispin)=key1(i,ispin)
+ end do
+ end do
+end subroutine det_copy
+
+subroutine do_spinfree_mono_excitation(key_in,key_out1,key_out2 &
+ ,nu1,nu2,ihole,ipart,phase1,phase2,ierr,jerr)
+ BEGIN_DOC
+ ! we create the spin-free mono-excitation E_pq=(a^+_p a_q + a^+_P a_Q)
+ ! we may create two determinants as result
+ !
+ END_DOC
+ implicit none
+ integer(bit_kind) :: key_in(N_int,2),key_out1(N_int,2)
+ integer(bit_kind) :: key_out2(N_int,2)
+ integer :: ihole,ipart,ierr,jerr,nu1,nu2
+ integer :: ispin
+ real*8 :: phase1,phase2
+
+ ! write(6,*) ' applying E_',ipart,ihole,' on determinant '
+ ! call print_det(key_in,N_int)
+
+ ! spin alpha
+ ispin=1
+ call do_signed_mono_excitation(key_in,key_out1,nu1,ihole &
+ ,ipart,ispin,phase1,ierr)
+ ! if (ierr.eq.1) then
+ ! write(6,*) ' 1 result is ',nu1,phase1
+ ! call print_det(key_out1,N_int)
+ ! end if
+ ! spin beta
+ ispin=2
+ call do_signed_mono_excitation(key_in,key_out2,nu2,ihole &
+ ,ipart,ispin,phase2,jerr)
+ ! if (jerr.eq.1) then
+ ! write(6,*) ' 2 result is ',nu2,phase2
+ ! call print_det(key_out2,N_int)
+ ! end if
+
+end subroutine do_spinfree_mono_excitation
+
diff --git a/src/casscf/driver_optorb.irp.f b/src/casscf/driver_optorb.irp.f
new file mode 100644
index 00000000..2e3e02dc
--- /dev/null
+++ b/src/casscf/driver_optorb.irp.f
@@ -0,0 +1,3 @@
+subroutine driver_optorb
+ implicit none
+end
diff --git a/src/casscf/get_energy.irp.f b/src/casscf/get_energy.irp.f
new file mode 100644
index 00000000..362da85d
--- /dev/null
+++ b/src/casscf/get_energy.irp.f
@@ -0,0 +1,104 @@
+program print_2rdm
+ implicit none
+ BEGIN_DOC
+ ! get the active part of the bielectronic energy on a given wave function.
+ !
+ ! useful to test the active part of the spin trace 2 rdms
+ END_DOC
+!no_vvvv_integrals = .True.
+ read_wf = .True.
+!touch read_wf no_vvvv_integrals
+!call routine
+!call routine_bis
+ call print_grad
+end
+
+subroutine print_grad
+ implicit none
+ integer :: i
+ do i = 1, nMonoEx
+ if(dabs(gradvec2(i)).gt.1.d-5)then
+ print*,''
+ print*,i,gradvec2(i),excit(:,i)
+ endif
+ enddo
+end
+
+subroutine routine_bis
+ implicit none
+ integer :: i,j
+ double precision :: accu_d,accu_od
+!accu_d = 0.d0
+!accu_od = 0.d0
+!print*,''
+!print*,''
+!print*,''
+!do i = 1, mo_num
+! write(*,'(100(F8.5,X))')super_ci_dm(i,:)
+! accu_d += super_ci_dm(i,i)
+! do j = i+1, mo_num
+! accu_od += dabs(super_ci_dm(i,j) - super_ci_dm(j,i))
+! enddo
+!enddo
+!print*,''
+!print*,''
+!print*,'accu_d = ',accu_d
+!print*,'n_elec = ',elec_num
+!print*,'accu_od= ',accu_od
+!print*,''
+!accu_d = 0.d0
+!do i = 1, N_det
+! accu_d += psi_coef(i,1)**2
+!enddo
+!print*,'accu_d = ',accu_d
+!provide superci_natorb
+
+ provide switch_mo_coef
+ mo_coef = switch_mo_coef
+ call save_mos
+end
+
+subroutine routine
+ integer :: i,j,k,l
+ integer :: ii,jj,kk,ll
+ double precision :: accu(4),twodm,thr,act_twodm2,integral,get_two_e_integral
+ thr = 1.d-10
+
+
+ accu = 0.d0
+ do ll = 1, n_act_orb
+ l = list_act(ll)
+ do kk = 1, n_act_orb
+ k = list_act(kk)
+ do jj = 1, n_act_orb
+ j = list_act(jj)
+ do ii = 1, n_act_orb
+ i = list_act(ii)
+ integral = get_two_e_integral(i,j,k,l,mo_integrals_map)
+ accu(1) += state_av_act_two_rdm_spin_trace_mo(ii,jj,kk,ll) * integral
+ enddo
+ enddo
+ enddo
+ enddo
+ print*,'accu = ',accu(1)
+
+ accu = 0.d0
+ do ll = 1, n_act_orb
+ l = list_act(ll)
+ do kk = 1, n_act_orb
+ k = list_act(kk)
+ do jj = 1, n_act_orb
+ j = list_act(jj)
+ do ii = 1, n_act_orb
+ i = list_act(ii)
+ integral = get_two_e_integral(i,j,k,l,mo_integrals_map)
+ accu(1) += state_av_act_two_rdm_openmp_spin_trace_mo(ii,jj,kk,ll) * integral
+ enddo
+ enddo
+ enddo
+ enddo
+ print*,'accu = ',accu(1)
+ print*,'psi_energy_two_e = ',psi_energy_two_e
+
+ print *, psi_energy_with_nucl_rep
+end
diff --git a/src/casscf/grad_old.irp.f b/src/casscf/grad_old.irp.f
new file mode 100644
index 00000000..d60a60c8
--- /dev/null
+++ b/src/casscf/grad_old.irp.f
@@ -0,0 +1,74 @@
+
+BEGIN_PROVIDER [real*8, gradvec_old, (nMonoEx)]
+ BEGIN_DOC
+ ! calculate the orbital gradient by hand, i.e. for
+ ! each determinant I we determine the string E_pq |I> (alpha and beta
+ ! separately) and generate
+ ! sum_I c_I is then the pq component of the orbital
+ ! gradient
+ ! E_pq = a^+_pa_q + a^+_Pa_Q
+ END_DOC
+ implicit none
+ integer :: ii,tt,aa,indx,ihole,ipart,istate
+ real*8 :: res
+
+ do indx=1,nMonoEx
+ ihole=excit(1,indx)
+ ipart=excit(2,indx)
+ call calc_grad_elem(ihole,ipart,res)
+ gradvec_old(indx)=res
+ end do
+
+ real*8 :: norm_grad
+ norm_grad=0.d0
+ do indx=1,nMonoEx
+ norm_grad+=gradvec_old(indx)*gradvec_old(indx)
+ end do
+ norm_grad=sqrt(norm_grad)
+ if (bavard) then
+ write(6,*)
+ write(6,*) ' Norm of the orbital gradient (via <0|EH|0>) : ', norm_grad
+ write(6,*)
+ endif
+
+
+END_PROVIDER
+
+subroutine calc_grad_elem(ihole,ipart,res)
+ BEGIN_DOC
+ ! eq 18 of Siegbahn et al, Physica Scripta 1980
+ ! we calculate 2 , q=hole, p=particle
+ END_DOC
+ implicit none
+ integer :: ihole,ipart,mu,iii,ispin,ierr,nu,istate
+ real*8 :: res
+ integer(bit_kind), allocatable :: det_mu(:,:),det_mu_ex(:,:)
+ real*8 :: i_H_psi_array(N_states),phase
+ allocate(det_mu(N_int,2))
+ allocate(det_mu_ex(N_int,2))
+
+ res=0.D0
+
+ do mu=1,n_det
+ ! get the string of the determinant
+ call det_extract(det_mu,mu,N_int)
+ do ispin=1,2
+ ! do the monoexcitation on it
+ call det_copy(det_mu,det_mu_ex,N_int)
+ call do_signed_mono_excitation(det_mu,det_mu_ex,nu &
+ ,ihole,ipart,ispin,phase,ierr)
+ if (ierr.eq.1) then
+ call i_H_psi(det_mu_ex,psi_det,psi_coef,N_int &
+ ,N_det,N_det,N_states,i_H_psi_array)
+ do istate=1,N_states
+ res+=i_H_psi_array(istate)*psi_coef(mu,istate)*phase
+ end do
+ end if
+ end do
+ end do
+
+ ! state-averaged gradient
+ res*=2.D0/dble(N_states)
+
+end subroutine calc_grad_elem
+
diff --git a/src/casscf/gradient.irp.f b/src/casscf/gradient.irp.f
new file mode 100644
index 00000000..e717e822
--- /dev/null
+++ b/src/casscf/gradient.irp.f
@@ -0,0 +1,171 @@
+use bitmasks
+
+BEGIN_PROVIDER [ integer, nMonoEx ]
+ BEGIN_DOC
+ ! Number of single excitations
+ END_DOC
+ implicit none
+ nMonoEx=n_core_inact_orb*n_act_orb+n_core_inact_orb*n_virt_orb+n_act_orb*n_virt_orb
+END_PROVIDER
+
+ BEGIN_PROVIDER [integer, excit, (2,nMonoEx)]
+&BEGIN_PROVIDER [character*3, excit_class, (nMonoEx)]
+ BEGIN_DOC
+ ! a list of the orbitals involved in the excitation
+ END_DOC
+
+ implicit none
+ integer :: i,t,a,ii,tt,aa,indx
+ indx=0
+ do ii=1,n_core_inact_orb
+ i=list_core_inact(ii)
+ do tt=1,n_act_orb
+ t=list_act(tt)
+ indx+=1
+ excit(1,indx)=i
+ excit(2,indx)=t
+ excit_class(indx)='c-a'
+ end do
+ end do
+
+ do ii=1,n_core_inact_orb
+ i=list_core_inact(ii)
+ do aa=1,n_virt_orb
+ a=list_virt(aa)
+ indx+=1
+ excit(1,indx)=i
+ excit(2,indx)=a
+ excit_class(indx)='c-v'
+ end do
+ end do
+
+ do tt=1,n_act_orb
+ t=list_act(tt)
+ do aa=1,n_virt_orb
+ a=list_virt(aa)
+ indx+=1
+ excit(1,indx)=t
+ excit(2,indx)=a
+ excit_class(indx)='a-v'
+ end do
+ end do
+
+ if (bavard) then
+ write(6,*) ' Filled the table of the Monoexcitations '
+ do indx=1,nMonoEx
+ write(6,*) ' ex ',indx,' : ',excit(1,indx),' -> ' &
+ ,excit(2,indx),' ',excit_class(indx)
+ end do
+ end if
+
+END_PROVIDER
+
+BEGIN_PROVIDER [real*8, gradvec2, (nMonoEx)]
+ BEGIN_DOC
+ ! calculate the orbital gradient from density
+ ! matrices and integrals; Siegbahn et al, Phys Scr 1980
+ ! eqs 14 a,b,c
+ END_DOC
+ implicit none
+ integer :: i,t,a,indx
+ real*8 :: gradvec_it,gradvec_ia,gradvec_ta
+ real*8 :: norm_grad
+
+ indx=0
+ do i=1,n_core_inact_orb
+ do t=1,n_act_orb
+ indx+=1
+ gradvec2(indx)=gradvec_it(i,t)
+ end do
+ end do
+
+ do i=1,n_core_inact_orb
+ do a=1,n_virt_orb
+ indx+=1
+ gradvec2(indx)=gradvec_ia(i,a)
+ end do
+ end do
+
+ do t=1,n_act_orb
+ do a=1,n_virt_orb
+ indx+=1
+ gradvec2(indx)=gradvec_ta(t,a)
+ end do
+ end do
+
+ norm_grad=0.d0
+ do indx=1,nMonoEx
+ norm_grad+=gradvec2(indx)*gradvec2(indx)
+ end do
+ norm_grad=sqrt(norm_grad)
+ write(6,*)
+ write(6,*) ' Norm of the orbital gradient (via D, P and integrals): ', norm_grad
+ write(6,*)
+
+END_PROVIDER
+
+real*8 function gradvec_it(i,t)
+ BEGIN_DOC
+ ! the orbital gradient core/inactive -> active
+ ! we assume natural orbitals
+ END_DOC
+ implicit none
+ integer :: i,t
+
+ integer :: ii,tt,v,vv,x,y
+ integer :: x3,y3
+
+ ii=list_core_inact(i)
+ tt=list_act(t)
+ gradvec_it=2.D0*(Fipq(tt,ii)+Fapq(tt,ii))
+ gradvec_it-=occnum(tt)*Fipq(ii,tt)
+ do v=1,n_act_orb
+ vv=list_act(v)
+ do x=1,n_act_orb
+ x3=x+n_core_inact_orb
+ do y=1,n_act_orb
+ y3=y+n_core_inact_orb
+ gradvec_it-=2.D0*P0tuvx_no(t,v,x,y)*bielec_PQxx_no(ii,vv,x3,y3)
+ end do
+ end do
+ end do
+ gradvec_it*=2.D0
+end function gradvec_it
+
+real*8 function gradvec_ia(i,a)
+ BEGIN_DOC
+ ! the orbital gradient core/inactive -> virtual
+ END_DOC
+ implicit none
+ integer :: i,a,ii,aa
+
+ ii=list_core_inact(i)
+ aa=list_virt(a)
+ gradvec_ia=2.D0*(Fipq(aa,ii)+Fapq(aa,ii))
+ gradvec_ia*=2.D0
+
+end function gradvec_ia
+
+real*8 function gradvec_ta(t,a)
+ BEGIN_DOC
+ ! the orbital gradient active -> virtual
+ ! we assume natural orbitals
+ END_DOC
+ implicit none
+ integer :: t,a,tt,aa,v,vv,x,y
+
+ tt=list_act(t)
+ aa=list_virt(a)
+ gradvec_ta=0.D0
+ gradvec_ta+=occnum(tt)*Fipq(aa,tt)
+ do v=1,n_act_orb
+ do x=1,n_act_orb
+ do y=1,n_act_orb
+ gradvec_ta+=2.D0*P0tuvx_no(t,v,x,y)*bielecCI_no(x,y,v,aa)
+ end do
+ end do
+ end do
+ gradvec_ta*=2.D0
+
+end function gradvec_ta
+
diff --git a/src/casscf/hessian.irp.f b/src/casscf/hessian.irp.f
new file mode 100644
index 00000000..52be1b76
--- /dev/null
+++ b/src/casscf/hessian.irp.f
@@ -0,0 +1,656 @@
+use bitmasks
+
+BEGIN_PROVIDER [real*8, hessmat, (nMonoEx,nMonoEx)]
+ BEGIN_DOC
+ ! calculate the orbital hessian 2
+ ! + + by hand,
+ ! determinant per determinant, as for the gradient
+ !
+ ! we assume that we have natural active orbitals
+ END_DOC
+ implicit none
+ integer :: indx,ihole,ipart
+ integer :: jndx,jhole,jpart
+ character*3 :: iexc,jexc
+ real*8 :: res
+
+ if (bavard) then
+ write(6,*) ' providing Hessian matrix hessmat '
+ write(6,*) ' nMonoEx = ',nMonoEx
+ endif
+
+ do indx=1,nMonoEx
+ do jndx=1,nMonoEx
+ hessmat(indx,jndx)=0.D0
+ end do
+ end do
+
+ do indx=1,nMonoEx
+ ihole=excit(1,indx)
+ ipart=excit(2,indx)
+ iexc=excit_class(indx)
+ do jndx=indx,nMonoEx
+ jhole=excit(1,jndx)
+ jpart=excit(2,jndx)
+ jexc=excit_class(jndx)
+ call calc_hess_elem(ihole,ipart,jhole,jpart,res)
+ hessmat(indx,jndx)=res
+ hessmat(jndx,indx)=res
+ end do
+ end do
+
+END_PROVIDER
+
+subroutine calc_hess_elem(ihole,ipart,jhole,jpart,res)
+ BEGIN_DOC
+ ! eq 19 of Siegbahn et al, Physica Scripta 1980
+ ! we calculate 2
+ ! + +
+ ! average over all states is performed.
+ ! no transition between states.
+ END_DOC
+ implicit none
+ integer :: ihole,ipart,ispin,mu,istate
+ integer :: jhole,jpart,jspin
+ integer :: mu_pq, mu_pqrs, mu_rs, mu_rspq, nu_rs,nu
+ real*8 :: res
+ integer(bit_kind), allocatable :: det_mu(:,:)
+ integer(bit_kind), allocatable :: det_nu(:,:)
+ integer(bit_kind), allocatable :: det_mu_pq(:,:)
+ integer(bit_kind), allocatable :: det_mu_rs(:,:)
+ integer(bit_kind), allocatable :: det_nu_rs(:,:)
+ integer(bit_kind), allocatable :: det_mu_pqrs(:,:)
+ integer(bit_kind), allocatable :: det_mu_rspq(:,:)
+ real*8 :: i_H_psi_array(N_states),phase,phase2,phase3
+ real*8 :: i_H_j_element
+ allocate(det_mu(N_int,2))
+ allocate(det_nu(N_int,2))
+ allocate(det_mu_pq(N_int,2))
+ allocate(det_mu_rs(N_int,2))
+ allocate(det_nu_rs(N_int,2))
+ allocate(det_mu_pqrs(N_int,2))
+ allocate(det_mu_rspq(N_int,2))
+ integer :: mu_pq_possible
+ integer :: mu_rs_possible
+ integer :: nu_rs_possible
+ integer :: mu_pqrs_possible
+ integer :: mu_rspq_possible
+
+ res=0.D0
+
+ ! the terms <0|E E H |0>
+ do mu=1,n_det
+ ! get the string of the determinant
+ call det_extract(det_mu,mu,N_int)
+ do ispin=1,2
+ ! do the monoexcitation pq on it
+ call det_copy(det_mu,det_mu_pq,N_int)
+ call do_signed_mono_excitation(det_mu,det_mu_pq,mu_pq &
+ ,ihole,ipart,ispin,phase,mu_pq_possible)
+ if (mu_pq_possible.eq.1) then
+ ! possible, but not necessarily in the list
+ ! do the second excitation
+ do jspin=1,2
+ call det_copy(det_mu_pq,det_mu_pqrs,N_int)
+ call do_signed_mono_excitation(det_mu_pq,det_mu_pqrs,mu_pqrs&
+ ,jhole,jpart,jspin,phase2,mu_pqrs_possible)
+ ! excitation possible
+ if (mu_pqrs_possible.eq.1) then
+ call i_H_psi(det_mu_pqrs,psi_det,psi_coef,N_int &
+ ,N_det,N_det,N_states,i_H_psi_array)
+ do istate=1,N_states
+ res+=i_H_psi_array(istate)*psi_coef(mu,istate)*phase*phase2
+ end do
+ end if
+ ! try the de-excitation with opposite sign
+ call det_copy(det_mu_pq,det_mu_pqrs,N_int)
+ call do_signed_mono_excitation(det_mu_pq,det_mu_pqrs,mu_pqrs&
+ ,jpart,jhole,jspin,phase2,mu_pqrs_possible)
+ phase2=-phase2
+ ! excitation possible
+ if (mu_pqrs_possible.eq.1) then
+ call i_H_psi(det_mu_pqrs,psi_det,psi_coef,N_int &
+ ,N_det,N_det,N_states,i_H_psi_array)
+ do istate=1,N_states
+ res+=i_H_psi_array(istate)*psi_coef(mu,istate)*phase*phase2
+ end do
+ end if
+ end do
+ end if
+ ! exchange the notion of pq and rs
+ ! do the monoexcitation rs on the initial determinant
+ call det_copy(det_mu,det_mu_rs,N_int)
+ call do_signed_mono_excitation(det_mu,det_mu_rs,mu_rs &
+ ,jhole,jpart,ispin,phase2,mu_rs_possible)
+ if (mu_rs_possible.eq.1) then
+ ! do the second excitation
+ do jspin=1,2
+ call det_copy(det_mu_rs,det_mu_rspq,N_int)
+ call do_signed_mono_excitation(det_mu_rs,det_mu_rspq,mu_rspq&
+ ,ihole,ipart,jspin,phase3,mu_rspq_possible)
+ ! excitation possible (of course, the result is outside the CAS)
+ if (mu_rspq_possible.eq.1) then
+ call i_H_psi(det_mu_rspq,psi_det,psi_coef,N_int &
+ ,N_det,N_det,N_states,i_H_psi_array)
+ do istate=1,N_states
+ res+=i_H_psi_array(istate)*psi_coef(mu,istate)*phase2*phase3
+ end do
+ end if
+ ! we may try the de-excitation, with opposite sign
+ call det_copy(det_mu_rs,det_mu_rspq,N_int)
+ call do_signed_mono_excitation(det_mu_rs,det_mu_rspq,mu_rspq&
+ ,ipart,ihole,jspin,phase3,mu_rspq_possible)
+ phase3=-phase3
+ ! excitation possible (of course, the result is outside the CAS)
+ if (mu_rspq_possible.eq.1) then
+ call i_H_psi(det_mu_rspq,psi_det,psi_coef,N_int &
+ ,N_det,N_det,N_states,i_H_psi_array)
+ do istate=1,N_states
+ res+=i_H_psi_array(istate)*psi_coef(mu,istate)*phase2*phase3
+ end do
+ end if
+ end do
+ end if
+ !
+ ! the operator E H E, we have to do a double loop over the determinants
+ ! we still have the determinant mu_pq and the phase in memory
+ if (mu_pq_possible.eq.1) then
+ do nu=1,N_det
+ call det_extract(det_nu,nu,N_int)
+ do jspin=1,2
+ call det_copy(det_nu,det_nu_rs,N_int)
+ call do_signed_mono_excitation(det_nu,det_nu_rs,nu_rs &
+ ,jhole,jpart,jspin,phase2,nu_rs_possible)
+ ! excitation possible ?
+ if (nu_rs_possible.eq.1) then
+ call i_H_j(det_mu_pq,det_nu_rs,N_int,i_H_j_element)
+ do istate=1,N_states
+ res+=2.D0*i_H_j_element*psi_coef(mu,istate) &
+ *psi_coef(nu,istate)*phase*phase2
+ end do
+ end if
+ end do
+ end do
+ end if
+ end do
+ end do
+
+ ! state-averaged Hessian
+ res*=1.D0/dble(N_states)
+
+end subroutine calc_hess_elem
+
+BEGIN_PROVIDER [real*8, hessmat2, (nMonoEx,nMonoEx)]
+ BEGIN_DOC
+ ! explicit hessian matrix from density matrices and integrals
+ ! of course, this will be used for a direct Davidson procedure later
+ ! we will not store the matrix in real life
+ ! formulas are broken down as functions for the 6 classes of matrix elements
+ !
+ END_DOC
+ implicit none
+ integer :: i,j,t,u,a,b,indx,jndx,bstart,ustart,indx_shift
+
+ real*8 :: hessmat_itju
+ real*8 :: hessmat_itja
+ real*8 :: hessmat_itua
+ real*8 :: hessmat_iajb
+ real*8 :: hessmat_iatb
+ real*8 :: hessmat_taub
+
+ if (bavard) then
+ write(6,*) ' providing Hessian matrix hessmat2 '
+ write(6,*) ' nMonoEx = ',nMonoEx
+ endif
+
+ !$OMP PARALLEL DEFAULT(NONE) &
+ !$OMP SHARED(hessmat2,n_core_inact_orb,n_act_orb,n_virt_orb,nMonoEx) &
+ !$OMP PRIVATE(i,indx,jndx,j,ustart,t,u,a,bstart,indx_shift)
+
+ !$OMP DO
+ do i=1,n_core_inact_orb
+ do t=1,n_act_orb
+ indx = t + (i-1)*n_act_orb
+ jndx=indx
+ do j=i,n_core_inact_orb
+ if (i.eq.j) then
+ ustart=t
+ else
+ ustart=1
+ end if
+ do u=ustart,n_act_orb
+ hessmat2(jndx,indx)=hessmat_itju(i,t,j,u)
+ jndx+=1
+ end do
+ end do
+ do j=1,n_core_inact_orb
+ do a=1,n_virt_orb
+ hessmat2(jndx,indx)=hessmat_itja(i,t,j,a)
+ jndx+=1
+ end do
+ end do
+ do u=1,n_act_orb
+ do a=1,n_virt_orb
+ hessmat2(jndx,indx)=hessmat_itua(i,t,u,a)
+ jndx+=1
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO NOWAIT
+
+ indx_shift = n_core_inact_orb*n_act_orb
+ !$OMP DO
+ do a=1,n_virt_orb
+ do i=1,n_core_inact_orb
+ indx = a + (i-1)*n_virt_orb + indx_shift
+ jndx=indx
+ do j=i,n_core_inact_orb
+ if (i.eq.j) then
+ bstart=a
+ else
+ bstart=1
+ end if
+ do b=bstart,n_virt_orb
+ hessmat2(jndx,indx)=hessmat_iajb(i,a,j,b)
+ jndx+=1
+ end do
+ end do
+ do t=1,n_act_orb
+ do b=1,n_virt_orb
+ hessmat2(jndx,indx)=hessmat_iatb(i,a,t,b)
+ jndx+=1
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO NOWAIT
+
+ indx_shift += n_core_inact_orb*n_virt_orb
+ !$OMP DO
+ do a=1,n_virt_orb
+ do t=1,n_act_orb
+ indx = a + (t-1)*n_virt_orb + indx_shift
+ jndx=indx
+ do u=t,n_act_orb
+ if (t.eq.u) then
+ bstart=a
+ else
+ bstart=1
+ end if
+ do b=bstart,n_virt_orb
+ hessmat2(jndx,indx)=hessmat_taub(t,a,u,b)
+ jndx+=1
+ end do
+ end do
+ end do
+ end do
+ !$OMP END DO
+
+ !$OMP END PARALLEL
+
+ do jndx=1,nMonoEx
+ do indx=1,jndx-1
+ hessmat2(indx,jndx) = hessmat2(jndx,indx)
+ enddo
+ enddo
+
+
+END_PROVIDER
+
+real*8 function hessmat_itju(i,t,j,u)
+ BEGIN_DOC
+ ! the orbital hessian for core/inactive -> active, core/inactive -> active
+ ! i, t, j, u are list indices, the corresponding orbitals are ii,tt,jj,uu
+ !
+ ! we assume natural orbitals
+ END_DOC
+ implicit none
+ integer :: i,t,j,u,ii,tt,uu,v,vv,x,xx,y,jj
+ real*8 :: term,t2
+
+ ii=list_core_inact(i)
+ tt=list_act(t)
+ if (i.eq.j) then
+ if (t.eq.u) then
+ ! diagonal element
+ term=occnum(tt)*Fipq(ii,ii)+2.D0*(Fipq(tt,tt)+Fapq(tt,tt)) &
+ -2.D0*(Fipq(ii,ii)+Fapq(ii,ii))
+ term+=2.D0*(3.D0*bielec_pxxq_no(tt,i,i,tt)-bielec_pqxx_no(tt,tt,i,i))
+ term-=2.D0*occnum(tt)*(3.D0*bielec_pxxq_no(tt,i,i,tt) &
+ -bielec_pqxx_no(tt,tt,i,i))
+ term-=occnum(tt)*Fipq(tt,tt)
+ do v=1,n_act_orb
+ vv=list_act(v)
+ do x=1,n_act_orb
+ xx=list_act(x)
+ term+=2.D0*(P0tuvx_no(t,t,v,x)*bielec_pqxx_no(vv,xx,i,i) &
+ +(P0tuvx_no(t,x,v,t)+P0tuvx_no(t,x,t,v))* &
+ bielec_pxxq_no(vv,i,i,xx))
+ do y=1,n_act_orb
+ term-=2.D0*P0tuvx_no(t,v,x,y)*bielecCI_no(t,v,y,xx)
+ end do
+ end do
+ end do
+ else
+ ! it/iu, t != u
+ uu=list_act(u)
+ term=2.D0*(Fipq(tt,uu)+Fapq(tt,uu))
+ term+=2.D0*(4.D0*bielec_PxxQ_no(tt,i,j,uu)-bielec_PxxQ_no(uu,i,j,tt) &
+ -bielec_PQxx_no(tt,uu,i,j))
+ term-=occnum(tt)*Fipq(uu,tt)
+ term-=(occnum(tt)+occnum(uu)) &
+ *(3.D0*bielec_PxxQ_no(tt,i,i,uu)-bielec_PQxx_no(uu,tt,i,i))
+ do v=1,n_act_orb
+ vv=list_act(v)
+ ! term-=D0tu(u,v)*Fipq(tt,vv) ! published, but inverting t and u seems more correct
+ do x=1,n_act_orb
+ xx=list_act(x)
+ term+=2.D0*(P0tuvx_no(u,t,v,x)*bielec_pqxx_no(vv,xx,i,i) &
+ +(P0tuvx_no(u,x,v,t)+P0tuvx_no(u,x,t,v)) &
+ *bielec_pxxq_no(vv,i,i,xx))
+ do y=1,n_act_orb
+ term-=2.D0*P0tuvx_no(t,v,x,y)*bielecCI_no(u,v,y,xx)
+ end do
+ end do
+ end do
+ end if
+ else
+ ! it/ju
+ jj=list_core_inact(j)
+ uu=list_act(u)
+ if (t.eq.u) then
+ term=occnum(tt)*Fipq(ii,jj)
+ term-=2.D0*(Fipq(ii,jj)+Fapq(ii,jj))
+ else
+ term=0.D0
+ end if
+ term+=2.D0*(4.D0*bielec_PxxQ_no(tt,i,j,uu)-bielec_PxxQ_no(uu,i,j,tt) &
+ -bielec_PQxx_no(tt,uu,i,j))
+ term-=(occnum(tt)+occnum(uu))* &
+ (4.D0*bielec_PxxQ_no(tt,i,j,uu)-bielec_PxxQ_no(uu,i,j,tt) &
+ -bielec_PQxx_no(uu,tt,i,j))
+ do v=1,n_act_orb
+ vv=list_act(v)
+ do x=1,n_act_orb
+ xx=list_act(x)
+ term+=2.D0*(P0tuvx_no(u,t,v,x)*bielec_pqxx_no(vv,xx,i,j) &
+ +(P0tuvx_no(u,x,v,t)+P0tuvx_no(u,x,t,v)) &
+ *bielec_pxxq_no(vv,i,j,xx))
+ end do
+ end do
+ end if
+
+ term*=2.D0
+ hessmat_itju=term
+
+end function hessmat_itju
+
+real*8 function hessmat_itja(i,t,j,a)
+ BEGIN_DOC
+ ! the orbital hessian for core/inactive -> active, core/inactive -> virtual
+ END_DOC
+ implicit none
+ integer :: i,t,j,a,ii,tt,jj,aa,v,vv,x,y
+ real*8 :: term
+
+ ! it/ja
+ ii=list_core_inact(i)
+ tt=list_act(t)
+ jj=list_core_inact(j)
+ aa=list_virt(a)
+ term=2.D0*(4.D0*bielec_pxxq_no(aa,j,i,tt) &
+ -bielec_pqxx_no(aa,tt,i,j) -bielec_pxxq_no(aa,i,j,tt))
+ term-=occnum(tt)*(4.D0*bielec_pxxq_no(aa,j,i,tt) &
+ -bielec_pqxx_no(aa,tt,i,j) -bielec_pxxq_no(aa,i,j,tt))
+ if (i.eq.j) then
+ term+=2.D0*(Fipq(aa,tt)+Fapq(aa,tt))
+ term-=0.5D0*occnum(tt)*Fipq(aa,tt)
+ do v=1,n_act_orb
+ do x=1,n_act_orb
+ do y=1,n_act_orb
+ term-=P0tuvx_no(t,v,x,y)*bielecCI_no(x,y,v,aa)
+ end do
+ end do
+ end do
+ end if
+ term*=2.D0
+ hessmat_itja=term
+
+end function hessmat_itja
+
+real*8 function hessmat_itua(i,t,u,a)
+ BEGIN_DOC
+ ! the orbital hessian for core/inactive -> active, active -> virtual
+ END_DOC
+ implicit none
+ integer :: i,t,u,a,ii,tt,uu,aa,v,vv,x,xx,u3,t3,v3
+ real*8 :: term
+
+ ii=list_core_inact(i)
+ tt=list_act(t)
+ t3=t+n_core_inact_orb
+ uu=list_act(u)
+ u3=u+n_core_inact_orb
+ aa=list_virt(a)
+ if (t.eq.u) then
+ term=-occnum(tt)*Fipq(aa,ii)
+ else
+ term=0.D0
+ end if
+ term-=occnum(uu)*(bielec_pqxx_no(aa,ii,t3,u3)-4.D0*bielec_pqxx_no(aa,uu,t3,i)&
+ +bielec_pxxq_no(aa,t3,u3,ii))
+ do v=1,n_act_orb
+ vv=list_act(v)
+ v3=v+n_core_inact_orb
+ do x=1,n_act_orb
+ integer :: x3
+ xx=list_act(x)
+ x3=x+n_core_inact_orb
+ term-=2.D0*(P0tuvx_no(t,u,v,x)*bielec_pqxx_no(aa,ii,v3,x3) &
+ +(P0tuvx_no(t,v,u,x)+P0tuvx_no(t,v,x,u)) &
+ *bielec_pqxx_no(aa,xx,v3,i))
+ end do
+ end do
+ if (t.eq.u) then
+ term+=Fipq(aa,ii)+Fapq(aa,ii)
+ end if
+ term*=2.D0
+ hessmat_itua=term
+
+end function hessmat_itua
+
+real*8 function hessmat_iajb(i,a,j,b)
+ BEGIN_DOC
+ ! the orbital hessian for core/inactive -> virtual, core/inactive -> virtual
+ END_DOC
+ implicit none
+ integer :: i,a,j,b,ii,aa,jj,bb
+ real*8 :: term
+
+ ii=list_core_inact(i)
+ aa=list_virt(a)
+ if (i.eq.j) then
+ if (a.eq.b) then
+ ! ia/ia
+ term=2.D0*(Fipq(aa,aa)+Fapq(aa,aa)-Fipq(ii,ii)-Fapq(ii,ii))
+ term+=2.D0*(3.D0*bielec_pxxq_no(aa,i,i,aa)-bielec_pqxx_no(aa,aa,i,i))
+ else
+ bb=list_virt(b)
+ ! ia/ib
+ term=2.D0*(Fipq(aa,bb)+Fapq(aa,bb))
+ term+=2.D0*(3.D0*bielec_pxxq_no(aa,i,i,bb)-bielec_pqxx_no(aa,bb,i,i))
+ end if
+ else
+ ! ia/jb
+ jj=list_core_inact(j)
+ bb=list_virt(b)
+ term=2.D0*(4.D0*bielec_pxxq_no(aa,i,j,bb)-bielec_pqxx_no(aa,bb,i,j) &
+ -bielec_pxxq_no(aa,j,i,bb))
+ if (a.eq.b) then
+ term-=2.D0*(Fipq(ii,jj)+Fapq(ii,jj))
+ end if
+ end if
+ term*=2.D0
+ hessmat_iajb=term
+
+end function hessmat_iajb
+
+real*8 function hessmat_iatb(i,a,t,b)
+ BEGIN_DOC
+ ! the orbital hessian for core/inactive -> virtual, active -> virtual
+ END_DOC
+ implicit none
+ integer :: i,a,t,b,ii,aa,tt,bb,v,vv,x,y,v3,t3
+ real*8 :: term
+
+ ii=list_core_inact(i)
+ aa=list_virt(a)
+ tt=list_act(t)
+ bb=list_virt(b)
+ t3=t+n_core_inact_orb
+ term=occnum(tt)*(4.D0*bielec_pxxq_no(aa,i,t3,bb)-bielec_pxxq_no(aa,t3,i,bb)&
+ -bielec_pqxx_no(aa,bb,i,t3))
+ if (a.eq.b) then
+ term-=Fipq(tt,ii)+Fapq(tt,ii)
+ term-=0.5D0*occnum(tt)*Fipq(tt,ii)
+ do v=1,n_act_orb
+ do x=1,n_act_orb
+ do y=1,n_act_orb
+ term-=P0tuvx_no(t,v,x,y)*bielecCI_no(x,y,v,ii)
+ end do
+ end do
+ end do
+ end if
+ term*=2.D0
+ hessmat_iatb=term
+
+end function hessmat_iatb
+
+real*8 function hessmat_taub(t,a,u,b)
+ BEGIN_DOC
+ ! the orbital hessian for act->virt,act->virt
+ END_DOC
+ implicit none
+ integer :: t,a,u,b,tt,aa,uu,bb,v,vv,x,xx,y
+ integer :: v3,x3
+ real*8 :: term,t1,t2,t3
+
+ tt=list_act(t)
+ aa=list_virt(a)
+ if (t == u) then
+ if (a == b) then
+ ! ta/ta
+ t1=occnum(tt)*Fipq(aa,aa)
+ t2=0.D0
+ t3=0.D0
+ t1-=occnum(tt)*Fipq(tt,tt)
+ do v=1,n_act_orb
+ vv=list_act(v)
+ v3=v+n_core_inact_orb
+ do x=1,n_act_orb
+ xx=list_act(x)
+ x3=x+n_core_inact_orb
+ t2+=2.D0*(P0tuvx_no(t,t,v,x)*bielec_pqxx_no(aa,aa,v3,x3) &
+ +(P0tuvx_no(t,x,v,t)+P0tuvx_no(t,x,t,v))* &
+ bielec_pxxq_no(aa,x3,v3,aa))
+ do y=1,n_act_orb
+ t3-=2.D0*P0tuvx_no(t,v,x,y)*bielecCI_no(t,v,y,xx)
+ end do
+ end do
+ end do
+ term=t1+t2+t3
+ else
+ bb=list_virt(b)
+ ! ta/tb b/=a
+ term=occnum(tt)*Fipq(aa,bb)
+ do v=1,n_act_orb
+ vv=list_act(v)
+ v3=v+n_core_inact_orb
+ do x=1,n_act_orb
+ xx=list_act(x)
+ x3=x+n_core_inact_orb
+ term+=2.D0*(P0tuvx_no(t,t,v,x)*bielec_pqxx_no(aa,bb,v3,x3) &
+ +(P0tuvx_no(t,x,v,t)+P0tuvx_no(t,x,t,v)) &
+ *bielec_pxxq_no(aa,x3,v3,bb))
+ end do
+ end do
+ end if
+ else
+ ! ta/ub t/=u
+ uu=list_act(u)
+ bb=list_virt(b)
+ term=0.D0
+ do v=1,n_act_orb
+ vv=list_act(v)
+ v3=v+n_core_inact_orb
+ do x=1,n_act_orb
+ xx=list_act(x)
+ x3=x+n_core_inact_orb
+ term+=2.D0*(P0tuvx_no(t,u,v,x)*bielec_pqxx_no(aa,bb,v3,x3) &
+ +(P0tuvx_no(t,x,v,u)+P0tuvx_no(t,x,u,v)) &
+ *bielec_pxxq_no(aa,x3,v3,bb))
+ end do
+ end do
+ if (a.eq.b) then
+ term-=0.5D0*(occnum(tt)*Fipq(uu,tt)+occnum(uu)*Fipq(tt,uu))
+ do v=1,n_act_orb
+ do y=1,n_act_orb
+ do x=1,n_act_orb
+ term-=P0tuvx_no(t,v,x,y)*bielecCI_no(x,y,v,uu)
+ term-=P0tuvx_no(u,v,x,y)*bielecCI_no(x,y,v,tt)
+ end do
+ end do
+ end do
+ end if
+
+ end if
+
+ term*=2.D0
+ hessmat_taub=term
+
+end function hessmat_taub
+
+BEGIN_PROVIDER [real*8, hessdiag, (nMonoEx)]
+ BEGIN_DOC
+ ! the diagonal of the Hessian, needed for the Davidson procedure
+ END_DOC
+ implicit none
+ integer :: i,t,a,indx,indx_shift
+ real*8 :: hessmat_itju,hessmat_iajb,hessmat_taub
+
+ !$OMP PARALLEL DEFAULT(NONE) &
+ !$OMP SHARED(hessdiag,n_core_inact_orb,n_act_orb,n_virt_orb,nMonoEx) &
+ !$OMP PRIVATE(i,indx,t,a,indx_shift)
+
+ !$OMP DO
+ do i=1,n_core_inact_orb
+ do t=1,n_act_orb
+ indx = t + (i-1)*n_act_orb
+ hessdiag(indx)=hessmat_itju(i,t,i,t)
+ end do
+ end do
+ !$OMP END DO NOWAIT
+
+ indx_shift = n_core_inact_orb*n_act_orb
+ !$OMP DO
+ do a=1,n_virt_orb
+ do i=1,n_core_inact_orb
+ indx = a + (i-1)*n_virt_orb + indx_shift
+ hessdiag(indx)=hessmat_iajb(i,a,i,a)
+ end do
+ end do
+ !$OMP END DO NOWAIT
+
+ indx_shift += n_core_inact_orb*n_virt_orb
+ !$OMP DO
+ do a=1,n_virt_orb
+ do t=1,n_act_orb
+ indx = a + (t-1)*n_virt_orb + indx_shift
+ hessdiag(indx)=hessmat_taub(t,a,t,a)
+ end do
+ end do
+ !$OMP END DO
+ !$OMP END PARALLEL
+
+END_PROVIDER
diff --git a/src/casscf/mcscf_fock.irp.f b/src/casscf/mcscf_fock.irp.f
new file mode 100644
index 00000000..e4568405
--- /dev/null
+++ b/src/casscf/mcscf_fock.irp.f
@@ -0,0 +1,80 @@
+BEGIN_PROVIDER [real*8, Fipq, (mo_num,mo_num) ]
+ BEGIN_DOC
+ ! the inactive Fock matrix, in molecular orbitals
+ END_DOC
+ implicit none
+ integer :: p,q,k,kk,t,tt,u,uu
+
+ do q=1,mo_num
+ do p=1,mo_num
+ Fipq(p,q)=one_ints_no(p,q)
+ end do
+ end do
+
+ ! the inactive Fock matrix
+ do k=1,n_core_inact_orb
+ kk=list_core_inact(k)
+ do q=1,mo_num
+ do p=1,mo_num
+ Fipq(p,q)+=2.D0*bielec_pqxx_no(p,q,k,k) -bielec_pxxq_no(p,k,k,q)
+ end do
+ end do
+ end do
+
+ if (bavard) then
+ integer :: i
+ write(6,*)
+ write(6,*) ' the diagonal of the inactive effective Fock matrix '
+ write(6,'(5(i3,F12.5))') (i,Fipq(i,i),i=1,mo_num)
+ write(6,*)
+ end if
+
+
+END_PROVIDER
+
+
+BEGIN_PROVIDER [real*8, Fapq, (mo_num,mo_num) ]
+ BEGIN_DOC
+ ! the active active Fock matrix, in molecular orbitals
+ ! we create them in MOs, quite expensive
+ !
+ ! for an implementation in AOs we need first the natural orbitals
+ ! for forming an active density matrix in AOs
+ !
+ END_DOC
+ implicit none
+ integer :: p,q,k,kk,t,tt,u,uu
+
+ Fapq = 0.d0
+
+ ! the active Fock matrix, D0tu is diagonal
+ do t=1,n_act_orb
+ tt=list_act(t)
+ do q=1,mo_num
+ do p=1,mo_num
+ Fapq(p,q)+=occnum(tt) &
+ *(bielec_pqxx_no(p,q,tt,tt)-0.5D0*bielec_pxxq_no(p,tt,tt,q))
+ end do
+ end do
+ end do
+
+ if (bavard) then
+ integer :: i
+ write(6,*)
+ write(6,*) ' the effective Fock matrix over MOs'
+ write(6,*)
+
+ write(6,*)
+ write(6,*) ' the diagonal of the inactive effective Fock matrix '
+ write(6,'(5(i3,F12.5))') (i,Fipq(i,i),i=1,mo_num)
+ write(6,*)
+ write(6,*)
+ write(6,*) ' the diagonal of the active Fock matrix '
+ write(6,'(5(i3,F12.5))') (i,Fapq(i,i),i=1,mo_num)
+ write(6,*)
+ end if
+
+
+END_PROVIDER
+
+
diff --git a/src/casscf/natorb.irp.f b/src/casscf/natorb.irp.f
new file mode 100644
index 00000000..9ce90304
--- /dev/null
+++ b/src/casscf/natorb.irp.f
@@ -0,0 +1,231 @@
+ BEGIN_PROVIDER [real*8, occnum, (mo_num)]
+ implicit none
+ BEGIN_DOC
+ ! MO occupation numbers
+ END_DOC
+
+ integer :: i
+ occnum=0.D0
+ do i=1,n_core_inact_orb
+ occnum(list_core_inact(i))=2.D0
+ end do
+
+ do i=1,n_act_orb
+ occnum(list_act(i))=occ_act(i)
+ end do
+
+ if (bavard) then
+ write(6,*) ' occupation numbers '
+ do i=1,mo_num
+ write(6,*) i,occnum(i)
+ end do
+ endif
+
+END_PROVIDER
+
+
+ BEGIN_PROVIDER [ real*8, natorbsCI, (n_act_orb,n_act_orb) ]
+&BEGIN_PROVIDER [ real*8, occ_act, (n_act_orb) ]
+ implicit none
+ BEGIN_DOC
+ ! Natural orbitals of CI
+ END_DOC
+ integer :: i, j
+ double precision :: Vt(n_act_orb,n_act_orb)
+
+! call lapack_diag(occ_act,natorbsCI,D0tu,n_act_orb,n_act_orb)
+ call svd(D0tu, size(D0tu,1), natorbsCI,size(natorbsCI,1), occ_act, Vt, size(Vt,1),n_act_orb,n_act_orb)
+
+ if (bavard) then
+ write(6,*) ' found occupation numbers as '
+ do i=1,n_act_orb
+ write(6,*) i,occ_act(i)
+ end do
+
+ integer :: nmx
+ real*8 :: xmx
+ do i=1,n_act_orb
+ ! largest element of the eigenvector should be positive
+ xmx=0.D0
+ nmx=0
+ do j=1,n_act_orb
+ if (abs(natOrbsCI(j,i)).gt.xmx) then
+ nmx=j
+ xmx=abs(natOrbsCI(j,i))
+ end if
+ end do
+ xmx=sign(1.D0,natOrbsCI(nmx,i))
+ do j=1,n_act_orb
+ natOrbsCI(j,i)*=xmx
+ end do
+
+ write(6,*) ' Eigenvector No ',i
+ write(6,'(5(I3,F12.5))') (j,natOrbsCI(j,i),j=1,n_act_orb)
+ end do
+ end if
+
+END_PROVIDER
+
+
+BEGIN_PROVIDER [real*8, P0tuvx_no, (n_act_orb,n_act_orb,n_act_orb,n_act_orb)]
+ implicit none
+ BEGIN_DOC
+ ! 4-index transformation of 2part matrices
+ END_DOC
+ integer :: i,j,k,l,p,q
+ real*8 :: d(n_act_orb)
+
+ ! index per index
+ ! first quarter
+ P0tuvx_no(:,:,:,:) = P0tuvx(:,:,:,:)
+
+ do j=1,n_act_orb
+ do k=1,n_act_orb
+ do l=1,n_act_orb
+ do p=1,n_act_orb
+ d(p)=0.D0
+ end do
+ do p=1,n_act_orb
+ do q=1,n_act_orb
+ d(p)+=P0tuvx_no(q,j,k,l)*natorbsCI(q,p)
+ end do
+ end do
+ do p=1,n_act_orb
+ P0tuvx_no(p,j,k,l)=d(p)
+ end do
+ end do
+ end do
+ end do
+ ! 2nd quarter
+ do j=1,n_act_orb
+ do k=1,n_act_orb
+ do l=1,n_act_orb
+ do p=1,n_act_orb
+ d(p)=0.D0
+ end do
+ do p=1,n_act_orb
+ do q=1,n_act_orb
+ d(p)+=P0tuvx_no(j,q,k,l)*natorbsCI(q,p)
+ end do
+ end do
+ do p=1,n_act_orb
+ P0tuvx_no(j,p,k,l)=d(p)
+ end do
+ end do
+ end do
+ end do
+ ! 3rd quarter
+ do j=1,n_act_orb
+ do k=1,n_act_orb
+ do l=1,n_act_orb
+ do p=1,n_act_orb
+ d(p)=0.D0
+ end do
+ do p=1,n_act_orb
+ do q=1,n_act_orb
+ d(p)+=P0tuvx_no(j,k,q,l)*natorbsCI(q,p)
+ end do
+ end do
+ do p=1,n_act_orb
+ P0tuvx_no(j,k,p,l)=d(p)
+ end do
+ end do
+ end do
+ end do
+ ! 4th quarter
+ do j=1,n_act_orb
+ do k=1,n_act_orb
+ do l=1,n_act_orb
+ do p=1,n_act_orb
+ d(p)=0.D0
+ end do
+ do p=1,n_act_orb
+ do q=1,n_act_orb
+ d(p)+=P0tuvx_no(j,k,l,q)*natorbsCI(q,p)
+ end do
+ end do
+ do p=1,n_act_orb
+ P0tuvx_no(j,k,l,p)=d(p)
+ end do
+ end do
+ end do
+ end do
+
+END_PROVIDER
+
+
+
+BEGIN_PROVIDER [real*8, one_ints_no, (mo_num,mo_num)]
+ implicit none
+ BEGIN_DOC
+ ! Transformed one-e integrals
+ END_DOC
+ integer :: i,j, p, q
+ real*8 :: d(n_act_orb)
+ one_ints_no(:,:)=mo_one_e_integrals(:,:)
+
+ ! 1st half-trf
+ do j=1,mo_num
+ do p=1,n_act_orb
+ d(p)=0.D0
+ end do
+ do p=1,n_act_orb
+ do q=1,n_act_orb
+ d(p)+=one_ints_no(list_act(q),j)*natorbsCI(q,p)
+ end do
+ end do
+ do p=1,n_act_orb
+ one_ints_no(list_act(p),j)=d(p)
+ end do
+ end do
+
+ ! 2nd half-trf
+ do j=1,mo_num
+ do p=1,n_act_orb
+ d(p)=0.D0
+ end do
+ do p=1,n_act_orb
+ do q=1,n_act_orb
+ d(p)+=one_ints_no(j,list_act(q))*natorbsCI(q,p)
+ end do
+ end do
+ do p=1,n_act_orb
+ one_ints_no(j,list_act(p))=d(p)
+ end do
+ end do
+END_PROVIDER
+
+
+BEGIN_PROVIDER [ double precision, NatOrbsCI_mos, (mo_num, mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! Rotation matrix from current MOs to the CI natural MOs
+ END_DOC
+ integer :: p,q
+
+ NatOrbsCI_mos(:,:) = 0.d0
+
+ do q = 1,mo_num
+ NatOrbsCI_mos(q,q) = 1.d0
+ enddo
+
+ do q = 1,n_act_orb
+ do p = 1,n_act_orb
+ NatOrbsCI_mos(list_act(p),list_act(q)) = natorbsCI(p,q)
+ enddo
+ enddo
+END_PROVIDER
+
+
+BEGIN_PROVIDER [real*8, NatOrbsFCI, (ao_num,mo_num)]
+ implicit none
+ BEGIN_DOC
+! FCI natural orbitals
+ END_DOC
+
+ call dgemm('N','N', ao_num,mo_num,mo_num,1.d0, &
+ mo_coef, size(mo_coef,1), &
+ NatOrbsCI_mos, size(NatOrbsCI_mos,1), 0.d0, &
+ NatOrbsFCI, size(NatOrbsFCI,1))
+END_PROVIDER
+
diff --git a/src/casscf/neworbs.irp.f b/src/casscf/neworbs.irp.f
new file mode 100644
index 00000000..06a89318
--- /dev/null
+++ b/src/casscf/neworbs.irp.f
@@ -0,0 +1,221 @@
+BEGIN_PROVIDER [real*8, SXmatrix, (nMonoEx+1,nMonoEx+1)]
+ implicit none
+ BEGIN_DOC
+ ! Single-excitation matrix
+ END_DOC
+
+ integer :: i,j
+
+ do i=1,nMonoEx+1
+ do j=1,nMonoEx+1
+ SXmatrix(i,j)=0.D0
+ end do
+ end do
+
+ do i=1,nMonoEx
+ SXmatrix(1,i+1)=gradvec2(i)
+ SXmatrix(1+i,1)=gradvec2(i)
+ end do
+
+ do i=1,nMonoEx
+ do j=1,nMonoEx
+ SXmatrix(i+1,j+1)=hessmat2(i,j)
+ SXmatrix(j+1,i+1)=hessmat2(i,j)
+ end do
+ end do
+
+ do i = 1, nMonoEx
+ SXmatrix(i+1,i+1) += level_shift_casscf
+ enddo
+ if (bavard) then
+ do i=2,nMonoEx
+ write(6,*) ' diagonal of the Hessian : ',i,hessmat2(i,i)
+ end do
+ end if
+
+
+END_PROVIDER
+
+ BEGIN_PROVIDER [real*8, SXeigenvec, (nMonoEx+1,nMonoEx+1)]
+&BEGIN_PROVIDER [real*8, SXeigenval, (nMonoEx+1)]
+ implicit none
+ BEGIN_DOC
+ ! Eigenvectors/eigenvalues of the single-excitation matrix
+ END_DOC
+ call lapack_diag(SXeigenval,SXeigenvec,SXmatrix,nMonoEx+1,nMonoEx+1)
+ if (bavard) then
+ write(6,*) ' SXdiag : lowest 5 eigenvalues '
+ write(6,*) ' 1 - ',SXeigenval(1),SXeigenvec(1,1)
+ if(nmonoex.gt.0)then
+ write(6,*) ' 2 - ',SXeigenval(2),SXeigenvec(1,2)
+ write(6,*) ' 3 - ',SXeigenval(3),SXeigenvec(1,3)
+ write(6,*) ' 4 - ',SXeigenval(4),SXeigenvec(1,4)
+ write(6,*) ' 5 - ',SXeigenval(5),SXeigenvec(1,5)
+ endif
+ write(6,*)
+ write(6,*) ' SXdiag : lowest eigenvalue = ',SXeigenval(1)
+ endif
+END_PROVIDER
+
+ BEGIN_PROVIDER [real*8, energy_improvement]
+ implicit none
+ if(state_following_casscf)then
+ energy_improvement = SXeigenval(best_vector_ovrlp_casscf)
+ else
+ energy_improvement = SXeigenval(1)
+ endif
+ END_PROVIDER
+
+
+
+ BEGIN_PROVIDER [ integer, best_vector_ovrlp_casscf ]
+&BEGIN_PROVIDER [ double precision, best_overlap_casscf ]
+ implicit none
+ integer :: i
+ double precision :: c0
+ best_overlap_casscf = 0.D0
+ best_vector_ovrlp_casscf = -1000
+ do i=1,nMonoEx+1
+ if (SXeigenval(i).lt.0.D0) then
+ if (abs(SXeigenvec(1,i)).gt.best_overlap_casscf) then
+ best_overlap_casscf=abs(SXeigenvec(1,i))
+ best_vector_ovrlp_casscf = i
+ end if
+ end if
+ end do
+ if(best_vector_ovrlp_casscf.lt.0)then
+ best_vector_ovrlp_casscf = minloc(SXeigenval,nMonoEx+1)
+ endif
+ c0=SXeigenvec(1,best_vector_ovrlp_casscf)
+ if (bavard) then
+ write(6,*) ' SXdiag : eigenvalue for best overlap with '
+ write(6,*) ' previous orbitals = ',SXeigenval(best_vector_ovrlp_casscf)
+ write(6,*) ' weight of the 1st element ',c0
+ endif
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, SXvector, (nMonoEx+1)]
+ implicit none
+ BEGIN_DOC
+ ! Best eigenvector of the single-excitation matrix
+ END_DOC
+ integer :: i
+ double precision :: c0
+ c0=SXeigenvec(1,best_vector_ovrlp_casscf)
+ do i=1,nMonoEx+1
+ SXvector(i)=SXeigenvec(i,best_vector_ovrlp_casscf)/c0
+ end do
+ END_PROVIDER
+
+
+BEGIN_PROVIDER [double precision, NewOrbs, (ao_num,mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! Updated orbitals
+ END_DOC
+ integer :: i,j,ialph
+
+ if(state_following_casscf)then
+ print*,'Using the state following casscf '
+ call dgemm('N','T', ao_num,mo_num,mo_num,1.d0, &
+ NatOrbsFCI, size(NatOrbsFCI,1), &
+ Umat, size(Umat,1), 0.d0, &
+ NewOrbs, size(NewOrbs,1))
+
+ level_shift_casscf *= 0.5D0
+ level_shift_casscf = max(level_shift_casscf,0.002d0)
+ !touch level_shift_casscf
+ else
+ if(best_vector_ovrlp_casscf.ne.1.and.n_orb_swap.ne.0)then
+ print*,'Taking the lowest root for the CASSCF'
+ print*,'!!! SWAPPING MOS !!!!!!'
+ level_shift_casscf *= 2.D0
+ level_shift_casscf = min(level_shift_casscf,0.5d0)
+ print*,'level_shift_casscf = ',level_shift_casscf
+ NewOrbs = switch_mo_coef
+ !mo_coef = switch_mo_coef
+ !soft_touch mo_coef
+ !call save_mos_no_occ
+ !stop
+ else
+ level_shift_casscf *= 0.5D0
+ level_shift_casscf = max(level_shift_casscf,0.002d0)
+ !touch level_shift_casscf
+ call dgemm('N','T', ao_num,mo_num,mo_num,1.d0, &
+ NatOrbsFCI, size(NatOrbsFCI,1), &
+ Umat, size(Umat,1), 0.d0, &
+ NewOrbs, size(NewOrbs,1))
+ endif
+ endif
+
+END_PROVIDER
+
+BEGIN_PROVIDER [real*8, Umat, (mo_num,mo_num) ]
+ implicit none
+ BEGIN_DOC
+ ! Orbital rotation matrix
+ END_DOC
+ integer :: i,j,indx,k,iter,t,a,ii,tt,aa
+ logical :: converged
+
+ real*8 :: Tpotmat (mo_num,mo_num), Tpotmat2 (mo_num,mo_num)
+ real*8 :: Tmat(mo_num,mo_num)
+ real*8 :: f
+
+ ! the orbital rotation matrix T
+ Tmat(:,:)=0.D0
+ indx=1
+ do i=1,n_core_inact_orb
+ ii=list_core_inact(i)
+ do t=1,n_act_orb
+ tt=list_act(t)
+ indx+=1
+ Tmat(ii,tt)= SXvector(indx)
+ Tmat(tt,ii)=-SXvector(indx)
+ end do
+ end do
+ do i=1,n_core_inact_orb
+ ii=list_core_inact(i)
+ do a=1,n_virt_orb
+ aa=list_virt(a)
+ indx+=1
+ Tmat(ii,aa)= SXvector(indx)
+ Tmat(aa,ii)=-SXvector(indx)
+ end do
+ end do
+ do t=1,n_act_orb
+ tt=list_act(t)
+ do a=1,n_virt_orb
+ aa=list_virt(a)
+ indx+=1
+ Tmat(tt,aa)= SXvector(indx)
+ Tmat(aa,tt)=-SXvector(indx)
+ end do
+ end do
+
+ ! Form the exponential
+
+ Tpotmat(:,:)=0.D0
+ Umat(:,:) =0.D0
+ do i=1,mo_num
+ Tpotmat(i,i)=1.D0
+ Umat(i,i) =1.d0
+ end do
+ iter=0
+ converged=.false.
+ do while (.not.converged)
+ iter+=1
+ f = 1.d0 / dble(iter)
+ Tpotmat2(:,:) = Tpotmat(:,:) * f
+ call dgemm('N','N', mo_num,mo_num,mo_num,1.d0, &
+ Tpotmat2, size(Tpotmat2,1), &
+ Tmat, size(Tmat,1), 0.d0, &
+ Tpotmat, size(Tpotmat,1))
+ Umat(:,:) = Umat(:,:) + Tpotmat(:,:)
+
+ converged = ( sum(abs(Tpotmat(:,:))) < 1.d-6).or.(iter>30)
+ end do
+END_PROVIDER
+
+
+
diff --git a/src/casscf/reorder_orb.irp.f b/src/casscf/reorder_orb.irp.f
new file mode 100644
index 00000000..3cb90522
--- /dev/null
+++ b/src/casscf/reorder_orb.irp.f
@@ -0,0 +1,70 @@
+subroutine reorder_orbitals_for_casscf
+ implicit none
+ BEGIN_DOC
+! routine that reorders the orbitals of the CASSCF in terms block of core, active and virtual
+ END_DOC
+ integer :: i,j,iorb
+ integer, allocatable :: iorder(:),array(:)
+ allocate(iorder(mo_num),array(mo_num))
+ do i = 1, n_core_orb
+ iorb = list_core(i)
+ array(iorb) = i
+ enddo
+
+ do i = 1, n_inact_orb
+ iorb = list_inact(i)
+ array(iorb) = mo_num + i
+ enddo
+
+ do i = 1, n_act_orb
+ iorb = list_act(i)
+ array(iorb) = 2 * mo_num + i
+ enddo
+
+ do i = 1, n_virt_orb
+ iorb = list_virt(i)
+ array(iorb) = 3 * mo_num + i
+ enddo
+
+ do i = 1, mo_num
+ iorder(i) = i
+ enddo
+ call isort(array,iorder,mo_num)
+ double precision, allocatable :: mo_coef_new(:,:)
+ allocate(mo_coef_new(ao_num,mo_num))
+ do i = 1, mo_num
+ mo_coef_new(:,i) = mo_coef(:,iorder(i))
+ enddo
+ mo_coef = mo_coef_new
+ touch mo_coef
+
+ list_core_reverse = 0
+ do i = 1, n_core_orb
+ list_core(i) = i
+ list_core_reverse(i) = i
+ mo_class(i) = "Core"
+ enddo
+
+ list_inact_reverse = 0
+ do i = 1, n_inact_orb
+ list_inact(i) = i + n_core_orb
+ list_inact_reverse(i+n_core_orb) = i
+ mo_class(i+n_core_orb) = "Inactive"
+ enddo
+
+ list_act_reverse = 0
+ do i = 1, n_act_orb
+ list_act(i) = n_core_inact_orb + i
+ list_act_reverse(n_core_inact_orb + i) = i
+ mo_class(n_core_inact_orb + i) = "Active"
+ enddo
+
+ list_virt_reverse = 0
+ do i = 1, n_virt_orb
+ list_virt(i) = n_core_inact_orb + n_act_orb + i
+ list_virt_reverse(n_core_inact_orb + n_act_orb + i) = i
+ mo_class(n_core_inact_orb + n_act_orb + i) = "Virtual"
+ enddo
+ touch list_core_reverse list_core list_inact list_inact_reverse list_act list_act_reverse list_virt list_virt_reverse
+
+end
diff --git a/src/casscf/save_energy.irp.f b/src/casscf/save_energy.irp.f
new file mode 100644
index 00000000..8729c5af
--- /dev/null
+++ b/src/casscf/save_energy.irp.f
@@ -0,0 +1,9 @@
+subroutine save_energy(E,pt2)
+ implicit none
+ BEGIN_DOC
+! Saves the energy in |EZFIO|.
+ END_DOC
+ double precision, intent(in) :: E(N_states), pt2(N_states)
+ call ezfio_set_casscf_energy(E(1:N_states))
+ call ezfio_set_casscf_energy_pt2(E(1:N_states)+pt2(1:N_states))
+end
diff --git a/src/casscf/superci_dm.irp.f b/src/casscf/superci_dm.irp.f
new file mode 100644
index 00000000..0aef222b
--- /dev/null
+++ b/src/casscf/superci_dm.irp.f
@@ -0,0 +1,207 @@
+ BEGIN_PROVIDER [double precision, super_ci_dm, (mo_num,mo_num)]
+ implicit none
+ BEGIN_DOC
+! density matrix of the super CI matrix, in the basis of NATURAL ORBITALS OF THE CASCI WF
+!
+! This is obtained from annex B of Roos et. al. Chemical Physics 48 (1980) 157-173
+!
+! WARNING ::: in the equation B3.d there is a TYPO with a forgotten MINUS SIGN (see variable mat_tmp_dm_super_ci )
+ END_DOC
+ super_ci_dm = 0.d0
+ integer :: i,j,iorb,jorb
+ integer :: a,aorb,b,borb
+ integer :: t,torb,v,vorb,u,uorb,x,xorb
+ double precision :: c0,ci
+ c0 = SXeigenvec(1,1)
+ ! equation B3.a of the annex B of Roos et. al. Chemical Physics 48 (1980) 157-173
+ ! loop over the core/inact
+ do i = 1, n_core_inact_orb
+ iorb = list_core_inact(i)
+ super_ci_dm(iorb,iorb) = 2.d0 ! first term of B3.a
+ ! loop over the core/inact
+ do j = 1, n_core_inact_orb
+ jorb = list_core_inact(j)
+ ! loop over the virtual
+ do a = 1, n_virt_orb
+ aorb = list_virt(a)
+ super_ci_dm(jorb,iorb) += -2.d0 * lowest_super_ci_coef_mo(aorb,iorb) * lowest_super_ci_coef_mo(aorb,jorb) ! second term in B3.a
+ enddo
+ do t = 1, n_act_orb
+ torb = list_act(t)
+ ! thrid term of the B3.a
+ super_ci_dm(jorb,iorb) += - lowest_super_ci_coef_mo(iorb,torb) * lowest_super_ci_coef_mo(jorb,torb) * (2.d0 - occ_act(t))
+ enddo
+ enddo
+ enddo
+
+ ! equation B3.b of the annex B of Roos et. al. Chemical Physics 48 (1980) 157-173
+ do i = 1, n_core_inact_orb
+ iorb = list_core_inact(i)
+ do t = 1, n_act_orb
+ torb = list_act(t)
+ super_ci_dm(iorb,torb) = c0 * lowest_super_ci_coef_mo(torb,iorb) * (2.d0 - occ_act(t))
+ super_ci_dm(torb,iorb) = c0 * lowest_super_ci_coef_mo(torb,iorb) * (2.d0 - occ_act(t))
+ do a = 1, n_virt_orb
+ aorb = list_virt(a)
+ super_ci_dm(iorb,torb) += - lowest_super_ci_coef_mo(aorb,iorb) * lowest_super_ci_coef_mo(aorb,torb) * occ_act(t)
+ super_ci_dm(torb,iorb) += - lowest_super_ci_coef_mo(aorb,iorb) * lowest_super_ci_coef_mo(aorb,torb) * occ_act(t)
+ enddo
+ enddo
+ enddo
+
+ ! equation B3.c of the annex B of Roos et. al. Chemical Physics 48 (1980) 157-173
+ do i = 1, n_core_inact_orb
+ iorb = list_core_inact(i)
+ do a = 1, n_virt_orb
+ aorb = list_virt(a)
+ super_ci_dm(aorb,iorb) = 2.d0 * c0 * lowest_super_ci_coef_mo(aorb,iorb)
+ super_ci_dm(iorb,aorb) = 2.d0 * c0 * lowest_super_ci_coef_mo(aorb,iorb)
+ enddo
+ enddo
+
+ ! equation B3.d of the annex B of Roos et. al. Chemical Physics 48 (1980) 157-173
+ do t = 1, n_act_orb
+ torb = list_act(t)
+ super_ci_dm(torb,torb) = occ_act(t) ! first term of equation B3.d
+ do x = 1, n_act_orb
+ xorb = list_act(x)
+ super_ci_dm(torb,torb) += - occ_act(x) * occ_act(t)* mat_tmp_dm_super_ci(x,x) ! second term involving the ONE-rdm
+ enddo
+ do u = 1, n_act_orb
+ uorb = list_act(u)
+
+ ! second term of equation B3.d
+ do x = 1, n_act_orb
+ xorb = list_act(x)
+ do v = 1, n_act_orb
+ vorb = list_act(v)
+ super_ci_dm(torb,uorb) += 2.d0 * P0tuvx_no(v,x,t,u) * mat_tmp_dm_super_ci(v,x) ! second term involving the TWO-rdm
+ enddo
+ enddo
+
+ ! third term of equation B3.d
+ do i = 1, n_core_inact_orb
+ iorb = list_core_inact(i)
+ super_ci_dm(torb,uorb) += lowest_super_ci_coef_mo(iorb,torb) * lowest_super_ci_coef_mo(iorb,uorb) * (2.d0 - occ_act(t) - occ_act(u))
+ enddo
+
+ enddo
+ enddo
+
+ ! equation B3.e of the annex B of Roos et. al. Chemical Physics 48 (1980) 157-173
+ do t = 1, n_act_orb
+ torb = list_act(t)
+ do a = 1, n_virt_orb
+ aorb = list_virt(a)
+ super_ci_dm(aorb,torb) += c0 * lowest_super_ci_coef_mo(aorb,torb) * occ_act(t)
+ super_ci_dm(torb,aorb) += c0 * lowest_super_ci_coef_mo(aorb,torb) * occ_act(t)
+ do i = 1, n_core_inact_orb
+ iorb = list_core_inact(i)
+ super_ci_dm(aorb,torb) += lowest_super_ci_coef_mo(iorb,aorb) * lowest_super_ci_coef_mo(iorb,torb) * (2.d0 - occ_act(t))
+ super_ci_dm(torb,aorb) += lowest_super_ci_coef_mo(iorb,aorb) * lowest_super_ci_coef_mo(iorb,torb) * (2.d0 - occ_act(t))
+ enddo
+ enddo
+ enddo
+
+ ! equation B3.f of the annex B of Roos et. al. Chemical Physics 48 (1980) 157-173
+ do a = 1, n_virt_orb
+ aorb = list_virt(a)
+ do b = 1, n_virt_orb
+ borb= list_virt(b)
+
+ ! First term of equation B3.f
+ do i = 1, n_core_inact_orb
+ iorb = list_core_inact(i)
+ super_ci_dm(borb,aorb) += 2.d0 * lowest_super_ci_coef_mo(iorb,aorb) * lowest_super_ci_coef_mo(iorb,borb)
+ enddo
+
+ ! Second term of equation B3.f
+ do t = 1, n_act_orb
+ torb = list_act(t)
+ super_ci_dm(borb,aorb) += lowest_super_ci_coef_mo(torb,aorb) * lowest_super_ci_coef_mo(torb,borb) * occ_act(t)
+ enddo
+ enddo
+ enddo
+
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, superci_natorb, (ao_num,mo_num)
+&BEGIN_PROVIDER [double precision, superci_nat_occ, (mo_num)
+ implicit none
+ call general_mo_coef_new_as_svd_vectors_of_mo_matrix_eig(super_ci_dm,mo_num,mo_num,mo_num,NatOrbsFCI,superci_nat_occ,superci_natorb)
+
+END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, mat_tmp_dm_super_ci, (n_act_orb,n_act_orb)]
+ implicit none
+ BEGIN_DOC
+ ! computation of the term in [ ] in the equation B3.d of Roos et. al. Chemical Physics 48 (1980) 157-173
+ !
+ ! !!!!! WARNING !!!!!! there is a TYPO: a MINUS SIGN SHOULD APPEAR in that term
+ END_DOC
+ integer :: a,aorb,i,iorb
+ integer :: x,xorb,v,vorb
+ mat_tmp_dm_super_ci = 0.d0
+ do v = 1, n_act_orb
+ vorb = list_act(v)
+ do x = 1, n_act_orb
+ xorb = list_act(x)
+ do a = 1, n_virt_orb
+ aorb = list_virt(a)
+ mat_tmp_dm_super_ci(x,v) += lowest_super_ci_coef_mo(aorb,vorb) * lowest_super_ci_coef_mo(aorb,xorb)
+ enddo
+ do i = 1, n_core_inact_orb
+ iorb = list_core_inact(i)
+ ! MARK THE MINUS SIGN HERE !!!!!!!!!!! BECAUSE OF TYPO IN THE ORIGINAL PAPER
+ mat_tmp_dm_super_ci(x,v) -= lowest_super_ci_coef_mo(iorb,vorb) * lowest_super_ci_coef_mo(iorb,xorb)
+ enddo
+ enddo
+ enddo
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, lowest_super_ci_coef_mo, (mo_num,mo_num)]
+ implicit none
+ integer :: i,j,iorb,jorb
+ integer :: a, aorb,t, torb
+ double precision :: sqrt2
+
+ sqrt2 = 1.d0/dsqrt(2.d0)
+ do i = 1, nMonoEx
+ iorb = excit(1,i)
+ jorb = excit(2,i)
+ lowest_super_ci_coef_mo(iorb,jorb) = SXeigenvec(i+1,1)
+ lowest_super_ci_coef_mo(jorb,iorb) = SXeigenvec(i+1,1)
+ enddo
+
+ ! a_{it} of the equation B.2 of Roos et. al. Chemical Physics 48 (1980) 157-173
+ do i = 1, n_core_inact_orb
+ iorb = list_core_inact(i)
+ do t = 1, n_act_orb
+ torb = list_act(t)
+ lowest_super_ci_coef_mo(torb,iorb) *= (2.d0 - occ_act(t))**(-0.5d0)
+ lowest_super_ci_coef_mo(iorb,torb) *= (2.d0 - occ_act(t))**(-0.5d0)
+ enddo
+ enddo
+
+ ! a_{ia} of the equation B.2 of Roos et. al. Chemical Physics 48 (1980) 157-173
+ do i = 1, n_core_inact_orb
+ iorb = list_core_inact(i)
+ do a = 1, n_virt_orb
+ aorb = list_virt(a)
+ lowest_super_ci_coef_mo(aorb,iorb) *= sqrt2
+ lowest_super_ci_coef_mo(iorb,aorb) *= sqrt2
+ enddo
+ enddo
+
+ ! a_{ta} of the equation B.2 of Roos et. al. Chemical Physics 48 (1980) 157-173
+ do a = 1, n_virt_orb
+ aorb = list_virt(a)
+ do t = 1, n_act_orb
+ torb = list_act(t)
+ lowest_super_ci_coef_mo(torb,aorb) *= occ_act(t)**(-0.5d0)
+ lowest_super_ci_coef_mo(aorb,torb) *= occ_act(t)**(-0.5d0)
+ enddo
+ enddo
+
+ END_PROVIDER
+
diff --git a/src/casscf/swap_orb.irp.f b/src/casscf/swap_orb.irp.f
new file mode 100644
index 00000000..5d442157
--- /dev/null
+++ b/src/casscf/swap_orb.irp.f
@@ -0,0 +1,132 @@
+ BEGIN_PROVIDER [double precision, SXvector_lowest, (nMonoEx)]
+ implicit none
+ integer :: i
+ do i=2,nMonoEx+1
+ SXvector_lowest(i-1)=SXeigenvec(i,1)
+ enddo
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, thresh_overlap_switch]
+ implicit none
+ thresh_overlap_switch = 0.5d0
+ END_PROVIDER
+
+ BEGIN_PROVIDER [integer, max_overlap, (nMonoEx)]
+&BEGIN_PROVIDER [integer, n_max_overlap]
+&BEGIN_PROVIDER [integer, dim_n_max_overlap]
+ implicit none
+ double precision, allocatable :: vec_tmp(:)
+ integer, allocatable :: iorder(:)
+ allocate(vec_tmp(nMonoEx),iorder(nMonoEx))
+ integer :: i
+ do i = 1, nMonoEx
+ iorder(i) = i
+ vec_tmp(i) = -dabs(SXvector_lowest(i))
+ enddo
+ call dsort(vec_tmp,iorder,nMonoEx)
+ n_max_overlap = 0
+ do i = 1, nMonoEx
+ if(dabs(vec_tmp(i)).gt.thresh_overlap_switch)then
+ n_max_overlap += 1
+ max_overlap(n_max_overlap) = iorder(i)
+ endif
+ enddo
+ dim_n_max_overlap = max(1,n_max_overlap)
+ END_PROVIDER
+
+ BEGIN_PROVIDER [integer, orb_swap, (2,dim_n_max_overlap)]
+&BEGIN_PROVIDER [integer, index_orb_swap, (dim_n_max_overlap)]
+&BEGIN_PROVIDER [integer, n_orb_swap ]
+ implicit none
+ use bitmasks ! you need to include the bitmasks_module.f90 features
+ integer :: i,imono,iorb,jorb,j
+ n_orb_swap = 0
+ do i = 1, n_max_overlap
+ imono = max_overlap(i)
+ iorb = excit(1,imono)
+ jorb = excit(2,imono)
+ if (excit_class(imono) == "c-a" .and.hessmat2(imono,imono).gt.0.d0)then ! core --> active rotation
+ n_orb_swap += 1
+ orb_swap(1,n_orb_swap) = iorb ! core
+ orb_swap(2,n_orb_swap) = jorb ! active
+ index_orb_swap(n_orb_swap) = imono
+ else if (excit_class(imono) == "a-v" .and.hessmat2(imono,imono).gt.0.d0)then ! active --> virtual rotation
+ n_orb_swap += 1
+ orb_swap(1,n_orb_swap) = jorb ! virtual
+ orb_swap(2,n_orb_swap) = iorb ! active
+ index_orb_swap(n_orb_swap) = imono
+ endif
+ enddo
+
+ integer,allocatable :: orb_swap_tmp(:,:)
+ allocate(orb_swap_tmp(2,dim_n_max_overlap))
+ do i = 1, n_orb_swap
+ orb_swap_tmp(1,i) = orb_swap(1,i)
+ orb_swap_tmp(2,i) = orb_swap(2,i)
+ enddo
+
+ integer(bit_kind), allocatable :: det_i(:),det_j(:)
+ allocate(det_i(N_int),det_j(N_int))
+ logical, allocatable :: good_orb_rot(:)
+ allocate(good_orb_rot(n_orb_swap))
+ integer, allocatable :: index_orb_swap_tmp(:)
+ allocate(index_orb_swap_tmp(dim_n_max_overlap))
+ index_orb_swap_tmp = index_orb_swap
+ good_orb_rot = .True.
+ integer :: icount,k
+ do i = 1, n_orb_swap
+ if(.not.good_orb_rot(i))cycle
+ det_i = 0_bit_kind
+ call set_bit_to_integer(orb_swap(1,i),det_i,N_int)
+ call set_bit_to_integer(orb_swap(2,i),det_i,N_int)
+ do j = i+1, n_orb_swap
+ det_j = 0_bit_kind
+ call set_bit_to_integer(orb_swap(1,j),det_j,N_int)
+ call set_bit_to_integer(orb_swap(2,j),det_j,N_int)
+ icount = 0
+ do k = 1, N_int
+ icount += popcnt(ior(det_i(k),det_j(k)))
+ enddo
+ if (icount.ne.4)then
+ good_orb_rot(i) = .False.
+ good_orb_rot(j) = .False.
+ exit
+ endif
+ enddo
+ enddo
+ icount = n_orb_swap
+ n_orb_swap = 0
+ do i = 1, icount
+ if(good_orb_rot(i))then
+ n_orb_swap += 1
+ index_orb_swap(n_orb_swap) = index_orb_swap_tmp(i)
+ orb_swap(1,n_orb_swap) = orb_swap_tmp(1,i)
+ orb_swap(2,n_orb_swap) = orb_swap_tmp(2,i)
+ endif
+ enddo
+
+ if(n_orb_swap.gt.0)then
+ print*,'n_orb_swap = ',n_orb_swap
+ endif
+ do i = 1, n_orb_swap
+ print*,'imono = ',index_orb_swap(i)
+ print*,orb_swap(1,i),'-->',orb_swap(2,i)
+ enddo
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, switch_mo_coef, (ao_num,mo_num)]
+ implicit none
+ integer :: i,j,iorb,jorb
+ switch_mo_coef = NatOrbsFCI
+ do i = 1, n_orb_swap
+ iorb = orb_swap(1,i)
+ jorb = orb_swap(2,i)
+ do j = 1, ao_num
+ switch_mo_coef(j,jorb) = NatOrbsFCI(j,iorb)
+ enddo
+ do j = 1, ao_num
+ switch_mo_coef(j,iorb) = NatOrbsFCI(j,jorb)
+ enddo
+ enddo
+
+ END_PROVIDER
diff --git a/src/casscf/test_pert_2rdm.irp.f b/src/casscf/test_pert_2rdm.irp.f
new file mode 100644
index 00000000..7c40de0f
--- /dev/null
+++ b/src/casscf/test_pert_2rdm.irp.f
@@ -0,0 +1,29 @@
+program test_pert_2rdm
+ implicit none
+ read_wf = .True.
+ touch read_wf
+!call get_pert_2rdm
+ integer :: i,j,k,l,ii,jj,kk,ll
+ double precision :: accu , get_two_e_integral, integral
+ accu = 0.d0
+ print*,'n_orb_pert_rdm = ',n_orb_pert_rdm
+ do ii = 1, n_orb_pert_rdm
+ i = list_orb_pert_rdm(ii)
+ do jj = 1, n_orb_pert_rdm
+ j = list_orb_pert_rdm(jj)
+ do kk = 1, n_orb_pert_rdm
+ k= list_orb_pert_rdm(kk)
+ do ll = 1, n_orb_pert_rdm
+ l = list_orb_pert_rdm(ll)
+ integral = get_two_e_integral(i,j,k,l,mo_integrals_map)
+! if(dabs(pert_2rdm_provider(ii,jj,kk,ll) * integral).gt.1.d-12)then
+! print*,i,j,k,l
+! print*,pert_2rdm_provider(ii,jj,kk,ll) * integral,pert_2rdm_provider(ii,jj,kk,ll), pert_2rdm_provider(ii,jj,kk,ll), integral
+! endif
+ accu += pert_2rdm_provider(ii,jj,kk,ll) * integral
+ enddo
+ enddo
+ enddo
+ enddo
+ print*,'accu = ',accu
+end
diff --git a/src/casscf/tot_en.irp.f b/src/casscf/tot_en.irp.f
new file mode 100644
index 00000000..1d70e087
--- /dev/null
+++ b/src/casscf/tot_en.irp.f
@@ -0,0 +1,101 @@
+ BEGIN_PROVIDER [real*8, etwo]
+&BEGIN_PROVIDER [real*8, eone]
+&BEGIN_PROVIDER [real*8, eone_bis]
+&BEGIN_PROVIDER [real*8, etwo_bis]
+&BEGIN_PROVIDER [real*8, etwo_ter]
+&BEGIN_PROVIDER [real*8, ecore]
+&BEGIN_PROVIDER [real*8, ecore_bis]
+ implicit none
+ integer :: t,u,v,x,i,ii,tt,uu,vv,xx,j,jj,t3,u3,v3,x3
+ real*8 :: e_one_all,e_two_all
+ e_one_all=0.D0
+ e_two_all=0.D0
+ do i=1,n_core_inact_orb
+ ii=list_core_inact(i)
+ e_one_all+=2.D0*mo_one_e_integrals(ii,ii)
+ do j=1,n_core_inact_orb
+ jj=list_core_inact(j)
+ e_two_all+=2.D0*bielec_PQxx(ii,ii,j,j)-bielec_PQxx(ii,jj,j,i)
+ end do
+ do t=1,n_act_orb
+ tt=list_act(t)
+ t3=t+n_core_inact_orb
+ do u=1,n_act_orb
+ uu=list_act(u)
+ u3=u+n_core_inact_orb
+ e_two_all+=D0tu(t,u)*(2.D0*bielec_PQxx(tt,uu,i,i) &
+ -bielec_PQxx(tt,ii,i,u3))
+ end do
+ end do
+ end do
+ do t=1,n_act_orb
+ tt=list_act(t)
+ do u=1,n_act_orb
+ uu=list_act(u)
+ e_one_all+=D0tu(t,u)*mo_one_e_integrals(tt,uu)
+ do v=1,n_act_orb
+ v3=v+n_core_inact_orb
+ do x=1,n_act_orb
+ x3=x+n_core_inact_orb
+ e_two_all +=P0tuvx(t,u,v,x)*bielec_PQxx(tt,uu,v3,x3)
+ end do
+ end do
+ end do
+ end do
+ ecore =nuclear_repulsion
+ ecore_bis=nuclear_repulsion
+ do i=1,n_core_inact_orb
+ ii=list_core_inact(i)
+ ecore +=2.D0*mo_one_e_integrals(ii,ii)
+ ecore_bis+=2.D0*mo_one_e_integrals(ii,ii)
+ do j=1,n_core_inact_orb
+ jj=list_core_inact(j)
+ ecore +=2.D0*bielec_PQxx(ii,ii,j,j)-bielec_PQxx(ii,jj,j,i)
+ ecore_bis+=2.D0*bielec_PxxQ(ii,i,j,jj)-bielec_PxxQ(ii,j,j,ii)
+ end do
+ end do
+ eone =0.D0
+ eone_bis=0.D0
+ etwo =0.D0
+ etwo_bis=0.D0
+ etwo_ter=0.D0
+ do t=1,n_act_orb
+ tt=list_act(t)
+ t3=t+n_core_inact_orb
+ do u=1,n_act_orb
+ uu=list_act(u)
+ u3=u+n_core_inact_orb
+ eone +=D0tu(t,u)*mo_one_e_integrals(tt,uu)
+ eone_bis+=D0tu(t,u)*mo_one_e_integrals(tt,uu)
+ do i=1,n_core_inact_orb
+ ii=list_core_inact(i)
+ eone +=D0tu(t,u)*(2.D0*bielec_PQxx(tt,uu,i,i) &
+ -bielec_PQxx(tt,ii,i,u3))
+ eone_bis+=D0tu(t,u)*(2.D0*bielec_PxxQ(tt,u3,i,ii) &
+ -bielec_PxxQ(tt,i,i,uu))
+ end do
+ do v=1,n_act_orb
+ vv=list_act(v)
+ v3=v+n_core_inact_orb
+ do x=1,n_act_orb
+ xx=list_act(x)
+ x3=x+n_core_inact_orb
+ real*8 :: h1,h2,h3
+ h1=bielec_PQxx(tt,uu,v3,x3)
+ h2=bielec_PxxQ(tt,u3,v3,xx)
+ h3=bielecCI(t,u,v,xx)
+ etwo +=P0tuvx(t,u,v,x)*h1
+ etwo_bis+=P0tuvx(t,u,v,x)*h2
+ etwo_ter+=P0tuvx(t,u,v,x)*h3
+ if ((h1.ne.h2).or.(h1.ne.h3)) then
+ write(6,9901) t,u,v,x,h1,h2,h3
+ 9901 format('aie: ',4I4,3E20.12)
+ end if
+ end do
+ end do
+ end do
+ end do
+
+END_PROVIDER
+
+
diff --git a/src/cipsi/EZFIO.cfg b/src/cipsi/EZFIO.cfg
new file mode 100644
index 00000000..5110b776
--- /dev/null
+++ b/src/cipsi/EZFIO.cfg
@@ -0,0 +1,5 @@
+[pert_2rdm]
+type: logical
+doc: If true, computes the one- and two-body rdms with perturbation theory
+interface: ezfio,provider,ocaml
+default: False
diff --git a/src/cipsi/NEED b/src/cipsi/NEED
index 0cab61d0..c9dc92c0 100644
--- a/src/cipsi/NEED
+++ b/src/cipsi/NEED
@@ -3,3 +3,4 @@ zmq
mpi
davidson_undressed
iterations
+two_body_rdm
diff --git a/src/cipsi/cipsi.irp.f b/src/cipsi/cipsi.irp.f
index 7e292d6e..ba922c49 100644
--- a/src/cipsi/cipsi.irp.f
+++ b/src/cipsi/cipsi.irp.f
@@ -13,6 +13,7 @@ subroutine run_cipsi
rss = memory_of_double(N_states)*4.d0
call check_mem(rss,irp_here)
+ N_iter = 1
allocate (pt2(N_states), zeros(N_states), rpt2(N_states), norm(N_states), variance(N_states))
double precision :: hf_energy_ref
diff --git a/src/cipsi/lock_2rdm.irp.f b/src/cipsi/lock_2rdm.irp.f
new file mode 100644
index 00000000..e69de29b
diff --git a/src/cipsi/pert_rdm_providers.irp.f b/src/cipsi/pert_rdm_providers.irp.f
new file mode 100644
index 00000000..e2917261
--- /dev/null
+++ b/src/cipsi/pert_rdm_providers.irp.f
@@ -0,0 +1,178 @@
+
+use bitmasks
+use omp_lib
+
+BEGIN_PROVIDER [ integer(omp_lock_kind), pert_2rdm_lock]
+ use f77_zmq
+ implicit none
+ call omp_init_lock(pert_2rdm_lock)
+END_PROVIDER
+
+BEGIN_PROVIDER [integer, n_orb_pert_rdm]
+ implicit none
+ n_orb_pert_rdm = n_act_orb
+END_PROVIDER
+
+BEGIN_PROVIDER [integer, list_orb_reverse_pert_rdm, (mo_num)]
+ implicit none
+ list_orb_reverse_pert_rdm = list_act_reverse
+
+END_PROVIDER
+
+BEGIN_PROVIDER [integer, list_orb_pert_rdm, (n_orb_pert_rdm)]
+ implicit none
+ list_orb_pert_rdm = list_act
+
+END_PROVIDER
+
+BEGIN_PROVIDER [double precision, pert_2rdm_provider, (n_orb_pert_rdm,n_orb_pert_rdm,n_orb_pert_rdm,n_orb_pert_rdm)]
+ implicit none
+ pert_2rdm_provider = 0.d0
+
+END_PROVIDER
+
+subroutine fill_buffer_double_rdm(i_generator, sp, h1, h2, bannedOrb, banned, fock_diag_tmp, E0, pt2, variance, norm, mat, buf, psi_det_connection, psi_coef_connection_reverse, n_det_connection)
+ use bitmasks
+ use selection_types
+ implicit none
+
+ integer, intent(in) :: n_det_connection
+ double precision, intent(in) :: psi_coef_connection_reverse(N_states,n_det_connection)
+ integer(bit_kind), intent(in) :: psi_det_connection(N_int,2,n_det_connection)
+ integer, intent(in) :: i_generator, sp, h1, h2
+ double precision, intent(in) :: mat(N_states, mo_num, mo_num)
+ logical, intent(in) :: bannedOrb(mo_num, 2), banned(mo_num, mo_num)
+ double precision, intent(in) :: fock_diag_tmp(mo_num)
+ double precision, intent(in) :: E0(N_states)
+ double precision, intent(inout) :: pt2(N_states)
+ double precision, intent(inout) :: variance(N_states)
+ double precision, intent(inout) :: norm(N_states)
+ type(selection_buffer), intent(inout) :: buf
+ logical :: ok
+ integer :: s1, s2, p1, p2, ib, j, istate
+ integer(bit_kind) :: mask(N_int, 2), det(N_int, 2)
+ double precision :: e_pert, delta_E, val, Hii, sum_e_pert, tmp, alpha_h_psi, coef(N_states)
+ double precision, external :: diag_H_mat_elem_fock
+ double precision :: E_shift
+
+ logical, external :: detEq
+ double precision, allocatable :: values(:)
+ integer, allocatable :: keys(:,:)
+ integer :: nkeys
+ integer :: sze_buff
+ sze_buff = 5 * mo_num ** 2
+ allocate(keys(4,sze_buff),values(sze_buff))
+ nkeys = 0
+ if(sp == 3) then
+ s1 = 1
+ s2 = 2
+ else
+ s1 = sp
+ s2 = sp
+ end if
+ call apply_holes(psi_det_generators(1,1,i_generator), s1, h1, s2, h2, mask, ok, N_int)
+ E_shift = 0.d0
+
+ if (h0_type == 'SOP') then
+ j = det_to_occ_pattern(i_generator)
+ E_shift = psi_det_Hii(i_generator) - psi_occ_pattern_Hii(j)
+ endif
+
+ do p1=1,mo_num
+ if(bannedOrb(p1, s1)) cycle
+ ib = 1
+ if(sp /= 3) ib = p1+1
+
+ do p2=ib,mo_num
+
+! -----
+! /!\ Generating only single excited determinants doesn't work because a
+! determinant generated by a single excitation may be doubly excited wrt
+! to a determinant of the future. In that case, the determinant will be
+! detected as already generated when generating in the future with a
+! double excitation.
+!
+! if (.not.do_singles) then
+! if ((h1 == p1) .or. (h2 == p2)) then
+! cycle
+! endif
+! endif
+!
+! if (.not.do_doubles) then
+! if ((h1 /= p1).and.(h2 /= p2)) then
+! cycle
+! endif
+! endif
+! -----
+
+ if(bannedOrb(p2, s2)) cycle
+ if(banned(p1,p2)) cycle
+
+
+ if( sum(abs(mat(1:N_states, p1, p2))) == 0d0) cycle
+ call apply_particles(mask, s1, p1, s2, p2, det, ok, N_int)
+
+ if (do_only_cas) then
+ integer, external :: number_of_holes, number_of_particles
+ if (number_of_particles(det)>0) then
+ cycle
+ endif
+ if (number_of_holes(det)>0) then
+ cycle
+ endif
+ endif
+
+ if (do_ddci) then
+ logical, external :: is_a_two_holes_two_particles
+ if (is_a_two_holes_two_particles(det)) then
+ cycle
+ endif
+ endif
+
+ if (do_only_1h1p) then
+ logical, external :: is_a_1h1p
+ if (.not.is_a_1h1p(det)) cycle
+ endif
+
+
+ Hii = diag_H_mat_elem_fock(psi_det_generators(1,1,i_generator),det,fock_diag_tmp,N_int)
+
+ sum_e_pert = 0d0
+ integer :: degree
+ call get_excitation_degree(det,HF_bitmask,degree,N_int)
+ if(degree == 2)cycle
+ do istate=1,N_states
+ delta_E = E0(istate) - Hii + E_shift
+ alpha_h_psi = mat(istate, p1, p2)
+ val = alpha_h_psi + alpha_h_psi
+ tmp = dsqrt(delta_E * delta_E + val * val)
+ if (delta_E < 0.d0) then
+ tmp = -tmp
+ endif
+ e_pert = 0.5d0 * (tmp - delta_E)
+ coef(istate) = e_pert / alpha_h_psi
+ print*,e_pert,coef,alpha_h_psi
+ pt2(istate) = pt2(istate) + e_pert
+ variance(istate) = variance(istate) + alpha_h_psi * alpha_h_psi
+ norm(istate) = norm(istate) + coef(istate) * coef(istate)
+
+ if (weight_selection /= 5) then
+ ! Energy selection
+ sum_e_pert = sum_e_pert + e_pert * selection_weight(istate)
+
+ else
+ ! Variance selection
+ sum_e_pert = sum_e_pert - alpha_h_psi * alpha_h_psi * selection_weight(istate)
+ endif
+ end do
+ call give_2rdm_pert_contrib(det,coef,psi_det_connection,psi_coef_connection_reverse,n_det_connection,nkeys,keys,values,sze_buff)
+
+ if(sum_e_pert <= buf%mini) then
+ call add_to_selection_buffer(buf, det, sum_e_pert)
+ end if
+ end do
+ end do
+ call update_keys_values(keys,values,nkeys,n_orb_pert_rdm,pert_2rdm_provider,pert_2rdm_lock)
+end
+
+
diff --git a/src/cipsi/pt2_stoch_routines.irp.f b/src/cipsi/pt2_stoch_routines.irp.f
index 9f891320..281b0c5d 100644
--- a/src/cipsi/pt2_stoch_routines.irp.f
+++ b/src/cipsi/pt2_stoch_routines.irp.f
@@ -77,6 +77,7 @@ logical function testTeethBuilding(minF, N)
tilde_cW(i) = tilde_cW(i-1) + tilde_w(i)
enddo
tilde_cW(:) = tilde_cW(:) + 1.d0
+ deallocate(tilde_w)
n0 = 0
testTeethBuilding = .false.
@@ -89,19 +90,19 @@ logical function testTeethBuilding(minF, N)
r = tilde_cW(n0 + minF)
Wt = (1d0 - u0) * f
if (dabs(Wt) <= 1.d-3) then
- return
+ exit
endif
if(Wt >= r - u0) then
testTeethBuilding = .true.
- return
+ exit
end if
n0 += 1
-! if(N_det_generators - n0 < minF * N) then
if(n0 > minFN) then
- return
+ exit
end if
end do
- stop "exited testTeethBuilding"
+ deallocate(tilde_cW)
+
end function
@@ -129,13 +130,13 @@ subroutine ZMQ_pt2(E, pt2,relative_error, error, variance, norm, N_in)
PROVIDE psi_bilinear_matrix_rows psi_det_sorted_order psi_bilinear_matrix_order
PROVIDE psi_bilinear_matrix_transp_rows_loc psi_bilinear_matrix_transp_columns
PROVIDE psi_bilinear_matrix_transp_order psi_selectors_coef_transp psi_det_sorted
- PROVIDE psi_det_hii N_generators_bitmask selection_weight pseudo_sym
+ PROVIDE psi_det_hii selection_weight pseudo_sym
if (h0_type == 'SOP') then
PROVIDE psi_occ_pattern_hii det_to_occ_pattern
endif
- if (N_det < max(4,N_states)) then
+ if (N_det <= max(4,N_states)) then
pt2=0.d0
variance=0.d0
norm=0.d0
@@ -156,7 +157,7 @@ subroutine ZMQ_pt2(E, pt2,relative_error, error, variance, norm, N_in)
do pt2_stoch_istate=1,N_states
state_average_weight(:) = 0.d0
state_average_weight(pt2_stoch_istate) = 1.d0
- TOUCH state_average_weight pt2_stoch_istate
+ TOUCH state_average_weight pt2_stoch_istate selection_weight
PROVIDE nproc pt2_F mo_two_e_integrals_in_map mo_one_e_integrals pt2_w
PROVIDE psi_selectors pt2_u pt2_J pt2_R
@@ -523,10 +524,24 @@ subroutine pt2_collector(zmq_socket_pull, E, relative_error, pt2, error, varianc
exit
else
call pull_pt2_results(zmq_socket_pull, index, eI_task, vI_task, nI_task, task_id, n_tasks, b2)
+ if(n_tasks > pt2_n_tasks_max)then
+ print*,'PB !!!'
+ print*,'If you see this, send an email to Anthony scemama with the following content'
+ print*,irp_here
+ print*,'n_tasks,pt2_n_tasks_max = ',n_tasks,pt2_n_tasks_max
+ stop -1
+ endif
if (zmq_delete_tasks_async_send(zmq_to_qp_run_socket,task_id,n_tasks,sending) == -1) then
stop 'PT2: Unable to delete tasks (send)'
endif
do i=1,n_tasks
+ if(index(i).gt.size(eI,2).or.index(i).lt.1)then
+ print*,'PB !!!'
+ print*,'If you see this, send an email to Anthony scemama with the following content'
+ print*,irp_here
+ print*,'i,index(i),size(ei,2) = ',i,index(i),size(ei,2)
+ stop -1
+ endif
eI(1:N_states, index(i)) += eI_task(1:N_states,i)
vI(1:N_states, index(i)) += vI_task(1:N_states,i)
nI(1:N_states, index(i)) += nI_task(1:N_states,i)
@@ -706,83 +721,95 @@ END_PROVIDER
- BEGIN_PROVIDER [ double precision, pt2_w, (N_det_generators) ]
-&BEGIN_PROVIDER [ double precision, pt2_cW, (0:N_det_generators) ]
-&BEGIN_PROVIDER [ double precision, pt2_W_T ]
-&BEGIN_PROVIDER [ double precision, pt2_u_0 ]
-&BEGIN_PROVIDER [ integer, pt2_n_0, (pt2_N_teeth+1) ]
- implicit none
- integer :: i, t
- double precision, allocatable :: tilde_w(:), tilde_cW(:)
- double precision :: r, tooth_width
- integer, external :: pt2_find_sample
+ BEGIN_PROVIDER [ double precision, pt2_w, (N_det_generators) ]
+&BEGIN_PROVIDER [ double precision, pt2_cW, (0:N_det_generators) ]
+&BEGIN_PROVIDER [ double precision, pt2_W_T ]
+&BEGIN_PROVIDER [ double precision, pt2_u_0 ]
+&BEGIN_PROVIDER [ integer, pt2_n_0, (pt2_N_teeth+1) ]
+ implicit none
+ integer :: i, t
+ double precision, allocatable :: tilde_w(:), tilde_cW(:)
+ double precision :: r, tooth_width
+ integer, external :: pt2_find_sample
+
+ double precision :: rss
+ double precision, external :: memory_of_double, memory_of_int
+ rss = memory_of_double(2*N_det_generators+1)
+ call check_mem(rss,irp_here)
+
+ if (N_det_generators == 1) then
+
+ pt2_w(1) = 1.d0
+ pt2_cw(1) = 1.d0
+ pt2_u_0 = 1.d0
+ pt2_W_T = 0.d0
+ pt2_n_0(1) = 0
+ pt2_n_0(2) = 1
+
+ else
+
+ allocate(tilde_w(N_det_generators), tilde_cW(0:N_det_generators))
+
+ tilde_cW(0) = 0d0
+
+ do i=1,N_det_generators
+ tilde_w(i) = psi_coef_sorted_gen(i,pt2_stoch_istate)**2 !+ 1.d-20
+ enddo
+
+ double precision :: norm
+ norm = 0.d0
+ do i=N_det_generators,1,-1
+ norm += tilde_w(i)
+ enddo
+
+ tilde_w(:) = tilde_w(:) / norm
+
+ tilde_cW(0) = -1.d0
+ do i=1,N_det_generators
+ tilde_cW(i) = tilde_cW(i-1) + tilde_w(i)
+ enddo
+ tilde_cW(:) = tilde_cW(:) + 1.d0
- double precision :: rss
- double precision, external :: memory_of_double, memory_of_int
- rss = memory_of_double(2*N_det_generators+1)
- call check_mem(rss,irp_here)
+ pt2_n_0(1) = 0
+ do
+ pt2_u_0 = tilde_cW(pt2_n_0(1))
+ r = tilde_cW(pt2_n_0(1) + pt2_minDetInFirstTeeth)
+ pt2_W_T = (1d0 - pt2_u_0) / dble(pt2_N_teeth)
+ if(pt2_W_T >= r - pt2_u_0) then
+ exit
+ end if
+ pt2_n_0(1) += 1
+ if(N_det_generators - pt2_n_0(1) < pt2_minDetInFirstTeeth * pt2_N_teeth) then
+ print *, "teeth building failed"
+ stop -1
+ end if
+ end do
+
+ do t=2, pt2_N_teeth
+ r = pt2_u_0 + pt2_W_T * dble(t-1)
+ pt2_n_0(t) = pt2_find_sample(r, tilde_cW)
+ end do
+ pt2_n_0(pt2_N_teeth+1) = N_det_generators
+
+ pt2_w(:pt2_n_0(1)) = tilde_w(:pt2_n_0(1))
+ do t=1, pt2_N_teeth
+ tooth_width = tilde_cW(pt2_n_0(t+1)) - tilde_cW(pt2_n_0(t))
+ if (tooth_width == 0.d0) then
+ tooth_width = sum(tilde_w(pt2_n_0(t):pt2_n_0(t+1)))
+ endif
+ ASSERT(tooth_width > 0.d0)
+ do i=pt2_n_0(t)+1, pt2_n_0(t+1)
+ pt2_w(i) = tilde_w(i) * pt2_W_T / tooth_width
+ end do
+ end do
+
+ pt2_cW(0) = 0d0
+ do i=1,N_det_generators
+ pt2_cW(i) = pt2_cW(i-1) + pt2_w(i)
+ end do
+ pt2_n_0(pt2_N_teeth+1) = N_det_generators
- allocate(tilde_w(N_det_generators), tilde_cW(0:N_det_generators))
-
- tilde_cW(0) = 0d0
-
- do i=1,N_det_generators
- tilde_w(i) = psi_coef_sorted_gen(i,pt2_stoch_istate)**2 !+ 1.d-20
- enddo
-
- double precision :: norm
- norm = 0.d0
- do i=N_det_generators,1,-1
- norm += tilde_w(i)
- enddo
-
- tilde_w(:) = tilde_w(:) / norm
-
- tilde_cW(0) = -1.d0
- do i=1,N_det_generators
- tilde_cW(i) = tilde_cW(i-1) + tilde_w(i)
- enddo
- tilde_cW(:) = tilde_cW(:) + 1.d0
-
- pt2_n_0(1) = 0
- do
- pt2_u_0 = tilde_cW(pt2_n_0(1))
- r = tilde_cW(pt2_n_0(1) + pt2_minDetInFirstTeeth)
- pt2_W_T = (1d0 - pt2_u_0) / dble(pt2_N_teeth)
- if(pt2_W_T >= r - pt2_u_0) then
- exit
- end if
- pt2_n_0(1) += 1
- if(N_det_generators - pt2_n_0(1) < pt2_minDetInFirstTeeth * pt2_N_teeth) then
- stop "teeth building failed"
- end if
- end do
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- do t=2, pt2_N_teeth
- r = pt2_u_0 + pt2_W_T * dble(t-1)
- pt2_n_0(t) = pt2_find_sample(r, tilde_cW)
- end do
- pt2_n_0(pt2_N_teeth+1) = N_det_generators
-
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- pt2_w(:pt2_n_0(1)) = tilde_w(:pt2_n_0(1))
- do t=1, pt2_N_teeth
- tooth_width = tilde_cW(pt2_n_0(t+1)) - tilde_cW(pt2_n_0(t))
- if (tooth_width == 0.d0) then
- tooth_width = sum(tilde_w(pt2_n_0(t):pt2_n_0(t+1)))
- endif
- ASSERT(tooth_width > 0.d0)
- do i=pt2_n_0(t)+1, pt2_n_0(t+1)
- pt2_w(i) = tilde_w(i) * pt2_W_T / tooth_width
- end do
- end do
-
- pt2_cW(0) = 0d0
- do i=1,N_det_generators
- pt2_cW(i) = pt2_cW(i-1) + pt2_w(i)
- end do
- pt2_n_0(pt2_N_teeth+1) = N_det_generators
+ endif
END_PROVIDER
diff --git a/src/cipsi/run_selection_slave.irp.f b/src/cipsi/run_selection_slave.irp.f
index 70ad543f..d9730d7f 100644
--- a/src/cipsi/run_selection_slave.irp.f
+++ b/src/cipsi/run_selection_slave.irp.f
@@ -61,7 +61,6 @@ subroutine run_selection_slave(thread,iproc,energy)
! Only first time
bsize = min(N, (elec_alpha_num * (mo_num-elec_alpha_num))**2)
call create_selection_buffer(bsize, bsize*2, buf)
-! call create_selection_buffer(N, N*2, buf2)
buffer_ready = .True.
else
ASSERT (N == buf%N)
diff --git a/src/cipsi/selection.irp.f b/src/cipsi/selection.irp.f
index df31bc39..3585940e 100644
--- a/src/cipsi/selection.irp.f
+++ b/src/cipsi/selection.irp.f
@@ -1,3 +1,4 @@
+
use bitmasks
BEGIN_PROVIDER [ double precision, pt2_match_weight, (N_states) ]
@@ -69,8 +70,6 @@ subroutine update_pt2_and_variance_weights(pt2, variance, norm, N_st)
variance_match_weight(k) = product(memo_variance(k,:))
enddo
- print *, '# PT2 weight ', real(pt2_match_weight(:),4)
- print *, '# var weight ', real(variance_match_weight(:),4)
SOFT_TOUCH pt2_match_weight variance_match_weight
end
@@ -84,7 +83,7 @@ BEGIN_PROVIDER [ double precision, selection_weight, (N_states) ]
case (0)
print *, 'Using input weights in selection'
- selection_weight(1:N_states) = state_average_weight(1:N_states)
+ selection_weight(1:N_states) = c0_weight(1:N_states) * state_average_weight(1:N_states)
case (1)
print *, 'Using 1/c_max^2 weight in selection'
@@ -93,20 +92,30 @@ BEGIN_PROVIDER [ double precision, selection_weight, (N_states) ]
case (2)
print *, 'Using pt2-matching weight in selection'
selection_weight(1:N_states) = c0_weight(1:N_states) * pt2_match_weight(1:N_states)
+ print *, '# PT2 weight ', real(pt2_match_weight(:),4)
case (3)
print *, 'Using variance-matching weight in selection'
selection_weight(1:N_states) = c0_weight(1:N_states) * variance_match_weight(1:N_states)
+ print *, '# var weight ', real(variance_match_weight(:),4)
case (4)
print *, 'Using variance- and pt2-matching weights in selection'
- selection_weight(1:N_states) = c0_weight(1:N_states) * variance_match_weight(1:N_states) * pt2_match_weight(1:N_states)
+ selection_weight(1:N_states) = c0_weight(1:N_states) * sqrt(variance_match_weight(1:N_states) * pt2_match_weight(1:N_states))
+ print *, '# PT2 weight ', real(pt2_match_weight(:),4)
+ print *, '# var weight ', real(variance_match_weight(:),4)
case (5)
print *, 'Using variance-matching weight in selection'
selection_weight(1:N_states) = c0_weight(1:N_states) * variance_match_weight(1:N_states)
+ print *, '# var weight ', real(variance_match_weight(:),4)
+
+ case (6)
+ print *, 'Using CI coefficient weight in selection'
+ selection_weight(1:N_states) = c0_weight(1:N_states)
end select
+ print *, '# Total weight ', real(selection_weight(:),4)
END_PROVIDER
@@ -164,15 +173,13 @@ subroutine select_connected(i_generator,E0,pt2,variance,norm,b,subset,csubset)
call build_fock_tmp(fock_diag_tmp,psi_det_generators(1,1,i_generator),N_int)
- do l=1,N_generators_bitmask
- do k=1,N_int
- hole_mask(k,1) = iand(generators_bitmask(k,1,s_hole,l), psi_det_generators(k,1,i_generator))
- hole_mask(k,2) = iand(generators_bitmask(k,2,s_hole,l), psi_det_generators(k,2,i_generator))
- particle_mask(k,1) = iand(generators_bitmask(k,1,s_part,l), not(psi_det_generators(k,1,i_generator)) )
- particle_mask(k,2) = iand(generators_bitmask(k,2,s_part,l), not(psi_det_generators(k,2,i_generator)) )
- enddo
- call select_singles_and_doubles(i_generator,hole_mask,particle_mask,fock_diag_tmp,E0,pt2,variance,norm,b,subset,csubset)
+ do k=1,N_int
+ hole_mask(k,1) = iand(generators_bitmask(k,1,s_hole), psi_det_generators(k,1,i_generator))
+ hole_mask(k,2) = iand(generators_bitmask(k,2,s_hole), psi_det_generators(k,2,i_generator))
+ particle_mask(k,1) = iand(generators_bitmask(k,1,s_part), not(psi_det_generators(k,1,i_generator)) )
+ particle_mask(k,2) = iand(generators_bitmask(k,2,s_part), not(psi_det_generators(k,2,i_generator)) )
enddo
+ call select_singles_and_doubles(i_generator,hole_mask,particle_mask,fock_diag_tmp,E0,pt2,variance,norm,b,subset,csubset)
deallocate(fock_diag_tmp)
end subroutine
@@ -248,6 +255,7 @@ subroutine select_singles_and_doubles(i_generator,hole_mask,particle_mask,fock_d
integer,allocatable :: tmp_array(:)
integer(bit_kind), allocatable :: minilist(:, :, :), fullminilist(:, :, :)
logical, allocatable :: banned(:,:,:), bannedOrb(:,:)
+ double precision, allocatable :: coef_fullminilist_rev(:,:)
double precision, allocatable :: mat(:,:,:)
@@ -338,6 +346,7 @@ subroutine select_singles_and_doubles(i_generator,hole_mask,particle_mask,fock_d
call isort(indices,iorder,nmax)
deallocate(iorder)
+ ! Start with 32 elements. Size will double along with the filtering.
allocate(preinteresting(0:32), prefullinteresting(0:32), &
interesting(0:32), fullinteresting(0:32))
preinteresting(:) = 0
@@ -469,7 +478,7 @@ subroutine select_singles_and_doubles(i_generator,hole_mask,particle_mask,fock_d
if (nt > 4) exit
endif
end do
- case default
+ case default
mobMask(1:N_int,1) = iand(negMask(1:N_int,1), psi_det_sorted(1:N_int,1,preinteresting(ii)))
mobMask(1:N_int,2) = iand(negMask(1:N_int,2), psi_det_sorted(1:N_int,2,preinteresting(ii)))
nt = 0
@@ -546,6 +555,14 @@ subroutine select_singles_and_doubles(i_generator,hole_mask,particle_mask,fock_d
allocate (fullminilist (N_int, 2, fullinteresting(0)), &
minilist (N_int, 2, interesting(0)) )
+ if(pert_2rdm)then
+ allocate(coef_fullminilist_rev(N_states,fullinteresting(0)))
+ do i=1,fullinteresting(0)
+ do j = 1, N_states
+ coef_fullminilist_rev(j,i) = psi_coef_sorted(fullinteresting(i),j)
+ enddo
+ enddo
+ endif
do i=1,fullinteresting(0)
fullminilist(1:N_int,1:2,i) = psi_det_sorted(1:N_int,1:2,fullinteresting(i))
enddo
@@ -597,12 +614,19 @@ subroutine select_singles_and_doubles(i_generator,hole_mask,particle_mask,fock_d
call splash_pq(mask, sp, minilist, i_generator, interesting(0), bannedOrb, banned, mat, interesting)
- call fill_buffer_double(i_generator, sp, h1, h2, bannedOrb, banned, fock_diag_tmp, E0, pt2, variance, norm, mat, buf)
+ if(.not.pert_2rdm)then
+ call fill_buffer_double(i_generator, sp, h1, h2, bannedOrb, banned, fock_diag_tmp, E0, pt2, variance, norm, mat, buf)
+ else
+ call fill_buffer_double_rdm(i_generator, sp, h1, h2, bannedOrb, banned, fock_diag_tmp, E0, pt2, variance, norm, mat, buf,fullminilist, coef_fullminilist_rev, fullinteresting(0))
+ endif
end if
enddo
if(s1 /= s2) monoBdo = .false.
enddo
deallocate(fullminilist,minilist)
+ if(pert_2rdm)then
+ deallocate(coef_fullminilist_rev)
+ endif
enddo
enddo
deallocate(preinteresting, prefullinteresting, interesting, fullinteresting)
@@ -628,11 +652,15 @@ subroutine fill_buffer_double(i_generator, sp, h1, h2, bannedOrb, banned, fock_d
logical :: ok
integer :: s1, s2, p1, p2, ib, j, istate
integer(bit_kind) :: mask(N_int, 2), det(N_int, 2)
- double precision :: e_pert, delta_E, val, Hii, sum_e_pert, tmp, alpha_h_psi, coef
+ double precision :: e_pert, delta_E, val, Hii, w, tmp, alpha_h_psi, coef
double precision, external :: diag_H_mat_elem_fock
double precision :: E_shift
logical, external :: detEq
+ double precision, allocatable :: values(:)
+ integer, allocatable :: keys(:,:)
+ integer :: nkeys
+
if(sp == 3) then
s1 = 1
@@ -683,6 +711,16 @@ subroutine fill_buffer_double(i_generator, sp, h1, h2, bannedOrb, banned, fock_d
if( sum(abs(mat(1:N_states, p1, p2))) == 0d0) cycle
call apply_particles(mask, s1, p1, s2, p2, det, ok, N_int)
+ if (do_only_cas) then
+ integer, external :: number_of_holes, number_of_particles
+ if (number_of_particles(det)>0) then
+ cycle
+ endif
+ if (number_of_holes(det)>0) then
+ cycle
+ endif
+ endif
+
if (do_ddci) then
logical, external :: is_a_two_holes_two_particles
if (is_a_two_holes_two_particles(det)) then
@@ -695,10 +733,14 @@ subroutine fill_buffer_double(i_generator, sp, h1, h2, bannedOrb, banned, fock_d
if (.not.is_a_1h1p(det)) cycle
endif
-
Hii = diag_H_mat_elem_fock(psi_det_generators(1,1,i_generator),det,fock_diag_tmp,N_int)
- sum_e_pert = 0d0
+ w = 0d0
+
+! integer(bit_kind) :: occ(N_int,2), n
+! call occ_pattern_of_det(det,occ,N_int)
+! call occ_pattern_to_dets_size(occ,n,elec_alpha_num,N_int)
+
do istate=1,N_states
delta_E = E0(istate) - Hii + E_shift
@@ -709,33 +751,63 @@ subroutine fill_buffer_double(i_generator, sp, h1, h2, bannedOrb, banned, fock_d
tmp = -tmp
endif
e_pert = 0.5d0 * (tmp - delta_E)
- coef = e_pert / alpha_h_psi
+ if (dabs(alpha_h_psi) > 1.d-4) then
+ coef = e_pert / alpha_h_psi
+ else
+ coef = alpha_h_psi / delta_E
+ endif
pt2(istate) = pt2(istate) + e_pert
variance(istate) = variance(istate) + alpha_h_psi * alpha_h_psi
norm(istate) = norm(istate) + coef * coef
- if (weight_selection /= 5) then
- ! Energy selection
- sum_e_pert = sum_e_pert + e_pert * selection_weight(istate)
- else
- ! Variance selection
- sum_e_pert = sum_e_pert - alpha_h_psi * alpha_h_psi * selection_weight(istate)
- endif
+!!!DEBUG
+! integer :: k
+! double precision :: alpha_h_psi_2,hij
+! alpha_h_psi_2 = 0.d0
+! do k = 1,N_det_selectors
+! call i_H_j(det,psi_selectors(1,1,k),N_int,hij)
+! alpha_h_psi_2 = alpha_h_psi_2 + psi_selectors_coef(k,istate) * hij
+! enddo
+! if(dabs(alpha_h_psi_2 - alpha_h_psi).gt.1.d-12)then
+! call debug_det(psi_det_generators(1,1,i_generator),N_int)
+! call debug_det(det,N_int)
+! print*,'alpha_h_psi,alpha_h_psi_2 = ',alpha_h_psi,alpha_h_psi_2
+! stop
+! endif
+!!!DEBUG
+
+ select case (weight_selection)
+
+ case(0:4)
+ ! Energy selection
+ w = w + e_pert * selection_weight(istate)
+
+ case(5)
+ ! Variance selection
+ w = w - alpha_h_psi * alpha_h_psi * selection_weight(istate)
+
+ case(6)
+ w = w - coef * coef * selection_weight(istate)
+
+ end select
end do
+
+
if(pseudo_sym)then
- if(dabs(mat(1, p1, p2)).lt.thresh_sym)then
- sum_e_pert = 10.d0
- endif
+ if(dabs(mat(1, p1, p2)).lt.thresh_sym)then
+ w = 0.d0
+ endif
endif
- if(sum_e_pert <= buf%mini) then
- call add_to_selection_buffer(buf, det, sum_e_pert)
+! w = dble(n) * w
+
+ if(w <= buf%mini) then
+ call add_to_selection_buffer(buf, det, w)
end if
end do
end do
end
-
subroutine splash_pq(mask, sp, det, i_gen, N_sel, bannedOrb, banned, mat, interesting)
use bitmasks
implicit none
@@ -814,10 +886,13 @@ subroutine splash_pq(mask, sp, det, i_gen, N_sel, bannedOrb, banned, mat, intere
call get_mask_phase(psi_det_sorted(1,1,interesting(i)), phasemask,N_int)
if(nt == 4) then
+! call get_d2_reference(det(1,1,i), phasemask, bannedOrb, banned, mat, mask, h, p, sp, psi_selectors_coef_transp(1, interesting(i)))
call get_d2(det(1,1,i), phasemask, bannedOrb, banned, mat, mask, h, p, sp, psi_selectors_coef_transp(1, interesting(i)))
else if(nt == 3) then
+! call get_d1_reference(det(1,1,i), phasemask, bannedOrb, banned, mat, mask, h, p, sp, psi_selectors_coef_transp(1, interesting(i)))
call get_d1(det(1,1,i), phasemask, bannedOrb, banned, mat, mask, h, p, sp, psi_selectors_coef_transp(1, interesting(i)))
else
+! call get_d0_reference(det(1,1,i), phasemask, bannedOrb, banned, mat, mask, h, p, sp, psi_selectors_coef_transp(1, interesting(i)))
call get_d0(det(1,1,i), phasemask, bannedOrb, banned, mat, mask, h, p, sp, psi_selectors_coef_transp(1, interesting(i)))
end if
else if(nt == 4) then
@@ -975,7 +1050,7 @@ subroutine get_d1(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
implicit none
integer(bit_kind), intent(in) :: mask(N_int, 2), gen(N_int, 2)
- integer(bit_kind), intent(in) :: phasemask(N_int,2)
+ integer(bit_kind), intent(in) :: phasemask(N_int,2)
logical, intent(in) :: bannedOrb(mo_num, 2), banned(mo_num, mo_num,2)
integer(bit_kind) :: det(N_int, 2)
double precision, intent(in) :: coefs(N_states)
@@ -1058,8 +1133,10 @@ subroutine get_d1(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
call get_mo_two_e_integrals(hfix,pfix,p2,mo_num,hij_cache(1,2),mo_integrals_map)
putj = p1
do puti=1,mo_num
+ if(lbanned(puti,mi)) cycle
!p1 fixed
- if(.not.(banned(putj,puti,bant).or.lbanned(puti,mi))) then
+ putj = p1
+ if(.not. banned(putj,puti,bant)) then
hij = hij_cache(puti,2)
if (hij /= 0.d0) then
hij = hij * get_phase_bi(phasemask, ma, mi, hfix, p2, puti, pfix, N_int)
@@ -1068,11 +1145,9 @@ subroutine get_d1(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
enddo
endif
end if
- enddo
-
- putj = p2
- do puti=1,mo_num
- if(.not.(banned(putj,puti,bant)).or.(lbanned(puti,mi))) then
+
+ putj = p2
+ if(.not. banned(putj,puti,bant)) then
hij = hij_cache(puti,1)
if (hij /= 0.d0) then
hij = hij * get_phase_bi(phasemask, ma, mi, hfix, p1, puti, pfix, N_int)
@@ -1135,8 +1210,9 @@ subroutine get_d1(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
call get_mo_two_e_integrals(hfix,p2,pfix,mo_num,hij_cache(1,2),mo_integrals_map)
putj = p2
do puti=1,mo_num
+ if(lbanned(puti,ma)) cycle
+ putj = p2
if(.not. banned(puti,putj,1)) then
- if(lbanned(puti,ma)) cycle
hij = hij_cache(puti,1)
if (hij /= 0.d0) then
hij = hij * get_phase_bi(phasemask, mi, ma, hfix, pfix, puti, p1, N_int)
@@ -1145,12 +1221,9 @@ subroutine get_d1(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
enddo
endif
end if
- enddo
- putj = p1
- do puti=1,mo_num
+ putj = p1
if(.not. banned(puti,putj,1)) then
- if(lbanned(puti,ma)) cycle
hij = hij_cache(puti,2)
if (hij /= 0.d0) then
hij = hij * get_phase_bi(phasemask, mi, ma, hfix, pfix, puti, p2, N_int)
@@ -1179,12 +1252,11 @@ subroutine get_d1(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
do i1=1,p(0,s1)
ib = 1
- p1 = p(i1,s1)
if(s1 == s2) ib = i1+1
- if(bannedOrb(p1, s1)) cycle
do i2=ib,p(0,s2)
+ p1 = p(i1,s1)
p2 = p(i2,s2)
- if(bannedOrb(p2, s2) .or. banned(p1, p2, 1)) cycle
+ if(bannedOrb(p1, s1) .or. bannedOrb(p2, s2) .or. banned(p1, p2, 1)) cycle
call apply_particles(mask, s1, p1, s2, p2, det, ok, N_int)
call i_h_j(gen, det, N_int, hij)
mat(:, p1, p2) = mat(:, p1, p2) + coefs(:) * hij
@@ -1220,25 +1292,45 @@ subroutine get_d0(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
if(sp == 3) then ! AB
h1 = p(1,1)
h2 = p(1,2)
- do p2=1, mo_num
- if(bannedOrb(p2,2)) cycle
- call get_mo_two_e_integrals(p2,h1,h2,mo_num,hij_cache1,mo_integrals_map)
- do p1=1, mo_num
- if(bannedOrb(p1, 1) .or. banned(p1, p2, bant)) cycle
- if(p1 /= h1 .and. p2 /= h2) then
- if (hij_cache1(p1) == 0.d0) cycle
- phase = get_phase_bi(phasemask, 1, 2, h1, p1, h2, p2, N_int)
- hij = hij_cache1(p1) * phase
- else
+ do p1=1, mo_num
+ if(bannedOrb(p1, 1)) cycle
+ call get_mo_two_e_integrals(p1,h2,h1,mo_num,hij_cache1,mo_integrals_map)
+ do p2=1, mo_num
+ if(bannedOrb(p2,2)) cycle
+ if(banned(p1, p2, bant)) cycle ! rentable?
+ if(p1 == h1 .or. p2 == h2) then
call apply_particles(mask, 1,p1,2,p2, det, ok, N_int)
call i_h_j(gen, det, N_int, hij)
- if (hij == 0.d0) cycle
+ else
+ phase = get_phase_bi(phasemask, 1, 2, h1, p1, h2, p2, N_int)
+! hij = mo_two_e_integral(p2, p1, h2, h1) * phase
+ hij = hij_cache1(p2) * phase
end if
+ if (hij == 0.d0) cycle
do k=1,N_states
mat(k, p1, p2) = mat(k, p1, p2) + coefs(k) * hij ! HOTSPOT
enddo
end do
end do
+! do p2=1, mo_num
+! if(bannedOrb(p2,2)) cycle
+! call get_mo_two_e_integrals(p2,h1,h2,mo_num,hij_cache1,mo_integrals_map)
+! do p1=1, mo_num
+! if(bannedOrb(p1, 1) .or. banned(p1, p2, bant)) cycle
+! if(p1 /= h1 .and. p2 /= h2) then
+! if (hij_cache1(p1) == 0.d0) cycle
+! phase = get_phase_bi(phasemask, 1, 2, h1, p1, h2, p2, N_int)
+! hij = hij_cache1(p1) * phase
+! else
+! call apply_particles(mask, 1,p1,2,p2, det, ok, N_int)
+! call i_h_j(gen, det, N_int, hij)
+! if (hij == 0.d0) cycle
+! end if
+! do k=1,N_states
+! mat(k, p1, p2) = mat(k, p1, p2) + coefs(k) * hij ! HOTSPOT
+! enddo
+! end do
+! end do
else ! AA BB
p1 = p(1,sp)
@@ -1248,24 +1340,36 @@ subroutine get_d0(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
call get_mo_two_e_integrals(puti,p2,p1,mo_num,hij_cache1,mo_integrals_map)
call get_mo_two_e_integrals(puti,p1,p2,mo_num,hij_cache2,mo_integrals_map)
do putj=puti+1, mo_num
- if(bannedOrb(putj, sp) .or. banned(putj, sp, bant)) cycle
- if(puti /= p1 .and. putj /= p2 .and. puti /= p2 .and. putj /= p1) then
- hij = hij_cache1(putj) - hij_cache2(putj)
- if (hij /= 0.d0) then
- hij = hij * get_phase_bi(phasemask, sp, sp, puti, p1 , putj, p2, N_int)
- do k=1,N_states
- mat(k, puti, putj) = mat(k, puti, putj) + coefs(k) * hij
- enddo
- endif
- else
+ if(bannedOrb(putj, sp)) cycle
+ if(banned(puti, putj, bant)) cycle ! rentable?
+ if(puti == p1 .or. putj == p2 .or. puti == p2 .or. putj == p1) then
call apply_particles(mask, sp,puti,sp,putj, det, ok, N_int)
call i_h_j(gen, det, N_int, hij)
- if (hij /= 0.d0) then
- do k=1,N_states
- mat(k, puti, putj) = mat(k, puti, putj) + coefs(k) * hij
- enddo
- endif
+ else
+ hij = (mo_two_e_integral(p1, p2, puti, putj) - mo_two_e_integral(p2, p1, puti, putj))* get_phase_bi(phasemask, sp, sp, puti, p1 , putj, p2, N_int)
end if
+ if (hij == 0.d0) cycle
+ do k=1,N_states
+ mat(k, puti, putj) = mat(k, puti, putj) + coefs(k) * hij
+ enddo
+! if(bannedOrb(putj, sp) .or. banned(putj, sp, bant)) cycle
+! if(puti /= p1 .and. putj /= p2 .and. puti /= p2 .and. putj /= p1) then
+! hij = hij_cache1(putj) - hij_cache2(putj)
+! if (hij /= 0.d0) then
+! hij = hij * get_phase_bi(phasemask, sp, sp, puti, p1 , putj, p2, N_int)
+! do k=1,N_states
+! mat(k, puti, putj) = mat(k, puti, putj) + coefs(k) * hij
+! enddo
+! endif
+! else
+! call apply_particles(mask, sp,puti,sp,putj, det, ok, N_int)
+! call i_h_j(gen, det, N_int, hij)
+! if (hij /= 0.d0) then
+! do k=1,N_states
+! mat(k, puti, putj) = mat(k, puti, putj) + coefs(k) * hij
+! enddo
+! endif
+! end if
end do
end do
end if
@@ -1395,3 +1499,356 @@ subroutine bitstring_to_list_in_selection( string, list, n_elements, Nint)
end
!
+
+
+
+
+! OLD unoptimized routines for debugging
+! ======================================
+
+subroutine get_d0_reference(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
+ use bitmasks
+ implicit none
+
+ integer(bit_kind), intent(in) :: gen(N_int, 2), mask(N_int, 2)
+ integer(bit_kind), intent(in) :: phasemask(N_int,2)
+ logical, intent(in) :: bannedOrb(mo_num, 2), banned(mo_num, mo_num,2)
+ integer(bit_kind) :: det(N_int, 2)
+ double precision, intent(in) :: coefs(N_states)
+ double precision, intent(inout) :: mat(N_states, mo_num, mo_num)
+ integer, intent(in) :: h(0:2,2), p(0:4,2), sp
+
+ integer :: i, j, s, h1, h2, p1, p2, puti, putj
+ double precision :: hij, phase
+ double precision, external :: get_phase_bi, mo_two_e_integral
+ logical :: ok
+
+ integer :: bant
+ bant = 1
+
+
+ if(sp == 3) then ! AB
+ h1 = p(1,1)
+ h2 = p(1,2)
+ do p1=1, mo_num
+ if(bannedOrb(p1, 1)) cycle
+ do p2=1, mo_num
+ if(bannedOrb(p2,2)) cycle
+ if(banned(p1, p2, bant)) cycle ! rentable?
+ if(p1 == h1 .or. p2 == h2) then
+ call apply_particles(mask, 1,p1,2,p2, det, ok, N_int)
+ call i_h_j(gen, det, N_int, hij)
+ else
+ phase = get_phase_bi(phasemask, 1, 2, h1, p1, h2, p2, N_int)
+ hij = mo_two_e_integral(p1, p2, h1, h2) * phase
+ end if
+ mat(:, p1, p2) += coefs(:) * hij
+ end do
+ end do
+ else ! AA BB
+ p1 = p(1,sp)
+ p2 = p(2,sp)
+ do puti=1, mo_num
+ if(bannedOrb(puti, sp)) cycle
+ do putj=puti+1, mo_num
+ if(bannedOrb(putj, sp)) cycle
+ if(banned(puti, putj, bant)) cycle ! rentable?
+ if(puti == p1 .or. putj == p2 .or. puti == p2 .or. putj == p1) then
+ call apply_particles(mask, sp,puti,sp,putj, det, ok, N_int)
+ call i_h_j(gen, det, N_int, hij)
+ else
+ hij = (mo_two_e_integral(p1, p2, puti, putj) - mo_two_e_integral(p2, p1, puti, putj))* get_phase_bi(phasemask, sp, sp, puti, p1 , putj, p2, N_int)
+ end if
+ mat(:, puti, putj) += coefs(:) * hij
+ end do
+ end do
+ end if
+end
+
+subroutine get_d1_reference(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
+ use bitmasks
+ implicit none
+
+ integer(bit_kind), intent(in) :: mask(N_int, 2), gen(N_int, 2)
+ integer(bit_kind), intent(in) :: phasemask(N_int,2)
+ logical, intent(in) :: bannedOrb(mo_num, 2), banned(mo_num, mo_num,2)
+ integer(bit_kind) :: det(N_int, 2)
+ double precision, intent(in) :: coefs(N_states)
+ double precision, intent(inout) :: mat(N_states, mo_num, mo_num)
+ integer, intent(in) :: h(0:2,2), p(0:4,2), sp
+ double precision :: hij, tmp_row(N_states, mo_num), tmp_row2(N_states, mo_num)
+ double precision, external :: get_phase_bi, mo_two_e_integral
+ logical :: ok
+
+ logical, allocatable :: lbanned(:,:)
+ integer :: puti, putj, ma, mi, s1, s2, i, i1, i2, j
+ integer :: hfix, pfix, h1, h2, p1, p2, ib
+
+ integer, parameter :: turn2(2) = (/2,1/)
+ integer, parameter :: turn3(2,3) = reshape((/2,3, 1,3, 1,2/), (/2,3/))
+
+ integer :: bant
+
+
+ allocate (lbanned(mo_num, 2))
+ lbanned = bannedOrb
+
+ do i=1, p(0,1)
+ lbanned(p(i,1), 1) = .true.
+ end do
+ do i=1, p(0,2)
+ lbanned(p(i,2), 2) = .true.
+ end do
+
+ ma = 1
+ if(p(0,2) >= 2) ma = 2
+ mi = turn2(ma)
+
+ bant = 1
+
+ if(sp == 3) then
+ !move MA
+ if(ma == 2) bant = 2
+ puti = p(1,mi)
+ hfix = h(1,ma)
+ p1 = p(1,ma)
+ p2 = p(2,ma)
+ if(.not. bannedOrb(puti, mi)) then
+ tmp_row = 0d0
+ do putj=1, hfix-1
+ if(lbanned(putj, ma) .or. banned(putj, puti,bant)) cycle
+ hij = (mo_two_e_integral(p1, p2, putj, hfix)-mo_two_e_integral(p2,p1,putj,hfix)) * get_phase_bi(phasemask, ma, ma, putj, p1, hfix, p2, N_int)
+ tmp_row(1:N_states,putj) += hij * coefs(1:N_states)
+ end do
+ do putj=hfix+1, mo_num
+ if(lbanned(putj, ma) .or. banned(putj, puti,bant)) cycle
+ hij = (mo_two_e_integral(p1, p2, hfix, putj)-mo_two_e_integral(p2,p1,hfix,putj)) * get_phase_bi(phasemask, ma, ma, hfix, p1, putj, p2, N_int)
+ tmp_row(1:N_states,putj) += hij * coefs(1:N_states)
+ end do
+
+ if(ma == 1) then
+ mat(1:N_states,1:mo_num,puti) += tmp_row(1:N_states,1:mo_num)
+ else
+ mat(1:N_states,puti,1:mo_num) += tmp_row(1:N_states,1:mo_num)
+ end if
+ end if
+
+ !MOVE MI
+ pfix = p(1,mi)
+ tmp_row = 0d0
+ tmp_row2 = 0d0
+ do puti=1,mo_num
+ if(lbanned(puti,mi)) cycle
+ !p1 fixed
+ putj = p1
+ if(.not. banned(putj,puti,bant)) then
+ hij = mo_two_e_integral(p2,pfix,hfix,puti) * get_phase_bi(phasemask, ma, mi, hfix, p2, puti, pfix, N_int)
+ tmp_row(:,puti) += hij * coefs(:)
+ end if
+
+ putj = p2
+ if(.not. banned(putj,puti,bant)) then
+ hij = mo_two_e_integral(p1,pfix,hfix,puti) * get_phase_bi(phasemask, ma, mi, hfix, p1, puti, pfix, N_int)
+ tmp_row2(:,puti) += hij * coefs(:)
+ end if
+ end do
+
+ if(mi == 1) then
+ mat(:,:,p1) += tmp_row(:,:)
+ mat(:,:,p2) += tmp_row2(:,:)
+ else
+ mat(:,p1,:) += tmp_row(:,:)
+ mat(:,p2,:) += tmp_row2(:,:)
+ end if
+ else
+ if(p(0,ma) == 3) then
+ do i=1,3
+ hfix = h(1,ma)
+ puti = p(i, ma)
+ p1 = p(turn3(1,i), ma)
+ p2 = p(turn3(2,i), ma)
+ tmp_row = 0d0
+ do putj=1,hfix-1
+ if(lbanned(putj,ma) .or. banned(puti,putj,1)) cycle
+ hij = (mo_two_e_integral(p1, p2, putj, hfix)-mo_two_e_integral(p2,p1,putj,hfix)) * get_phase_bi(phasemask, ma, ma, putj, p1, hfix, p2, N_int)
+ tmp_row(:,putj) += hij * coefs(:)
+ end do
+ do putj=hfix+1,mo_num
+ if(lbanned(putj,ma) .or. banned(puti,putj,1)) cycle
+ hij = (mo_two_e_integral(p1, p2, hfix, putj)-mo_two_e_integral(p2,p1,hfix,putj)) * get_phase_bi(phasemask, ma, ma, hfix, p1, putj, p2, N_int)
+ tmp_row(:,putj) += hij * coefs(:)
+ end do
+
+ mat(:, :puti-1, puti) += tmp_row(:,:puti-1)
+ mat(:, puti, puti:) += tmp_row(:,puti:)
+ end do
+ else
+ hfix = h(1,mi)
+ pfix = p(1,mi)
+ p1 = p(1,ma)
+ p2 = p(2,ma)
+ tmp_row = 0d0
+ tmp_row2 = 0d0
+ do puti=1,mo_num
+ if(lbanned(puti,ma)) cycle
+ putj = p2
+ if(.not. banned(puti,putj,1)) then
+ hij = mo_two_e_integral(pfix, p1, hfix, puti) * get_phase_bi(phasemask, mi, ma, hfix, pfix, puti, p1, N_int)
+ tmp_row(:,puti) += hij * coefs(:)
+ end if
+
+ putj = p1
+ if(.not. banned(puti,putj,1)) then
+ hij = mo_two_e_integral(pfix, p2, hfix, puti) * get_phase_bi(phasemask, mi, ma, hfix, pfix, puti, p2, N_int)
+ tmp_row2(:,puti) += hij * coefs(:)
+ end if
+ end do
+ mat(:,:p2-1,p2) += tmp_row(:,:p2-1)
+ mat(:,p2,p2:) += tmp_row(:,p2:)
+ mat(:,:p1-1,p1) += tmp_row2(:,:p1-1)
+ mat(:,p1,p1:) += tmp_row2(:,p1:)
+ end if
+ end if
+ deallocate(lbanned)
+
+ !! MONO
+ if(sp == 3) then
+ s1 = 1
+ s2 = 2
+ else
+ s1 = sp
+ s2 = sp
+ end if
+
+ do i1=1,p(0,s1)
+ ib = 1
+ if(s1 == s2) ib = i1+1
+ do i2=ib,p(0,s2)
+ p1 = p(i1,s1)
+ p2 = p(i2,s2)
+ if(bannedOrb(p1, s1) .or. bannedOrb(p2, s2) .or. banned(p1, p2, 1)) cycle
+ call apply_particles(mask, s1, p1, s2, p2, det, ok, N_int)
+ call i_h_j(gen, det, N_int, hij)
+ mat(:, p1, p2) += coefs(:) * hij
+ end do
+ end do
+end
+
+subroutine get_d2_reference(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs)
+ use bitmasks
+ implicit none
+
+ integer(bit_kind), intent(in) :: mask(N_int, 2), gen(N_int, 2)
+ integer(bit_kind), intent(in) :: phasemask(2,N_int)
+ logical, intent(in) :: bannedOrb(mo_num, 2), banned(mo_num, mo_num,2)
+ double precision, intent(in) :: coefs(N_states)
+ double precision, intent(inout) :: mat(N_states, mo_num, mo_num)
+ integer, intent(in) :: h(0:2,2), p(0:4,2), sp
+
+ double precision, external :: get_phase_bi, mo_two_e_integral
+
+ integer :: i, j, tip, ma, mi, puti, putj
+ integer :: h1, h2, p1, p2, i1, i2
+ double precision :: hij, phase
+
+ integer, parameter:: turn2d(2,3,4) = reshape((/0,0, 0,0, 0,0, 3,4, 0,0, 0,0, 2,4, 1,4, 0,0, 2,3, 1,3, 1,2 /), (/2,3,4/))
+ integer, parameter :: turn2(2) = (/2, 1/)
+ integer, parameter :: turn3(2,3) = reshape((/2,3, 1,3, 1,2/), (/2,3/))
+
+ integer :: bant
+ bant = 1
+
+ tip = p(0,1) * p(0,2)
+
+ ma = sp
+ if(p(0,1) > p(0,2)) ma = 1
+ if(p(0,1) < p(0,2)) ma = 2
+ mi = mod(ma, 2) + 1
+
+ if(sp == 3) then
+ if(ma == 2) bant = 2
+
+ if(tip == 3) then
+ puti = p(1, mi)
+ do i = 1, 3
+ putj = p(i, ma)
+ if(banned(putj,puti,bant)) cycle
+ i1 = turn3(1,i)
+ i2 = turn3(2,i)
+ p1 = p(i1, ma)
+ p2 = p(i2, ma)
+ h1 = h(1, ma)
+ h2 = h(2, ma)
+
+ hij = (mo_two_e_integral(p1, p2, h1, h2) - mo_two_e_integral(p2,p1, h1, h2)) * get_phase_bi(phasemask, ma, ma, h1, p1, h2, p2, N_int)
+ if(ma == 1) then
+ mat(:, putj, puti) += coefs(:) * hij
+ else
+ mat(:, puti, putj) += coefs(:) * hij
+ end if
+ end do
+ else
+ h1 = h(1,1)
+ h2 = h(1,2)
+ do j = 1,2
+ putj = p(j, 2)
+ p2 = p(turn2(j), 2)
+ do i = 1,2
+ puti = p(i, 1)
+
+ if(banned(puti,putj,bant)) cycle
+ p1 = p(turn2(i), 1)
+
+ hij = mo_two_e_integral(p1, p2, h1, h2) * get_phase_bi(phasemask, 1, 2, h1, p1, h2, p2,N_int)
+ mat(:, puti, putj) += coefs(:) * hij
+ end do
+ end do
+ end if
+
+ else
+ if(tip == 0) then
+ h1 = h(1, ma)
+ h2 = h(2, ma)
+ do i=1,3
+ puti = p(i, ma)
+ do j=i+1,4
+ putj = p(j, ma)
+ if(banned(puti,putj,1)) cycle
+
+ i1 = turn2d(1, i, j)
+ i2 = turn2d(2, i, j)
+ p1 = p(i1, ma)
+ p2 = p(i2, ma)
+ hij = (mo_two_e_integral(p1, p2, h1, h2) - mo_two_e_integral(p2,p1, h1, h2)) * get_phase_bi(phasemask, ma, ma, h1, p1, h2, p2,N_int)
+ mat(:, puti, putj) += coefs(:) * hij
+ end do
+ end do
+ else if(tip == 3) then
+ h1 = h(1, mi)
+ h2 = h(1, ma)
+ p1 = p(1, mi)
+ do i=1,3
+ puti = p(turn3(1,i), ma)
+ putj = p(turn3(2,i), ma)
+ if(banned(puti,putj,1)) cycle
+ p2 = p(i, ma)
+
+ hij = mo_two_e_integral(p1, p2, h1, h2) * get_phase_bi(phasemask, mi, ma, h1, p1, h2, p2,N_int)
+ mat(:, min(puti, putj), max(puti, putj)) += coefs(:) * hij
+ end do
+ else ! tip == 4
+ puti = p(1, sp)
+ putj = p(2, sp)
+ if(.not. banned(puti,putj,1)) then
+ p1 = p(1, mi)
+ p2 = p(2, mi)
+ h1 = h(1, mi)
+ h2 = h(2, mi)
+ hij = (mo_two_e_integral(p1, p2, h1, h2) - mo_two_e_integral(p2,p1, h1, h2)) * get_phase_bi(phasemask, mi, mi, h1, p1, h2, p2,N_int)
+ mat(:, puti, putj) += coefs(:) * hij
+ end if
+ end if
+ end if
+end
+
+
diff --git a/src/cipsi/selection_buffer.irp.f b/src/cipsi/selection_buffer.irp.f
index 17b6e9a9..cfa3b902 100644
--- a/src/cipsi/selection_buffer.irp.f
+++ b/src/cipsi/selection_buffer.irp.f
@@ -198,6 +198,7 @@ subroutine make_selection_buffer_s2(b)
deallocate(b%det)
+ print*,'n_d = ',n_d
call i8sort(bit_tmp,iorder,n_d)
do i=1,n_d
diff --git a/src/cipsi/slave_cipsi.irp.f b/src/cipsi/slave_cipsi.irp.f
index 3e33dfa8..e9990986 100644
--- a/src/cipsi/slave_cipsi.irp.f
+++ b/src/cipsi/slave_cipsi.irp.f
@@ -117,8 +117,12 @@ subroutine run_slave_main
call mpi_print('zmq_get_dvector state_average_weight')
IRP_ENDIF
if (zmq_get_dvector(zmq_to_qp_run_socket,1,'state_average_weight',state_average_weight,N_states) == -1) cycle
+ IRP_IF MPI_DEBUG
+ call mpi_print('zmq_get_dvector selection_weight')
+ IRP_ENDIF
+ if (zmq_get_dvector(zmq_to_qp_run_socket,1,'selection_weight',selection_weight,N_states) == -1) cycle
pt2_e0_denominator(1:N_states) = energy(1:N_states)
- TOUCH pt2_e0_denominator state_average_weight threshold_generators
+ TOUCH pt2_e0_denominator state_average_weight threshold_generators selection_weight
if (mpi_master) then
print *, 'N_det', N_det
@@ -127,6 +131,7 @@ subroutine run_slave_main
print *, 'pt2_e0_denominator', pt2_e0_denominator
print *, 'pt2_stoch_istate', pt2_stoch_istate
print *, 'state_average_weight', state_average_weight
+ print *, 'selection_weight', selection_weight
endif
call wall_time(t1)
call write_double(6,(t1-t0),'Broadcast time')
diff --git a/src/cipsi/stochastic_cipsi.irp.f b/src/cipsi/stochastic_cipsi.irp.f
index ae2b7519..b8bf6a1d 100644
--- a/src/cipsi/stochastic_cipsi.irp.f
+++ b/src/cipsi/stochastic_cipsi.irp.f
@@ -10,8 +10,9 @@ subroutine run_stochastic_cipsi
double precision :: rss
double precision, external :: memory_of_double
- PROVIDE H_apply_buffer_allocated N_generators_bitmask
+ PROVIDE H_apply_buffer_allocated
+ N_iter = 1
threshold_generators = 1.d0
SOFT_TOUCH threshold_generators
@@ -101,7 +102,7 @@ subroutine run_stochastic_cipsi
! Add selected determinants
call copy_H_apply_buffer_to_wf()
- call save_wavefunction
+! call save_wavefunction
PROVIDE psi_coef
PROVIDE psi_det
diff --git a/src/cipsi/update_2rdm.irp.f b/src/cipsi/update_2rdm.irp.f
new file mode 100644
index 00000000..260c48fd
--- /dev/null
+++ b/src/cipsi/update_2rdm.irp.f
@@ -0,0 +1,223 @@
+use bitmasks
+
+subroutine give_2rdm_pert_contrib(det,coef,psi_det_connection,psi_coef_connection_reverse,n_det_connection,nkeys,keys,values,sze_buff)
+ implicit none
+ integer, intent(in) :: n_det_connection,sze_buff
+ double precision, intent(in) :: coef(N_states)
+ integer(bit_kind), intent(in) :: det(N_int,2)
+ integer(bit_kind), intent(in) :: psi_det_connection(N_int,2,n_det_connection)
+ double precision, intent(in) :: psi_coef_connection_reverse(N_states,n_det_connection)
+ integer, intent(inout) :: keys(4,sze_buff),nkeys
+ double precision, intent(inout) :: values(sze_buff)
+ integer :: i,j
+ integer :: exc(0:2,2,2)
+ integer :: degree
+ double precision :: phase, contrib
+ do i = 1, n_det_connection
+ call get_excitation(det,psi_det_connection(1,1,i),exc,degree,phase,N_int)
+ if(degree.gt.2)cycle
+ contrib = 0.d0
+ do j = 1, N_states
+ contrib += state_average_weight(j) * psi_coef_connection_reverse(j,i) * phase * coef(j)
+ enddo
+ ! case of single excitations
+ if(degree == 1)then
+ if (nkeys + 6 * elec_alpha_num .ge. sze_buff)then
+ call update_keys_values(keys,values,nkeys,n_orb_pert_rdm,pert_2rdm_provider,pert_2rdm_lock)
+ nkeys = 0
+ endif
+ call update_buffer_single_exc_rdm(det,psi_det_connection(1,1,i),exc,phase,contrib,nkeys,keys,values,sze_buff)
+ else
+ !! case of double excitations
+ ! if (nkeys + 4 .ge. sze_buff)then
+ ! call update_keys_values(keys,values,nkeys,n_orb_pert_rdm,pert_2rdm_provider,pert_2rdm_lock)
+ ! nkeys = 0
+ ! endif
+ ! call update_buffer_double_exc_rdm(exc,phase,contrib,nkeys,keys,values,sze_buff)
+ endif
+ enddo
+!call update_keys_values(keys,values,nkeys,n_orb_pert_rdm,pert_2rdm_provider,pert_2rdm_lock)
+!nkeys = 0
+
+end
+
+subroutine update_buffer_single_exc_rdm(det1,det2,exc,phase,contrib,nkeys,keys,values,sze_buff)
+ implicit none
+ integer, intent(in) :: sze_buff
+ integer(bit_kind), intent(in) :: det1(N_int,2)
+ integer(bit_kind), intent(in) :: det2(N_int,2)
+ integer,intent(in) :: exc(0:2,2,2)
+ double precision,intent(in) :: phase, contrib
+ integer, intent(inout) :: nkeys, keys(4,sze_buff)
+ double precision, intent(inout):: values(sze_buff)
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2),ispin,other_spin
+ integer :: h1,h2,p1,p2,i
+ call bitstring_to_list_ab(det1, occ, n_occ_ab, N_int)
+
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ p1 = exc(1,2,1)
+ ispin = 1
+ other_spin = 2
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ p1 = exc(1,2,2)
+ ispin = 2
+ other_spin = 1
+ endif
+ if(list_orb_reverse_pert_rdm(h1).lt.0)return
+ h1 = list_orb_reverse_pert_rdm(h1)
+ if(list_orb_reverse_pert_rdm(p1).lt.0)return
+ p1 = list_orb_reverse_pert_rdm(p1)
+ !update the alpha/beta part
+ do i = 1, n_occ_ab(other_spin)
+ h2 = occ(i,other_spin)
+ if(list_orb_reverse_pert_rdm(h2).lt.0)return
+ h2 = list_orb_reverse_pert_rdm(h2)
+
+ nkeys += 1
+ values(nkeys) = 0.5d0 * contrib * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = h2
+ nkeys += 1
+ values(nkeys) = 0.5d0 * contrib * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = p1
+ enddo
+ !update the same spin part
+!do i = 1, n_occ_ab(ispin)
+! h2 = occ(i,ispin)
+! if(list_orb_reverse_pert_rdm(h2).lt.0)return
+! h2 = list_orb_reverse_pert_rdm(h2)
+
+! nkeys += 1
+! values(nkeys) = 0.5d0 * contrib * phase
+! keys(1,nkeys) = h1
+! keys(2,nkeys) = h2
+! keys(3,nkeys) = p1
+! keys(4,nkeys) = h2
+
+! nkeys += 1
+! values(nkeys) = - 0.5d0 * contrib * phase
+! keys(1,nkeys) = h1
+! keys(2,nkeys) = h2
+! keys(3,nkeys) = h2
+! keys(4,nkeys) = p1
+!
+! nkeys += 1
+! values(nkeys) = 0.5d0 * contrib * phase
+! keys(1,nkeys) = h2
+! keys(2,nkeys) = h1
+! keys(3,nkeys) = h2
+! keys(4,nkeys) = p1
+
+! nkeys += 1
+! values(nkeys) = - 0.5d0 * contrib * phase
+! keys(1,nkeys) = h2
+! keys(2,nkeys) = h1
+! keys(3,nkeys) = p1
+! keys(4,nkeys) = h2
+!enddo
+
+end
+
+subroutine update_buffer_double_exc_rdm(exc,phase,contrib,nkeys,keys,values,sze_buff)
+ implicit none
+ integer, intent(in) :: sze_buff
+ integer,intent(in) :: exc(0:2,2,2)
+ double precision,intent(in) :: phase, contrib
+ integer, intent(inout) :: nkeys, keys(4,sze_buff)
+ double precision, intent(inout):: values(sze_buff)
+ integer :: h1,h2,p1,p2
+
+ if (exc(0,1,1) == 1) then
+ ! Double alpha/beta
+ h1 = exc(1,1,1)
+ h2 = exc(1,1,2)
+ p1 = exc(1,2,1)
+ p2 = exc(1,2,2)
+ ! check if the orbitals involved are within the orbital range
+ if(list_orb_reverse_pert_rdm(h1).lt.0)return
+ h1 = list_orb_reverse_pert_rdm(h1)
+ if(list_orb_reverse_pert_rdm(h2).lt.0)return
+ h2 = list_orb_reverse_pert_rdm(h2)
+ if(list_orb_reverse_pert_rdm(p1).lt.0)return
+ p1 = list_orb_reverse_pert_rdm(p1)
+ if(list_orb_reverse_pert_rdm(p2).lt.0)return
+ p2 = list_orb_reverse_pert_rdm(p2)
+ nkeys += 1
+ values(nkeys) = 0.5d0 * contrib * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = p2
+ nkeys += 1
+ values(nkeys) = 0.5d0 * contrib * phase
+ keys(1,nkeys) = p1
+ keys(2,nkeys) = p2
+ keys(3,nkeys) = h1
+ keys(4,nkeys) = h2
+
+ else
+ if (exc(0,1,1) == 2) then
+ ! Double alpha/alpha
+ h1 = exc(1,1,1)
+ h2 = exc(2,1,1)
+ p1 = exc(1,2,1)
+ p2 = exc(2,2,1)
+ else if (exc(0,1,2) == 2) then
+ ! Double beta
+ h1 = exc(1,1,2)
+ h2 = exc(2,1,2)
+ p1 = exc(1,2,2)
+ p2 = exc(2,2,2)
+ endif
+ ! check if the orbitals involved are within the orbital range
+ if(list_orb_reverse_pert_rdm(h1).lt.0)return
+ h1 = list_orb_reverse_pert_rdm(h1)
+ if(list_orb_reverse_pert_rdm(h2).lt.0)return
+ h2 = list_orb_reverse_pert_rdm(h2)
+ if(list_orb_reverse_pert_rdm(p1).lt.0)return
+ p1 = list_orb_reverse_pert_rdm(p1)
+ if(list_orb_reverse_pert_rdm(p2).lt.0)return
+ p2 = list_orb_reverse_pert_rdm(p2)
+ nkeys += 1
+ values(nkeys) = 0.5d0 * contrib * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = p2
+
+ nkeys += 1
+ values(nkeys) = - 0.5d0 * contrib * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p2
+ keys(4,nkeys) = p1
+
+ nkeys += 1
+ values(nkeys) = 0.5d0 * contrib * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = p2
+ keys(4,nkeys) = p1
+
+ nkeys += 1
+ values(nkeys) = - 0.5d0 * contrib * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = p2
+ endif
+
+end
+
+
diff --git a/src/cis/20.cis.bats b/src/cis/20.cis.bats
index 54eefe95..bcbff701 100644
--- a/src/cis/20.cis.bats
+++ b/src/cis/20.cis.bats
@@ -21,6 +21,11 @@ function run() {
eq $energy3 $4 $thresh
}
+@test "B-B" { # 2.0s
+ run b2_stretched.ezfio -48.995058575280950 -48.974653655601145 -48.974653655601031
+
+}
+
@test "SiH2_3B1" { # 1.23281s 1.24958s
run sih2_3b1.ezfio -289.969297318489 -289.766898643192 -289.737521023380
}
diff --git a/src/cisd/30.cisd.bats b/src/cisd/30.cisd.bats
index 5c9ac996..d17b45a0 100644
--- a/src/cisd/30.cisd.bats
+++ b/src/cisd/30.cisd.bats
@@ -18,6 +18,11 @@ function run() {
}
+@test "B-B" { #
+ qp set_file b2_stretched.ezfio
+ run -49.120607088648597 -49.055152453388231
+}
+
@test "SiH2_3B1" { # 1.53842s 3.53856s
qp set_file sih2_3b1.ezfio
run -290.015949171697 -289.805036176618
diff --git a/src/cisd/cisd.irp.f b/src/cisd/cisd.irp.f
index 65f943d3..4153c9a6 100644
--- a/src/cisd/cisd.irp.f
+++ b/src/cisd/cisd.irp.f
@@ -44,6 +44,7 @@ program cisd
! * "del" orbitals which will be never occupied
!
END_DOC
+ PROVIDE N_states
read_wf = .False.
SOFT_TOUCH read_wf
call run
@@ -51,29 +52,52 @@ end
subroutine run
implicit none
- integer :: i
+ integer :: i,k
+ double precision :: cisdq(N_states), delta_e
+ double precision,external :: diag_h_mat_elem
if(pseudo_sym)then
call H_apply_cisd_sym
else
call H_apply_cisd
endif
- print *, 'N_det = ', N_det
- print*,'******************************'
- print *, 'Energies of the states:'
- do i = 1,N_states
- print *, i, CI_energy(i)
- enddo
- if (N_states > 1) then
- print*,'******************************'
- print*,'Excitation energies '
- do i = 2, N_states
- print*, i ,CI_energy(i) - CI_energy(1)
- enddo
- endif
psi_coef = ci_eigenvectors
SOFT_TOUCH psi_coef
call save_wavefunction
call ezfio_set_cisd_energy(CI_energy)
+ do i = 1,N_states
+ k = maxloc(dabs(psi_coef_sorted(1:N_det,i)),dim=1)
+ delta_E = CI_electronic_energy(i) - diag_h_mat_elem(psi_det_sorted(1,1,k),N_int)
+ cisdq(i) = CI_energy(i) + delta_E * (1.d0 - psi_coef_sorted(k,i)**2)
+ enddo
+ print *, 'N_det = ', N_det
+ print*,''
+ print*,'******************************'
+ print *, 'CISD Energies'
+ do i = 1,N_states
+ print *, i, CI_energy(i)
+ enddo
+ print*,''
+ print*,'******************************'
+ print *, 'CISD+Q Energies'
+ do i = 1,N_states
+ print *, i, cisdq(i)
+ enddo
+ if (N_states > 1) then
+ print*,''
+ print*,'******************************'
+ print*,'Excitation energies (au) (CISD+Q)'
+ do i = 2, N_states
+ print*, i ,CI_energy(i) - CI_energy(1), cisdq(i) - cisdq(1)
+ enddo
+ print*,''
+ print*,'******************************'
+ print*,'Excitation energies (eV) (CISD+Q)'
+ do i = 2, N_states
+ print*, i ,(CI_energy(i) - CI_energy(1))/0.0367502d0, &
+ (cisdq(i) - cisdq(1)) / 0.0367502d0
+ enddo
+ endif
+
end
diff --git a/src/cisd/cisd_routine.irp.f b/src/cisd/cisd_routine.irp.f
new file mode 100644
index 00000000..93b31e7d
--- /dev/null
+++ b/src/cisd/cisd_routine.irp.f
@@ -0,0 +1,28 @@
+subroutine run_cisd
+ implicit none
+ integer :: i
+
+ if(pseudo_sym)then
+ call H_apply_cisd_sym
+ else
+ call H_apply_cisd
+ endif
+ print *, 'N_det = ', N_det
+ print*,'******************************'
+ print *, 'Energies of the states:'
+ do i = 1,N_states
+ print *, i, CI_energy(i)
+ enddo
+ if (N_states > 1) then
+ print*,'******************************'
+ print*,'Excitation energies '
+ do i = 2, N_states
+ print*, i ,CI_energy(i) - CI_energy(1)
+ enddo
+ endif
+ psi_coef = ci_eigenvectors
+ SOFT_TOUCH psi_coef
+ call save_wavefunction
+ call ezfio_set_cisd_energy(CI_energy)
+
+end
diff --git a/src/davidson/u0_wee_u0.irp.f b/src/davidson/u0_wee_u0.irp.f
index c1f163d4..0c543aca 100644
--- a/src/davidson/u0_wee_u0.irp.f
+++ b/src/davidson/u0_wee_u0.irp.f
@@ -6,7 +6,7 @@ BEGIN_PROVIDER [ double precision, psi_energy_two_e, (N_states) ]
integer :: i,j
call u_0_H_u_0_two_e(psi_energy_two_e,psi_coef,N_det,psi_det,N_int,N_states,psi_det_size)
do i=N_det+1,N_states
- psi_energy(i) = 0.d0
+ psi_energy_two_e(i) = 0.d0
enddo
END_PROVIDER
diff --git a/src/density_for_dft/density_for_dft.irp.f b/src/density_for_dft/density_for_dft.irp.f
index 4514f111..c925bdf8 100644
--- a/src/density_for_dft/density_for_dft.irp.f
+++ b/src/density_for_dft/density_for_dft.irp.f
@@ -106,12 +106,31 @@ END_PROVIDER
BEGIN_PROVIDER [double precision, one_e_dm_average_mo_for_dft, (mo_num,mo_num)]
implicit none
integer :: i
- one_e_dm_average_mo_for_dft = 0.d0
+ one_e_dm_average_mo_for_dft = one_e_dm_average_alpha_mo_for_dft + one_e_dm_average_beta_mo_for_dft
+END_PROVIDER
+
+
+BEGIN_PROVIDER [double precision, one_e_dm_average_alpha_mo_for_dft, (mo_num,mo_num)]
+ implicit none
+ integer :: i
+ one_e_dm_average_alpha_mo_for_dft = 0.d0
do i = 1, N_states
- one_e_dm_average_mo_for_dft(:,:) += one_e_dm_mo_for_dft(:,:,i) * state_average_weight(i)
+ one_e_dm_average_alpha_mo_for_dft(:,:) += one_e_dm_mo_alpha_for_dft(:,:,i) * state_average_weight(i)
enddo
END_PROVIDER
+
+BEGIN_PROVIDER [double precision, one_e_dm_average_beta_mo_for_dft, (mo_num,mo_num)]
+ implicit none
+ integer :: i
+ one_e_dm_average_beta_mo_for_dft = 0.d0
+ do i = 1, N_states
+ one_e_dm_average_beta_mo_for_dft(:,:) += one_e_dm_mo_beta_for_dft(:,:,i) * state_average_weight(i)
+ enddo
+END_PROVIDER
+
+
+
BEGIN_PROVIDER [ double precision, one_e_dm_alpha_ao_for_dft, (ao_num,ao_num,N_states) ]
&BEGIN_PROVIDER [ double precision, one_e_dm_beta_ao_for_dft, (ao_num,ao_num,N_states) ]
BEGIN_DOC
diff --git a/src/determinants/EZFIO.cfg b/src/determinants/EZFIO.cfg
index 93a91933..a8935695 100644
--- a/src/determinants/EZFIO.cfg
+++ b/src/determinants/EZFIO.cfg
@@ -22,6 +22,12 @@ doc: If |true|, read the wave function from the |EZFIO| file
interface: ezfio,provider,ocaml
default: False
+[pruning]
+type: float
+doc: If p>0., remove p*Ndet determinants at every iteration
+interface: ezfio,provider,ocaml
+default: 0.
+
[s2_eig]
type: logical
doc: Force the wave function to be an eigenfunction of |S^2|
@@ -32,11 +38,11 @@ default: True
type: integer
doc: Weight used in the calculation of the one-electron density matrix. 0: 1./(c_0^2), 1: 1/N_states, 2: input state-average weight, 3: 1/(Norm_L3(Psi))
interface: ezfio,provider,ocaml
-default: 1
+default: 2
[weight_selection]
type: integer
-doc: Weight used in the selection. 0: input state-average weight, 1: 1./(c_0^2), 2: rPT2 matching, 3: variance matching, 4: variance and rPT2 matching, 5: variance minimization and matching
+doc: Weight used in the selection. 0: input state-average weight, 1: 1./(c_0^2), 2: rPT2 matching, 3: variance matching, 4: variance and rPT2 matching, 5: variance minimization and matching, 6: CI coefficients
interface: ezfio,provider,ocaml
default: 2
diff --git a/src/determinants/density_matrix.irp.f b/src/determinants/density_matrix.irp.f
index a930d70b..e69a1803 100644
--- a/src/determinants/density_matrix.irp.f
+++ b/src/determinants/density_matrix.irp.f
@@ -257,6 +257,18 @@ subroutine set_natural_mos
double precision, allocatable :: tmp(:,:)
label = "Natural"
+ integer :: i,j,iorb,jorb
+ do i = 1, n_virt_orb
+ iorb = list_virt(i)
+ do j = 1, n_core_inact_act_orb
+ jorb = list_core_inact_act(j)
+ if(one_e_dm_mo(iorb,jorb).ne. 0.d0)then
+ print*,'AHAHAH'
+ print*,iorb,jorb,one_e_dm_mo(iorb,jorb)
+ stop
+ endif
+ enddo
+ enddo
call mo_as_svd_vectors_of_mo_matrix_eig(one_e_dm_mo,size(one_e_dm_mo,1),mo_num,mo_num,mo_occ,label)
soft_touch mo_occ
diff --git a/src/determinants/example.irp.f b/src/determinants/example.irp.f
index 4d5b6b55..4f56f807 100644
--- a/src/determinants/example.irp.f
+++ b/src/determinants/example.irp.f
@@ -151,7 +151,7 @@ subroutine routine_example_psi_det
print*,'Determinant connected'
call debug_det(psi_det(1,1,idx(i)),N_int)
print*,'excitation degree = ',degree_list(i)
- call i_H_j(psi_det(1,1,1) , psi_det(1,1,idx(i)),hij,N_int)
+ call i_H_j(psi_det(1,1,1) , psi_det(1,1,idx(i)),N_int,hij)
do j = 1, N_states
i_H_psi(j) += hij * psi_coef(idx(i),j)
enddo
diff --git a/src/determinants/h_apply.irp.f b/src/determinants/h_apply.irp.f
index f0d4d1c9..1c79bc75 100644
--- a/src/determinants/h_apply.irp.f
+++ b/src/determinants/h_apply.irp.f
@@ -124,39 +124,49 @@ subroutine copy_H_apply_buffer_to_wf
PROVIDE H_apply_buffer_allocated
+
ASSERT (N_int > 0)
ASSERT (N_det > 0)
allocate ( buffer_det(N_int,2,N_det), buffer_coef(N_det,N_states) )
+ ! Backup determinants
+ j=0
do i=1,N_det
- do k=1,N_int
- ASSERT (sum(popcnt(psi_det(:,1,i))) == elec_alpha_num)
- ASSERT (sum(popcnt(psi_det(:,2,i))) == elec_beta_num)
- buffer_det(k,1,i) = psi_det(k,1,i)
- buffer_det(k,2,i) = psi_det(k,2,i)
- enddo
+ if (pruned(i)) cycle ! Pruned determinants
+ j+=1
+ ASSERT (sum(popcnt(psi_det(:,1,i))) == elec_alpha_num)
+ ASSERT (sum(popcnt(psi_det(:,2,i))) == elec_beta_num)
+ buffer_det(:,:,j) = psi_det(:,:,i)
enddo
+ N_det_old = j
+
+ ! Backup coefficients
do k=1,N_states
+ j=0
do i=1,N_det
- buffer_coef(i,k) = psi_coef(i,k)
+ if (pruned(i)) cycle ! Pruned determinants
+ j += 1
+ buffer_coef(j,k) = psi_coef(i,k)
enddo
+ ASSERT ( j == N_det_old )
enddo
- N_det_old = N_det
+ ! Update N_det
+ N_det = N_det_old
do j=0,nproc-1
N_det = N_det + H_apply_buffer(j)%N_det
enddo
+ ! Update array sizes
if (psi_det_size < N_det) then
psi_det_size = N_det
TOUCH psi_det_size
endif
+
+ ! Restore backup in resized array
do i=1,N_det_old
- do k=1,N_int
- psi_det(k,1,i) = buffer_det(k,1,i)
- psi_det(k,2,i) = buffer_det(k,2,i)
- enddo
+ psi_det(:,:,i) = buffer_det(:,:,i)
ASSERT (sum(popcnt(psi_det(:,1,i))) == elec_alpha_num)
ASSERT (sum(popcnt(psi_det(:,2,i))) == elec_beta_num )
enddo
@@ -165,6 +175,9 @@ subroutine copy_H_apply_buffer_to_wf
psi_coef(i,k) = buffer_coef(i,k)
enddo
enddo
+
+ ! Copy new buffers
+
!$OMP PARALLEL DEFAULT(SHARED) &
!$OMP PRIVATE(j,k,i) FIRSTPRIVATE(N_det_old) &
!$OMP SHARED(N_int,H_apply_buffer,psi_det,psi_coef,N_states,psi_det_size)
diff --git a/src/determinants/h_apply_nozmq.template.f b/src/determinants/h_apply_nozmq.template.f
index fac838d0..bd261bbe 100644
--- a/src/determinants/h_apply_nozmq.template.f
+++ b/src/determinants/h_apply_nozmq.template.f
@@ -33,22 +33,22 @@ subroutine $subroutine($params_main)
do ispin=1,2
do k=1,N_int
mask(k,ispin,s_hole) = &
- iand(generators_bitmask(k,ispin,s_hole,i_bitmask_gen), &
+ iand(generators_bitmask(k,ispin,s_hole), &
psi_det_generators(k,ispin,i_generator) )
mask(k,ispin,s_part) = &
- iand(generators_bitmask(k,ispin,s_part,i_bitmask_gen), &
+ iand(generators_bitmask(k,ispin,s_part), &
not(psi_det_generators(k,ispin,i_generator)) )
mask(k,ispin,d_hole1) = &
- iand(generators_bitmask(k,ispin,d_hole1,i_bitmask_gen), &
+ iand(generators_bitmask(k,ispin,d_hole1), &
psi_det_generators(k,ispin,i_generator) )
mask(k,ispin,d_part1) = &
- iand(generators_bitmask(k,ispin,d_part1,i_bitmask_gen), &
+ iand(generators_bitmask(k,ispin,d_part1), &
not(psi_det_generators(k,ispin,i_generator)) )
mask(k,ispin,d_hole2) = &
- iand(generators_bitmask(k,ispin,d_hole2,i_bitmask_gen), &
+ iand(generators_bitmask(k,ispin,d_hole2), &
psi_det_generators(k,ispin,i_generator) )
mask(k,ispin,d_part2) = &
- iand(generators_bitmask(k,ispin,d_part2,i_bitmask_gen), &
+ iand(generators_bitmask(k,ispin,d_part2), &
not(psi_det_generators(k,ispin,i_generator)) )
enddo
enddo
diff --git a/src/determinants/occ_pattern.irp.f b/src/determinants/occ_pattern.irp.f
index 5f37b289..6e6f9c9f 100644
--- a/src/determinants/occ_pattern.irp.f
+++ b/src/determinants/occ_pattern.irp.f
@@ -409,6 +409,51 @@ BEGIN_PROVIDER [ double precision, weight_occ_pattern, (N_occ_pattern,N_states)
enddo
END_PROVIDER
+BEGIN_PROVIDER [ double precision, weight_occ_pattern_average, (N_occ_pattern) ]
+ implicit none
+ BEGIN_DOC
+ ! State-average weight of the occupation patterns in the wave function
+ END_DOC
+ integer :: i,j,k
+ weight_occ_pattern_average(:) = 0.d0
+ do i=1,N_det
+ j = det_to_occ_pattern(i)
+ do k=1,N_states
+ weight_occ_pattern_average(j) += psi_coef(i,k) * psi_coef(i,k) * state_average_weight(k)
+ enddo
+ enddo
+END_PROVIDER
+
+ BEGIN_PROVIDER [ double precision, psi_occ_pattern_sorted, (N_int,2,N_occ_pattern) ]
+&BEGIN_PROVIDER [ double precision, weight_occ_pattern_average_sorted, (N_occ_pattern) ]
+&BEGIN_PROVIDER [ integer, psi_occ_pattern_sorted_order, (N_occ_pattern) ]
+&BEGIN_PROVIDER [ integer, psi_occ_pattern_sorted_order_reverse, (N_occ_pattern) ]
+ implicit none
+ BEGIN_DOC
+ ! Occupation patterns sorted by weight
+ END_DOC
+ integer :: i,j,k
+ integer, allocatable :: iorder(:)
+ allocate ( iorder(N_occ_pattern) )
+ do i=1,N_occ_pattern
+ weight_occ_pattern_average_sorted(i) = -weight_occ_pattern_average(i)
+ iorder(i) = i
+ enddo
+ call dsort(weight_occ_pattern_average_sorted,iorder,N_occ_pattern)
+ do i=1,N_occ_pattern
+ do j=1,N_int
+ psi_occ_pattern_sorted(j,1,i) = psi_occ_pattern(j,1,iorder(i))
+ psi_occ_pattern_sorted(j,2,i) = psi_occ_pattern(j,2,iorder(i))
+ enddo
+ psi_occ_pattern_sorted_order(iorder(i)) = i
+ psi_occ_pattern_sorted_order_reverse(i) = iorder(i)
+ weight_occ_pattern_average_sorted(i) = -weight_occ_pattern_average_sorted(i)
+ enddo
+
+ deallocate(iorder)
+
+END_PROVIDER
+
subroutine make_s2_eigenfunction
implicit none
diff --git a/src/determinants/prune_wf.irp.f b/src/determinants/prune_wf.irp.f
new file mode 100644
index 00000000..c3cd8d12
--- /dev/null
+++ b/src/determinants/prune_wf.irp.f
@@ -0,0 +1,35 @@
+BEGIN_PROVIDER [ logical, pruned, (N_det) ]
+ implicit none
+ BEGIN_DOC
+ ! True if determinant is removed by pruning
+ END_DOC
+
+ pruned(:) = .False.
+
+ if (pruning == 0.d0) then
+ return
+ endif
+
+ integer :: i,j,k,ndet_new,nsop_max
+ double precision :: thr
+
+ if (s2_eig) then
+
+ nsop_max = max(1,int ( dble(N_occ_pattern) * (1.d0 - pruning) + 0.5d0 ))
+
+ do i=1,N_det
+ k = det_to_occ_pattern(i)
+ pruned(i) = psi_occ_pattern_sorted_order_reverse(k) > nsop_max
+ enddo
+
+ else
+
+ ndet_new = max(1,int( dble(N_det) * (1.d0 - pruning) + 0.5d0 ))
+ thr = psi_average_norm_contrib_sorted(ndet_new)
+ do i=1, N_det
+ pruned(i) = psi_average_norm_contrib(i) < thr
+ enddo
+
+ endif
+
+END_PROVIDER
diff --git a/src/determinants/psi_cas.irp.f b/src/determinants/psi_cas.irp.f
index 8698512f..19a1c260 100644
--- a/src/determinants/psi_cas.irp.f
+++ b/src/determinants/psi_cas.irp.f
@@ -16,19 +16,17 @@ use bitmasks
do l = 1, N_states
psi_cas_coef(i,l) = 0.d0
enddo
- do l=1,n_cas_bitmask
- good = .True.
- do k=1,N_int
- good = good .and. ( &
- iand(not(cas_bitmask(k,1,l)), psi_det(k,1,i)) == &
- iand(not(cas_bitmask(k,1,l)), hf_bitmask(k,1)) ) .and. ( &
- iand(not(cas_bitmask(k,2,l)), psi_det(k,2,i)) == &
- iand(not(cas_bitmask(k,2,l)), hf_bitmask(k,2)) )
- enddo
- if (good) then
- exit
- endif
+ good = .True.
+ do k=1,N_int
+ good = good .and. ( &
+ iand(not(act_bitmask(k,1)), psi_det(k,1,i)) == &
+ iand(not(act_bitmask(k,1)), hf_bitmask(k,1)) ) .and. ( &
+ iand(not(act_bitmask(k,2)), psi_det(k,2,i)) == &
+ iand(not(act_bitmask(k,2)), hf_bitmask(k,2)) )
enddo
+ if (good) then
+ exit
+ endif
if (good) then
N_det_cas = N_det_cas+1
do k=1,N_int
diff --git a/src/determinants/two_e_density_matrix.irp.pouet b/src/determinants/two_e_density_matrix.irp.pouet
new file mode 100644
index 00000000..7f8f4896
--- /dev/null
+++ b/src/determinants/two_e_density_matrix.irp.pouet
@@ -0,0 +1,609 @@
+
+ BEGIN_PROVIDER [double precision, two_bod_alpha_beta_mo, (mo_num,mo_num,mo_num,mo_num,N_states)]
+ implicit none
+ BEGIN_DOC
+ ! two_bod_alpha_beta(i,j,k,l) =
+ ! 1 1 2 2 = chemist notations
+ ! note that no 1/2 factor is introduced in order to take into acccount for the spin symmetry
+ !
+ END_DOC
+ integer :: dim1,dim2,dim3,dim4
+ double precision :: cpu_0,cpu_1
+ dim1 = mo_num
+ dim2 = mo_num
+ dim3 = mo_num
+ dim4 = mo_num
+ two_bod_alpha_beta_mo = 0.d0
+ print*,'providing two_bod_alpha_beta ...'
+ call wall_time(cpu_0)
+ call two_body_dm_nstates_openmp(two_bod_alpha_beta_mo,dim1,dim2,dim3,dim4,psi_coef,size(psi_coef,2),size(psi_coef,1))
+ call wall_time(cpu_1)
+ print*,'two_bod_alpha_beta provided in',dabs(cpu_1-cpu_0)
+
+ integer :: ii,jj,i,j,k,l
+ if(no_core_density .EQ. "no_core_dm")then
+ print*,'USING THE VALENCE ONLY TWO BODY DENSITY'
+
+ do ii = 1, n_core_orb ! 1
+ i = list_core(ii)
+ do j = 1, mo_num ! 2
+ do k = 1, mo_num ! 1
+ do l = 1, mo_num ! 2
+ ! 2 2 1 1
+ two_bod_alpha_beta_mo(l,j,k,i,:) = 0.d0
+ two_bod_alpha_beta_mo(j,l,k,i,:) = 0.d0
+ two_bod_alpha_beta_mo(l,j,i,k,:) = 0.d0
+ two_bod_alpha_beta_mo(j,l,i,k,:) = 0.d0
+
+ two_bod_alpha_beta_mo(k,i,l,j,:) = 0.d0
+ two_bod_alpha_beta_mo(k,i,j,l,:) = 0.d0
+ two_bod_alpha_beta_mo(i,k,l,j,:) = 0.d0
+ two_bod_alpha_beta_mo(i,k,j,l,:) = 0.d0
+ enddo
+ enddo
+ enddo
+ enddo
+
+
+ endif
+
+ END_PROVIDER
+
+
+ BEGIN_PROVIDER [double precision, two_bod_alpha_beta_mo_physicist, (mo_num,mo_num,mo_num,mo_num,N_states)]
+ implicit none
+ BEGIN_DOC
+ ! two_bod_alpha_beta_mo_physicist,(i,j,k,l) =
+ ! 1 2 1 2 = physicist notations
+ ! note that no 1/2 factor is introduced in order to take into acccount for the spin symmetry
+ !
+ END_DOC
+ integer :: i,j,k,l,istate
+ double precision :: cpu_0,cpu_1
+ two_bod_alpha_beta_mo_physicist = 0.d0
+ print*,'providing two_bod_alpha_beta_mo_physicist ...'
+ call wall_time(cpu_0)
+ do istate = 1, N_states
+ do i = 1, mo_num
+ do j = 1, mo_num
+ do k = 1, mo_num
+ do l = 1, mo_num
+ ! 1 2 1 2 1 1 2 2
+ two_bod_alpha_beta_mo_physicist(l,k,i,j,istate) = two_bod_alpha_beta_mo(i,l,j,k,istate)
+ enddo
+ enddo
+ enddo
+ enddo
+ enddo
+ call wall_time(cpu_1)
+ print*,'two_bod_alpha_beta_mo_physicist provided in',dabs(cpu_1-cpu_0)
+
+ END_PROVIDER
+
+
+ subroutine two_body_dm_nstates_openmp(big_array,dim1,dim2,dim3,dim4,u_0,N_st,sze)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes v_0 = H|u_0> and s_0 = S^2 |u_0>
+ !
+ ! Assumes that the determinants are in psi_det
+ !
+ ! istart, iend, ishift, istep are used in ZMQ parallelization.
+ END_DOC
+ integer, intent(in) :: N_st,sze
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: u_0(sze,N_st)
+ integer :: k
+ double precision, allocatable :: u_t(:,:)
+ !DIR$ ATTRIBUTES ALIGN : $IRP_ALIGN :: u_t
+ allocate(u_t(N_st,N_det))
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order,N_det)
+ enddo
+ call dtranspose( &
+ u_0, &
+ size(u_0, 1), &
+ u_t, &
+ size(u_t, 1), &
+ N_det, N_st)
+
+ call two_body_dm_nstates_openmp_work(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,1,N_det,0,1)
+ deallocate(u_t)
+
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order_reverse,N_det)
+ enddo
+
+ end
+
+
+ subroutine two_body_dm_nstates_openmp_work(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes v_0 = H|u_0> and s_0 = S^2 |u_0>
+ !
+ ! Default should be 1,N_det,0,1
+ END_DOC
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(in) :: u_t(N_st,N_det)
+
+
+ PROVIDE N_int
+
+ select case (N_int)
+ case (1)
+ call two_body_dm_nstates_openmp_work_1(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (2)
+ call two_body_dm_nstates_openmp_work_2(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (3)
+ call two_body_dm_nstates_openmp_work_3(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (4)
+ call two_body_dm_nstates_openmp_work_4(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case default
+ call two_body_dm_nstates_openmp_work_N_int(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ end select
+ end
+ BEGIN_TEMPLATE
+
+ subroutine two_body_dm_nstates_openmp_work_$N_int(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(in) :: u_t(N_st,N_det)
+
+ double precision :: hij, sij
+ integer :: i,j,k,l
+ integer :: k_a, k_b, l_a, l_b, m_a, m_b
+ integer :: istate
+ integer :: krow, kcol, krow_b, kcol_b
+ integer :: lrow, lcol
+ integer :: mrow, mcol
+ integer(bit_kind) :: spindet($N_int)
+ integer(bit_kind) :: tmp_det($N_int,2)
+ integer(bit_kind) :: tmp_det2($N_int,2)
+ integer(bit_kind) :: tmp_det3($N_int,2)
+ integer(bit_kind), allocatable :: buffer(:,:)
+ integer :: n_doubles
+ integer, allocatable :: doubles(:)
+ integer, allocatable :: singles_a(:)
+ integer, allocatable :: singles_b(:)
+ integer, allocatable :: idx(:), idx0(:)
+ integer :: maxab, n_singles_a, n_singles_b, kcol_prev, nmax
+ integer*8 :: k8
+
+ maxab = max(N_det_alpha_unique, N_det_beta_unique)+1
+ allocate(idx0(maxab))
+
+ do i=1,maxab
+ idx0(i) = i
+ enddo
+
+ ! Prepare the array of all alpha single excitations
+ ! -------------------------------------------------
+
+ PROVIDE N_int nthreads_davidson
+
+ ! Alpha/Beta double excitations
+ ! =============================
+
+ allocate( buffer($N_int,maxab), &
+ singles_a(maxab), &
+ singles_b(maxab), &
+ doubles(maxab), &
+ idx(maxab))
+
+ kcol_prev=-1
+
+ ASSERT (iend <= N_det)
+ ASSERT (istart > 0)
+ ASSERT (istep > 0)
+
+ do k_a=istart+ishift,iend,istep
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ if (kcol /= kcol_prev) then
+ call get_all_spin_singles_$N_int( &
+ psi_det_beta_unique, idx0, &
+ tmp_det(1,2), N_det_beta_unique, &
+ singles_b, n_singles_b)
+ endif
+ kcol_prev = kcol
+
+ ! Loop over singly excited beta columns
+ ! -------------------------------------
+
+ do i=1,n_singles_b
+ lcol = singles_b(i)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique(1:$N_int, lcol)
+
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ ASSERT (l_a <= N_det)
+
+ do j=1,psi_bilinear_matrix_columns_loc(lcol+1) - l_a
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,j) = psi_det_alpha_unique(1:$N_int, lrow)
+
+ ASSERT (l_a <= N_det)
+ idx(j) = l_a
+ l_a = l_a+1
+ enddo
+ j = j-1
+
+ call get_all_spin_singles_$N_int( &
+ buffer, idx, tmp_det(1,1), j, &
+ singles_a, n_singles_a )
+
+ ! Loop over alpha singles
+ ! -----------------------
+
+ do k = 1,n_singles_a
+ l_a = singles_a(k)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ !!!!!!!!!!!!!!!!!! ALPHA BETA
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ call off_diagonal_double_to_two_body_ab_dm(tmp_det,tmp_det2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ enddo
+
+ enddo
+
+ enddo
+
+
+ do k_a=istart+ishift,iend,istep
+
+
+ ! Single and double alpha excitations
+ ! ===================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! ----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,1)
+
+ ! Loop inside the beta column to gather all the connected alphas
+ lcol = psi_bilinear_matrix_columns(k_a)
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ do i=1,N_det_alpha_unique
+ if (l_a > N_det) exit
+ lcol = psi_bilinear_matrix_columns(l_a)
+ if (lcol /= kcol) exit
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,i) = psi_det_alpha_unique(1:$N_int, lrow)
+ idx(i) = l_a
+ l_a = l_a+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_a, doubles, n_singles_a, n_doubles )
+
+ ! Compute Hij for all alpha singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+ do i=1,n_singles_a
+ l_a = singles_a(i)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ !!!! MONO SPIN
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ call off_diagonal_single_to_two_body_ab_dm(tmp_det, tmp_det2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+
+ enddo
+
+
+ !! Compute Hij for all alpha doubles
+ !! ----------------------------------
+ !
+ !do i=1,n_doubles
+ ! l_a = doubles(i)
+ ! ASSERT (l_a <= N_det)
+
+ ! lrow = psi_bilinear_matrix_rows(l_a)
+ ! ASSERT (lrow <= N_det_alpha_unique)
+
+ ! call i_H_j_double_spin_erf( tmp_det(1,1), psi_det_alpha_unique(1, lrow), $N_int, hij)
+ ! do l=1,N_st
+ ! v_t(l,k_a) = v_t(l,k_a) + hij * u_t(l,l_a)
+ ! ! same spin => sij = 0
+ ! enddo
+ !enddo
+
+
+
+ ! Single and double beta excitations
+ ! ==================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ kcol = psi_bilinear_matrix_columns(k_a)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,2)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! -----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+
+ ! Loop inside the alpha row to gather all the connected betas
+ lrow = psi_bilinear_matrix_transp_rows(k_b)
+ l_b = psi_bilinear_matrix_transp_rows_loc(lrow)
+ do i=1,N_det_beta_unique
+ if (l_b > N_det) exit
+ lrow = psi_bilinear_matrix_transp_rows(l_b)
+ if (lrow /= krow) exit
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ buffer(1:$N_int,i) = psi_det_beta_unique(1:$N_int, lcol)
+ idx(i) = l_b
+ l_b = l_b+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_b, doubles, n_singles_b, n_doubles )
+
+ ! Compute Hij for all beta singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ do i=1,n_singles_b
+ l_b = singles_b(i)
+ ASSERT (l_b <= N_det)
+
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, lcol)
+ l_a = psi_bilinear_matrix_transp_order(l_b)
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ call off_diagonal_single_to_two_body_ab_dm(tmp_det, tmp_det2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ ASSERT (l_a <= N_det)
+ enddo
+ !
+ !! Compute Hij for all beta doubles
+ !! ----------------------------------
+ !
+ !do i=1,n_doubles
+ ! l_b = doubles(i)
+ ! ASSERT (l_b <= N_det)
+
+ ! lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ! ASSERT (lcol <= N_det_beta_unique)
+
+ ! call i_H_j_double_spin_erf( tmp_det(1,2), psi_det_beta_unique(1, lcol), $N_int, hij)
+ ! l_a = psi_bilinear_matrix_transp_order(l_b)
+ ! ASSERT (l_a <= N_det)
+
+ ! do l=1,N_st
+ ! v_t(l,k_a) = v_t(l,k_a) + hij * u_t(l,l_a)
+ ! ! same spin => sij = 0
+ ! enddo
+ !enddo
+
+
+ ! Diagonal contribution
+ ! =====================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ double precision, external :: diag_H_mat_elem_erf, diag_S_mat_elem
+ double precision :: c_1(N_states),c_2(N_states)
+ do l = 1, N_states
+ c_1(l) = u_t(l,k_a)
+ enddo
+
+ call diagonal_contrib_to_two_body_ab_dm(tmp_det,c_1,big_array,dim1,dim2,dim3,dim4)
+
+ end do
+ deallocate(buffer, singles_a, singles_b, doubles, idx)
+
+ end
+
+ SUBST [ N_int ]
+
+ 1;;
+ 2;;
+ 3;;
+ 4;;
+ N_int;;
+
+ END_TEMPLATE
+
+ subroutine diagonal_contrib_to_two_body_ab_dm(det_1,c_1,big_array,dim1,dim2,dim3,dim4)
+ use bitmasks
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int,2)
+ double precision, intent(in) :: c_1(N_states)
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate
+ double precision :: c_1_bis
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ do istate = 1, N_states
+ c_1_bis = c_1(istate) * c_1(istate)
+ do i = 1, n_occ_ab(1)
+ h1 = occ(i,1)
+ do j = 1, n_occ_ab(2)
+ h2 = occ(j,2)
+ big_array(h1,h1,h2,h2,istate) += c_1_bis
+ enddo
+ enddo
+ enddo
+ end
+
+ subroutine diagonal_contrib_to_all_two_body_dm(det_1,c_1,big_array_ab,big_array_aa,big_array_bb,dim1,dim2,dim3,dim4)
+ use bitmasks
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array_ab(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: big_array_aa(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: big_array_bb(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int,2)
+ double precision, intent(in) :: c_1(N_states)
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate
+ double precision :: c_1_bis
+ BEGIN_DOC
+! no factor 1/2 have to be taken into account as the permutations are already taken into account
+ END_DOC
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ do istate = 1, N_states
+ c_1_bis = c_1(istate) * c_1(istate)
+ do i = 1, n_occ_ab(1)
+ h1 = occ(i,1)
+ do j = 1, n_occ_ab(2)
+ h2 = occ(j,2)
+ big_array_ab(h1,h1,h2,h2,istate) += c_1_bis
+ enddo
+ do j = 1, n_occ_ab(1)
+ h2 = occ(j,1)
+ big_array_aa(h1,h2,h1,h2,istate) -= c_1_bis
+ big_array_aa(h1,h1,h2,h2,istate) += c_1_bis
+ enddo
+ enddo
+ do i = 1, n_occ_ab(2)
+ h1 = occ(i,2)
+ do j = 1, n_occ_ab(2)
+ h2 = occ(j,2)
+ big_array_bb(h1,h1,h2,h2,istate) += c_1_bis
+ big_array_bb(h1,h2,h1,h2,istate) -= c_1_bis
+ enddo
+ enddo
+ enddo
+ end
+
+
+ subroutine off_diagonal_double_to_two_body_ab_dm(det_1,det_2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ use bitmasks
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ double precision, intent(in) :: c_1(N_states),c_2(N_states)
+ integer :: i,j,h1,h2,p1,p2,istate
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ call get_double_excitation(det_1,det_2,exc,phase,N_int)
+ h1 = exc(1,1,1)
+ h2 = exc(1,1,2)
+ p1 = exc(1,2,1)
+ p2 = exc(1,2,2)
+ do istate = 1, N_states
+ big_array(h1,p1,h2,p2,istate) += c_1(istate) * phase * c_2(istate)
+! big_array(p1,h1,p2,h2,istate) += c_1(istate) * phase * c_2(istate)
+ enddo
+ end
+
+ subroutine off_diagonal_single_to_two_body_ab_dm(det_1,det_2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ use bitmasks
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ double precision, intent(in) :: c_1(N_states),c_2(N_states)
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ p1 = exc(1,2,1)
+ do istate = 1, N_states
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ big_array(h1,p1,h2,h2,istate) += 1.d0 * c_1(istate) * c_2(istate) * phase
+ enddo
+ enddo
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ p1 = exc(1,2,2)
+ do istate = 1, N_states
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ big_array(h2,h2,h1,p1,istate) += 1.d0 * c_1(istate) * c_2(istate) * phase
+ enddo
+ enddo
+ endif
+ end
diff --git a/src/dft_one_e/e_xc_general.irp.f b/src/dft_one_e/e_xc_general.irp.f
index dc8b9d9a..fc9f9fd2 100644
--- a/src/dft_one_e/e_xc_general.irp.f
+++ b/src/dft_one_e/e_xc_general.irp.f
@@ -15,7 +15,7 @@ prefix = ""
for f in functionals:
print """
%sif (trim(exchange_functional) == '%s') then
- energy_x = energy_x_%s"""%(prefix, f, f)
+ energy_x = (1.d0 - HF_exchange ) * energy_x_%s"""%(prefix, f, f)
prefix = "else "
print """
else
diff --git a/src/dft_one_e/pot_general.irp.f b/src/dft_one_e/pot_general.irp.f
index 237af8c0..2f45a464 100644
--- a/src/dft_one_e/pot_general.irp.f
+++ b/src/dft_one_e/pot_general.irp.f
@@ -17,8 +17,8 @@ prefix = ""
for f in functionals:
print """
%sif (trim(exchange_functional) == '%s') then
- potential_x_alpha_ao = potential_x_alpha_ao_%s
- potential_x_beta_ao = potential_x_beta_ao_%s"""%(prefix, f, f, f)
+ potential_x_alpha_ao = ( 1.d0 - HF_exchange ) * potential_x_alpha_ao_%s
+ potential_x_beta_ao = ( 1.d0 - HF_exchange ) * potential_x_beta_ao_%s"""%(prefix, f, f, f)
prefix = "else "
print """
else
diff --git a/src/dft_utils_in_r/mo_in_r.irp.f b/src/dft_utils_in_r/mo_in_r.irp.f
index 60cd59f2..bfcc8abb 100644
--- a/src/dft_utils_in_r/mo_in_r.irp.f
+++ b/src/dft_utils_in_r/mo_in_r.irp.f
@@ -32,6 +32,7 @@
! k = 1 : x, k= 2, y, k 3, z
END_DOC
integer :: m
+ print*,'mo_num,n_points_final_grid',mo_num,n_points_final_grid
mos_grad_in_r_array = 0.d0
do m=1,3
call dgemm('N','N',mo_num,n_points_final_grid,ao_num,1.d0,mo_coef_transp,mo_num,aos_grad_in_r_array(1,1,m),ao_num,0.d0,mos_grad_in_r_array(1,1,m),mo_num)
diff --git a/src/dft_utils_one_e/ec_lyp_2.irp.f b/src/dft_utils_one_e/ec_lyp_2.irp.f
new file mode 100644
index 00000000..e97a0e00
--- /dev/null
+++ b/src/dft_utils_one_e/ec_lyp_2.irp.f
@@ -0,0 +1,28 @@
+double precision function ec_lyp2(RhoA,RhoB,GA,GB,GAB)
+ include 'constants.include.F'
+ implicit none
+ double precision, intent(in) :: RhoA,RhoB,GA,GB,GAB
+ double precision :: Tol,caa,cab,cac,cad,cae,RA,RB,comega,cdelta,cLaa,cLbb,cLab,E
+ ec_lyp2 = 0.d0
+ Tol=1D-14
+ E=2.718281828459045D0
+ caa=0.04918D0
+ cab=0.132D0
+ cac=0.2533D0
+ cad=0.349D0
+ cae=(2D0**(11D0/3D0))*((3D0/10D0)*((3D0*(Pi**2D0))**(2D0/3D0)))
+
+
+ RA = MAX(RhoA,0D0)
+ RB = MAX(RhoB,0D0)
+ IF ((RA.gt.Tol).OR.(RB.gt.Tol)) THEN
+ IF ((RA.gt.Tol).AND.(RB.gt.Tol)) THEN
+ comega = 1D0/(E**(cac/(RA+RB)**(1D0/3D0))*(RA+RB)**(10D0/3D0)*(cad+(RA+RB)**(1D0/3D0)))
+ cdelta = (cac+cad+(cac*cad)/(RA+RB)**(1D0/3D0))/(cad+(RA+RB)**(1D0/3D0))
+ cLaa = (cab*comega*RB*(RA-3D0*cdelta*RA-9D0*RB-((-11D0+cdelta)*RA**2D0)/(RA+RB)))/9D0
+ cLbb = (cab*comega*RA*(-9D0*RA+(RB*(RA-3D0*cdelta*RA-4D0*(-3D0+cdelta)*RB))/(RA+RB)))/9D0
+ cLab = cab*comega*(((47D0-7D0*cdelta)*RA*RB)/9D0-(4D0*(RA+RB)**2D0)/3D0)
+ ec_lyp2 = -(caa*(cLaa*GA+cLab*GAB+cLbb*GB+cab*cae*comega*RA*RB*(RA**(8D0/3D0)+RB**(8D0/3D0))+(4D0*RA*RB)/(RA+RB+cad*(RA+RB)**(2D0/3D0))))
+ endif
+ endif
+end
diff --git a/src/dft_utils_one_e/ec_scan.irp.f b/src/dft_utils_one_e/ec_scan.irp.f
index 4807b89f..741129eb 100644
--- a/src/dft_utils_one_e/ec_scan.irp.f
+++ b/src/dft_utils_one_e/ec_scan.irp.f
@@ -37,7 +37,9 @@ double precision function ec_scan(rho_a,rho_b,tau,grad_rho_2)
gama = 0.031091d0
! correlation energy lsda1
call ec_only_lda_sr(0.d0,nup,ndo,e_c_lsda1)
-
+
+ ! correlation energy per particle
+ e_c_lsda1 = e_c_lsda1/rho
xi = spin_d/rho
rs = (cst_43 * pi * rho)**(-cst_13)
s = drho/( 2.d0 * cst_3pi2**(cst_13) * rho**cst_43 )
@@ -61,7 +63,12 @@ double precision function ec_scan(rho_a,rho_b,tau,grad_rho_2)
g_at2 = 1.d0/(1.d0 + 4.d0 * a*t*t)**0.25d0
h1 = gama * phi_3 * dlog(1.d0 + w_1 * (1.d0 - g_at2))
! interpolation function
- fc_alpha = dexp(-c_1c * alpha * inv_1alph) * step_f(cst_1alph) - d_c * dexp(c_2c * inv_1alph) * step_f(-cst_1alph)
+
+ if(cst_1alph.gt.0.d0)then
+ fc_alpha = dexp(-c_1c * alpha * inv_1alph)
+ else
+ fc_alpha = - d_c * dexp(c_2c * inv_1alph)
+ endif
! first part of the correlation energy
e_c_1 = e_c_lsda1 + h1
@@ -82,15 +89,6 @@ double precision function ec_scan(rho_a,rho_b,tau,grad_rho_2)
ec_scan = e_c_1 + fc_alpha * (e_c_0 - e_c_1)
end
-double precision function step_f(x)
- implicit none
- double precision, intent(in) :: x
- if(x.lt.0.d0)then
- step_f = 0.d0
- else
- step_f = 1.d0
- endif
-end
double precision function beta_rs(rs)
implicit none
@@ -98,3 +96,4 @@ double precision function beta_rs(rs)
beta_rs = 0.066725d0 * (1.d0 + 0.1d0 * rs)/(1.d0 + 0.1778d0 * rs)
end
+
diff --git a/src/dft_utils_one_e/ec_scan_2.irp.f b/src/dft_utils_one_e/ec_scan_2.irp.f
new file mode 100644
index 00000000..4807b89f
--- /dev/null
+++ b/src/dft_utils_one_e/ec_scan_2.irp.f
@@ -0,0 +1,100 @@
+double precision function ec_scan(rho_a,rho_b,tau,grad_rho_2)
+ include 'constants.include.F'
+ implicit none
+ double precision, intent(in) :: rho_a,rho_b,tau,grad_rho_2
+ double precision :: cst_13,cst_23,cst_43,cst_53,rho_inv,cst_18,cst_3pi2
+ double precision :: thr,nup,ndo,xi,s,spin_d,drho,drho2,rho,inv_1alph,e_c_lsda1,h0
+ double precision :: rs,t_w,t_unif,ds_xi,alpha,fc_alpha,step_f,cst_1alph,beta_inf
+ double precision :: c_1c,c_2c,d_c,e_c_ldsa1,h1,phi,t,beta_rs,gama,a,w_1,g_at2,phi_3,e_c_1
+ double precision :: b_1c,b_2c,b_3c,dx_xi,gc_xi,e_c_lsda0,w_0,g_inf,cx_xi,x_inf,f0,e_c_0
+ thr = 1.d-12
+ nup = max(rho_a,thr)
+ ndo = max(rho_b,thr)
+ rho = nup + ndo
+ ec_scan = 0.d0
+ if((rho).lt.thr)return
+ ! constants ...
+ rho_inv = 1.d0/rho
+ cst_13 = 1.d0/3.d0
+ cst_23 = 2.d0 * cst_13
+ cst_43 = 4.d0 * cst_13
+ cst_53 = 5.d0 * cst_13
+ cst_18 = 1.d0/8.d0
+ cst_3pi2 = 3.d0 * pi*pi
+ drho2 = max(grad_rho_2,thr)
+ drho = dsqrt(drho2)
+ if((nup-ndo).gt.0.d0)then
+ spin_d = max(nup-ndo,thr)
+ else
+ spin_d = min(nup-ndo,-thr)
+ endif
+ c_1c = 0.64d0
+ c_2c = 1.5d0
+ d_c = 0.7d0
+ b_1c = 0.0285764d0
+ b_2c = 0.0889d0
+ b_3c = 0.125541d0
+ gama = 0.031091d0
+ ! correlation energy lsda1
+ call ec_only_lda_sr(0.d0,nup,ndo,e_c_lsda1)
+
+ xi = spin_d/rho
+ rs = (cst_43 * pi * rho)**(-cst_13)
+ s = drho/( 2.d0 * cst_3pi2**(cst_13) * rho**cst_43 )
+ t_w = drho2 * cst_18 * rho_inv
+ ds_xi = 0.5d0 * ( (1.d0+xi)**cst_53 + (1.d0 - xi)**cst_53)
+ t_unif = 0.3d0 * (cst_3pi2)**cst_23 * rho**cst_53*ds_xi
+ t_unif = max(t_unif,thr)
+ alpha = (tau - t_w)/t_unif
+ cst_1alph= 1.d0 - alpha
+ if(cst_1alph.gt.0.d0)then
+ cst_1alph= max(cst_1alph,thr)
+ else
+ cst_1alph= min(cst_1alph,-thr)
+ endif
+ inv_1alph= 1.d0/cst_1alph
+ phi = 0.5d0 * ( (1.d0+xi)**cst_23 + (1.d0 - xi)**cst_23)
+ phi_3 = phi*phi*phi
+ t = (cst_3pi2/16.d0)**cst_13 * s / (phi * rs**0.5d0)
+ w_1 = dexp(-e_c_lsda1/(gama * phi_3)) - 1.d0
+ a = beta_rs(rs) /(gama * w_1)
+ g_at2 = 1.d0/(1.d0 + 4.d0 * a*t*t)**0.25d0
+ h1 = gama * phi_3 * dlog(1.d0 + w_1 * (1.d0 - g_at2))
+ ! interpolation function
+ fc_alpha = dexp(-c_1c * alpha * inv_1alph) * step_f(cst_1alph) - d_c * dexp(c_2c * inv_1alph) * step_f(-cst_1alph)
+ ! first part of the correlation energy
+ e_c_1 = e_c_lsda1 + h1
+
+ dx_xi = 0.5d0 * ( (1.d0+xi)**cst_43 + (1.d0 - xi)**cst_43)
+ gc_xi = (1.d0 - 2.3631d0 * (dx_xi - 1.d0) ) * (1.d0 - xi**12.d0)
+ e_c_lsda0= - b_1c / (1.d0 + b_2c * rs**0.5d0 + b_3c * rs)
+ w_0 = dexp(-e_c_lsda0/b_1c) - 1.d0
+ beta_inf = 0.066725d0 * 0.1d0 / 0.1778d0
+ cx_xi = -3.d0/(4.d0*pi) * (9.d0 * pi/4.d0)**cst_13 * dx_xi
+
+ x_inf = 0.128026d0
+ f0 = -0.9d0
+ g_inf = 1.d0/(1.d0 + 4.d0 * x_inf * s*s)**0.25d0
+
+ h0 = b_1c * dlog(1.d0 + w_0 * (1.d0 - g_inf))
+ e_c_0 = (e_c_lsda0 + h0) * gc_xi
+
+ ec_scan = e_c_1 + fc_alpha * (e_c_0 - e_c_1)
+end
+
+double precision function step_f(x)
+ implicit none
+ double precision, intent(in) :: x
+ if(x.lt.0.d0)then
+ step_f = 0.d0
+ else
+ step_f = 1.d0
+ endif
+end
+
+double precision function beta_rs(rs)
+ implicit none
+ double precision, intent(in) ::rs
+ beta_rs = 0.066725d0 * (1.d0 + 0.1d0 * rs)/(1.d0 + 0.1778d0 * rs)
+
+end
diff --git a/src/ezfio_files/00.create.bats b/src/ezfio_files/00.create.bats
index 59bdad18..3d0eac25 100644
--- a/src/ezfio_files/00.create.bats
+++ b/src/ezfio_files/00.create.bats
@@ -24,6 +24,11 @@ function run {
}
+@test "B-B" {
+ qp set_file b2_stretched.ezfio
+ run b2_stretched.zmt 1 0 6-31g
+}
+
@test "C2H2" {
run c2h2.xyz 1 0 cc-pvdz_ecp_bfd bfd
}
diff --git a/src/fci/40.fci.bats b/src/fci/40.fci.bats
index 812cd3d4..7e30878a 100644
--- a/src/fci/40.fci.bats
+++ b/src/fci/40.fci.bats
@@ -22,7 +22,7 @@ function run_stoch() {
thresh=$2
test_exe fci || skip
qp set perturbation do_pt2 True
- qp set determinants n_det_max 100000
+ qp set determinants n_det_max $3
qp set determinants n_states 1
qp set davidson threshold_davidson 1.e-10
qp set davidson n_states_diag 1
@@ -31,137 +31,143 @@ function run_stoch() {
eq $energy1 $1 $thresh
}
+@test "B-B" {
+ qp set_file b2_stretched.ezfio
+ qp set determinants n_det_max 10000
+ qp set_frozen_core
+ run_stoch -49.14103054419 3.e-4 10000
+}
@test "F2" { # 4.07m
[[ -n $TRAVIS ]] && skip
qp set_file f2.ezfio
qp set_frozen_core
- run_stoch -199.30486 1.e-4
+ run_stoch -199.304922384814 3.e-4 100000
}
@test "NH3" { # 10.6657s
qp set_file nh3.ezfio
qp set_mo_class --core="[1-4]" --act="[5-72]"
- run -56.244753429144986 1.e-4
+ run -56.244753429144986 3.e-4 100000
}
@test "DHNO" { # 11.4721s
qp set_file dhno.ezfio
qp set_mo_class --core="[1-7]" --act="[8-64]"
- run -130.459020029816 1.e-4
+ run -130.459020029816 3.e-4 100000
}
@test "HCO" { # 12.2868s
qp set_file hco.ezfio
- run -113.297494345682 1.e-4
+ run -113.297931671897 3.e-4 100000
}
@test "H2O2" { # 12.9214s
qp set_file h2o2.ezfio
qp set_mo_class --core="[1-2]" --act="[3-24]" --del="[25-38]"
- run -151.00477 1.e-4
+ run -151.00467 1.e-4 100000
}
@test "HBO" { # 13.3144s
[[ -n $TRAVIS ]] && skip
qp set_file hbo.ezfio
- run -100.212829869715 1.e-4
+ run -100.212721540746 1.e-3 100000
}
@test "H2O" { # 11.3727s
[[ -n $TRAVIS ]] && skip
qp set_file h2o.ezfio
- run -76.2359268957699 1.e-4
+ run -76.2361605151999 3.e-4 100000
}
@test "ClO" { # 13.3755s
[[ -n $TRAVIS ]] && skip
qp set_file clo.ezfio
- run -534.545881614967 1.e-4
+ run -534.545616787223 3.e-4 100000
}
@test "SO" { # 13.4952s
[[ -n $TRAVIS ]] && skip
qp set_file so.ezfio
- run -26.0158153138924 1.e-4
+ run -26.0060656855457 1.e-3 100000
}
@test "H2S" { # 13.6745s
[[ -n $TRAVIS ]] && skip
qp set_file h2s.ezfio
- run -398.859168655255 1.e-4
+ run -398.859168655255 3.e-4 100000
}
@test "OH" { # 13.865s
[[ -n $TRAVIS ]] && skip
qp set_file oh.ezfio
- run -75.6120779012574 1.e-4
+ run -75.6121856748294 3.e-4 100000
}
@test "SiH2_3B1" { # 13.938ss
[[ -n $TRAVIS ]] && skip
qp set_file sih2_3b1.ezfio
- run -290.017539006762 1.e-4
+ run -290.017539006762 3.e-4 100000
}
@test "H3COH" { # 14.7299s
[[ -n $TRAVIS ]] && skip
qp set_file h3coh.ezfio
- run -115.205941463667 1.e-4
+ run -115.205191406072 3.e-4 100000
}
@test "SiH3" { # 15.99s
[[ -n $TRAVIS ]] && skip
qp set_file sih3.ezfio
- run -5.57241217753818 1.e-4
+ run -5.57241217753818 3.e-4 100000
}
@test "CH4" { # 16.1612s
[[ -n $TRAVIS ]] && skip
qp set_file ch4.ezfio
qp set_mo_class --core="[1]" --act="[2-30]" --del="[31-59]"
- run -40.2409678239136 1.e-4
+ run -40.2409678239136 3.e-4 100000
}
@test "ClF" { # 16.8864s
[[ -n $TRAVIS ]] && skip
qp set_file clf.ezfio
- run -559.170272077166 1.e-4
+ run -559.1702772994 3.e-4 100000
}
@test "SO2" { # 17.5645s
[[ -n $TRAVIS ]] && skip
qp set_file so2.ezfio
qp set_mo_class --core="[1-8]" --act="[9-87]"
- run -41.5746738713298 1.e-4
+ run -41.5746738713298 3.e-4 100000
}
@test "C2H2" { # 17.6827s
[[ -n $TRAVIS ]] && skip
qp set_file c2h2.ezfio
qp set_mo_class --act="[1-30]" --del="[31-36]"
- run -12.3656179738175 1.e-4
+ run -12.3671816782954 3.e-4 100000
}
@test "N2" { # 18.0198s
[[ -n $TRAVIS ]] && skip
qp set_file n2.ezfio
qp set_mo_class --core="[1,2]" --act="[3-40]" --del="[41-60]"
- run -109.291600196629 1.e-4
+ run -109.291711886659 3.e-4 100000
}
@test "N2H4" { # 18.5006s
[[ -n $TRAVIS ]] && skip
qp set_file n2h4.ezfio
qp set_mo_class --core="[1-2]" --act="[3-24]" --del="[25-48]"
- run -111.367332681559 1.e-4
+ run -111.367332681559 3.e-4 100000
}
@test "CO2" { # 21.1748s
[[ -n $TRAVIS ]] && skip
qp set_file co2.ezfio
qp set_mo_class --core="[1,2]" --act="[3-30]" --del="[31-42]"
- run -187.968599504402 1.e-4
+ run -187.96924172901 3.e-4 100000
}
@@ -169,13 +175,13 @@ function run_stoch() {
[[ -n $TRAVIS ]] && skip
qp set_file cu_nh3_4_2plus.ezfio
qp set_mo_class --core="[1-24]" --act="[25-45]" --del="[46-87]"
- run -1862.98614665139 1.e-04
+ run -1862.98614665139 3.e-04 100000
}
@test "HCN" { # 20.3273s
[[ -n $TRAVIS ]] && skip
qp set_file hcn.ezfio
qp set_mo_class --core="[1,2]" --act="[3-40]" --del="[41-55]"
- run -93.0728641601823 1.e-4
+ run -93.0803416322765 3.e-4 100000
}
diff --git a/src/fci/class.irp.f b/src/fci/class.irp.f
index 425691ae..b4a68ac2 100644
--- a/src/fci/class.irp.f
+++ b/src/fci/class.irp.f
@@ -1,10 +1,12 @@
BEGIN_PROVIDER [ logical, do_only_1h1p ]
+&BEGIN_PROVIDER [ logical, do_only_cas ]
&BEGIN_PROVIDER [ logical, do_ddci ]
implicit none
BEGIN_DOC
! In the FCI case, all those are always false
END_DOC
do_only_1h1p = .False.
+ do_only_cas = .False.
do_ddci = .False.
END_PROVIDER
diff --git a/src/generators_cas/generators.irp.f b/src/generators_cas/generators.irp.f
index c22eab51..b2f58202 100644
--- a/src/generators_cas/generators.irp.f
+++ b/src/generators_cas/generators.irp.f
@@ -55,6 +55,7 @@ END_PROVIDER
nongen(inongen) = i
endif
enddo
+ ASSERT (m == N_det_generators)
psi_det_sorted_gen(:,:,:N_det_generators) = psi_det_generators(:,:,:N_det_generators)
psi_coef_sorted_gen(:N_det_generators, :) = psi_coef_generators(:N_det_generators, :)
diff --git a/src/hartree_fock/10.hf.bats b/src/hartree_fock/10.hf.bats
index ae78309a..8a9dde37 100644
--- a/src/hartree_fock/10.hf.bats
+++ b/src/hartree_fock/10.hf.bats
@@ -17,6 +17,10 @@ function run() {
}
+@test "B-B" { # 3s
+ run b2_stretched.ezfio -48.9950585752809
+}
+
@test "SiH2_3B1" { # 0.539000 1.51094s
run sih2_3b1.ezfio -289.9654718650881
}
diff --git a/src/kohn_sham_rs/61.rsks.bats b/src/kohn_sham_rs/61.rsks.bats
index 558c5027..c5e67350 100644
--- a/src/kohn_sham_rs/61.rsks.bats
+++ b/src/kohn_sham_rs/61.rsks.bats
@@ -21,7 +21,6 @@ function run() {
eq $energy $3 $thresh
}
-
@test "H3COH" {
run h3coh.ezfio sr_pbe -115.50238225208
}
diff --git a/src/mo_basis/EZFIO.cfg b/src/mo_basis/EZFIO.cfg
index 126705bf..a055aad3 100644
--- a/src/mo_basis/EZFIO.cfg
+++ b/src/mo_basis/EZFIO.cfg
@@ -23,7 +23,7 @@ size: (mo_basis.mo_num)
[mo_class]
type: MO_class
doc: [ Core | Inactive | Active | Virtual | Deleted ], as defined by :ref:`qp_set_mo_class`
-interface: ezfio, provider
+interface: ezfio
size: (mo_basis.mo_num)
[ao_md5]
diff --git a/src/mo_basis/mo_class.irp.f b/src/mo_basis/mo_class.irp.f
new file mode 100644
index 00000000..95fbb443
--- /dev/null
+++ b/src/mo_basis/mo_class.irp.f
@@ -0,0 +1,40 @@
+! DO NOT MODIFY BY HAND
+! Created by $QP_ROOT/scripts/ezfio_interface/ei_handler.py
+! from file /home/eginer/programs/qp2/src/mo_basis/EZFIO.cfg
+
+
+BEGIN_PROVIDER [ character*(32), mo_class , (mo_num) ]
+ implicit none
+ BEGIN_DOC
+! [ Core | Inactive | Active | Virtual | Deleted ], as defined by :ref:`qp_set_mo_class`
+ END_DOC
+
+ logical :: has
+ PROVIDE ezfio_filename
+ if (mpi_master) then
+ if (size(mo_class) == 0) return
+
+ call ezfio_has_mo_basis_mo_class(has)
+ if (has) then
+ write(6,'(A)') '.. >>>>> [ IO READ: mo_class ] <<<<< ..'
+ call ezfio_get_mo_basis_mo_class(mo_class)
+ else
+ mo_class(:) = 'Active'
+ endif
+ endif
+ IRP_IF MPI_DEBUG
+ print *, irp_here, mpi_rank
+ call MPI_BARRIER(MPI_COMM_WORLD, ierr)
+ IRP_ENDIF
+ IRP_IF MPI
+ include 'mpif.h'
+ integer :: ierr
+ call MPI_BCAST( mo_class, (mo_num)*32, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+ if (ierr /= MPI_SUCCESS) then
+ stop 'Unable to read mo_class with MPI'
+ endif
+ IRP_ENDIF
+
+ call write_time(6)
+
+END_PROVIDER
diff --git a/src/mo_basis/mos.irp.f b/src/mo_basis/mos.irp.f
index 610e9a8c..aa04fb01 100644
--- a/src/mo_basis/mos.irp.f
+++ b/src/mo_basis/mos.irp.f
@@ -91,7 +91,6 @@ BEGIN_PROVIDER [ double precision, mo_coef, (ao_num,mo_num) ]
enddo
enddo
endif
-
END_PROVIDER
BEGIN_PROVIDER [ double precision, mo_coef_in_ao_ortho_basis, (ao_num, mo_num) ]
diff --git a/src/mo_basis/utils.irp.f b/src/mo_basis/utils.irp.f
index e141867a..12c6c79d 100644
--- a/src/mo_basis/utils.irp.f
+++ b/src/mo_basis/utils.irp.f
@@ -4,7 +4,6 @@ subroutine save_mos
integer :: i,j
call system('$QP_ROOT/scripts/save_current_mos.sh '//trim(ezfio_filename))
-
call ezfio_set_mo_basis_mo_num(mo_num)
call ezfio_set_mo_basis_mo_label(mo_label)
call ezfio_set_mo_basis_ao_md5(ao_md5)
@@ -17,6 +16,29 @@ subroutine save_mos
enddo
call ezfio_set_mo_basis_mo_coef(buffer)
call ezfio_set_mo_basis_mo_occ(mo_occ)
+ call ezfio_set_mo_basis_mo_class(mo_class)
+ deallocate (buffer)
+
+end
+
+
+subroutine save_mos_no_occ
+ implicit none
+ double precision, allocatable :: buffer(:,:)
+ integer :: i,j
+
+ call system('$QP_ROOT/scripts/save_current_mos.sh '//trim(ezfio_filename))
+ !call ezfio_set_mo_basis_mo_num(mo_num)
+ !call ezfio_set_mo_basis_mo_label(mo_label)
+ !call ezfio_set_mo_basis_ao_md5(ao_md5)
+ allocate ( buffer(ao_num,mo_num) )
+ buffer = 0.d0
+ do j = 1, mo_num
+ do i = 1, ao_num
+ buffer(i,j) = mo_coef(i,j)
+ enddo
+ enddo
+ call ezfio_set_mo_basis_mo_coef(buffer)
deallocate (buffer)
end
@@ -40,6 +62,7 @@ subroutine save_mos_truncated(n)
enddo
call ezfio_set_mo_basis_mo_coef(buffer)
call ezfio_set_mo_basis_mo_occ(mo_occ)
+ call ezfio_set_mo_basis_mo_class(mo_class)
deallocate (buffer)
end
@@ -217,3 +240,64 @@ subroutine mo_as_svd_vectors_of_mo_matrix_eig(matrix,lda,m,n,eig,label)
end
+subroutine mo_coef_new_as_svd_vectors_of_mo_matrix_eig(matrix,lda,m,n,mo_coef_before,eig,mo_coef_new)
+ implicit none
+ BEGIN_DOC
+! You enter with matrix in the MO basis defined with the mo_coef_before.
+!
+! You SVD the matrix and set the eigenvectors as mo_coef_new ordered by increasing singular values
+ END_DOC
+ integer,intent(in) :: lda,m,n
+ double precision, intent(in) :: matrix(lda,n),mo_coef_before(ao_num,m)
+ double precision, intent(out) :: eig(m),mo_coef_new(ao_num,m)
+
+ integer :: i,j
+ double precision :: accu
+ double precision, allocatable :: mo_coef_tmp(:,:), U(:,:),D(:), A(:,:), Vt(:,:), work(:)
+ !DIR$ ATTRIBUTES ALIGN : $IRP_ALIGN :: U, Vt, A
+
+ call write_time(6)
+ if (m /= mo_num) then
+ print *, irp_here, ': Error : m/= mo_num'
+ stop 1
+ endif
+
+ allocate(A(lda,n),U(lda,n),D(m),Vt(lda,n),mo_coef_tmp(ao_num,mo_num))
+
+ do j=1,n
+ do i=1,m
+ A(i,j) = matrix(i,j)
+ enddo
+ enddo
+ mo_coef_tmp = mo_coef_before
+
+ call svd(A,lda,U,lda,D,Vt,lda,m,n)
+
+ write (6,'(A)') ''
+ write (6,'(A)') 'Eigenvalues'
+ write (6,'(A)') '-----------'
+ write (6,'(A)') ''
+ write (6,'(A)') '======== ================ ================'
+ write (6,'(A)') ' MO Eigenvalue Cumulative '
+ write (6,'(A)') '======== ================ ================'
+
+ accu = 0.d0
+ do i=1,m
+ accu = accu + D(i)
+ write (6,'(I8,1X,F16.10,1X,F16.10)') i,D(i), accu
+ enddo
+ write (6,'(A)') '======== ================ ================'
+ write (6,'(A)') ''
+
+ call dgemm('N','N',ao_num,m,m,1.d0,mo_coef_tmp,size(mo_coef_new,1),U,size(U,1),0.d0,mo_coef_new,size(mo_coef_new,1))
+
+ do i=1,m
+ eig(i) = D(i)
+ enddo
+
+ deallocate(A,U,Vt,D,mo_coef_tmp)
+ call write_time(6)
+
+end
+
+
diff --git a/src/mo_two_e_ints/EZFIO.cfg b/src/mo_two_e_ints/EZFIO.cfg
index 57681638..bec74552 100644
--- a/src/mo_two_e_ints/EZFIO.cfg
+++ b/src/mo_two_e_ints/EZFIO.cfg
@@ -11,24 +11,3 @@ interface: ezfio,provider,ocaml
default: 1.e-15
ezfio_name: threshold_mo
-[no_vvvv_integrals]
-type: logical
-doc: If `True`, computes all integrals except for the integrals having 4 virtual indices
-interface: ezfio,provider,ocaml
-default: False
-ezfio_name: no_vvvv_integrals
-
-[no_ivvv_integrals]
-type: logical
-doc: Can be switched on only if `no_vvvv_integrals` is `True`, then does not compute the integrals with 3 virtual indices and 1 belonging to the core inactive active orbitals
-interface: ezfio,provider,ocaml
-default: False
-ezfio_name: no_ivvv_integrals
-
-[no_vvv_integrals]
-type: logical
-doc: Can be switched on only if `no_vvvv_integrals` is `True`, then does not compute the integrals with 3 virtual orbitals
-interface: ezfio,provider,ocaml
-default: False
-ezfio_name: no_vvv_integrals
-
diff --git a/src/mo_two_e_ints/four_idx_novvvv.irp.f b/src/mo_two_e_ints/four_idx_novvvv.irp.f
new file mode 100644
index 00000000..054d0a35
--- /dev/null
+++ b/src/mo_two_e_ints/four_idx_novvvv.irp.f
@@ -0,0 +1,180 @@
+BEGIN_PROVIDER [ logical, no_vvvv_integrals ]
+ implicit none
+ BEGIN_DOC
+! If `True`, computes all integrals except for the integrals having 3 or 4 virtual indices
+ END_DOC
+
+ no_vvvv_integrals = .False.
+END_PROVIDER
+
+BEGIN_PROVIDER [ double precision, mo_coef_novirt, (ao_num,n_core_inact_act_orb) ]
+ implicit none
+ BEGIN_DOC
+ ! MO coefficients without virtual MOs
+ END_DOC
+ integer :: j,jj
+
+ do j=1,n_core_inact_act_orb
+ jj = list_core_inact_act(j)
+ mo_coef_novirt(:,j) = mo_coef(:,jj)
+ enddo
+
+END_PROVIDER
+
+subroutine ao_to_mo_novirt(A_ao,LDA_ao,A_mo,LDA_mo)
+ implicit none
+ BEGIN_DOC
+ ! Transform A from the |AO| basis to the |MO| basis excluding virtuals
+ !
+ ! $C^\dagger.A_{ao}.C$
+ END_DOC
+ integer, intent(in) :: LDA_ao,LDA_mo
+ double precision, intent(in) :: A_ao(LDA_ao,ao_num)
+ double precision, intent(out) :: A_mo(LDA_mo,n_core_inact_act_orb)
+ double precision, allocatable :: T(:,:)
+
+ allocate ( T(ao_num,n_core_inact_act_orb) )
+ !DIR$ ATTRIBUTES ALIGN : $IRP_ALIGN :: T
+
+ call dgemm('N','N', ao_num, n_core_inact_act_orb, ao_num, &
+ 1.d0, A_ao,LDA_ao, &
+ mo_coef_novirt, size(mo_coef_novirt,1), &
+ 0.d0, T, size(T,1))
+
+ call dgemm('T','N', n_core_inact_act_orb, n_core_inact_act_orb, ao_num,&
+ 1.d0, mo_coef_novirt,size(mo_coef_novirt,1), &
+ T, ao_num, &
+ 0.d0, A_mo, size(A_mo,1))
+
+ deallocate(T)
+end
+
+
+subroutine four_idx_novvvv
+ use map_module
+ implicit none
+ BEGIN_DOC
+ ! Retransform MO integrals for next CAS-SCF step
+ END_DOC
+ integer :: i,j,k,l,n_integrals
+ double precision, allocatable :: f(:,:,:), f2(:,:,:), d(:,:), T(:,:,:,:), T2(:,:,:,:)
+ double precision, external :: get_ao_two_e_integral
+ integer(key_kind), allocatable :: idx(:)
+ real(integral_kind), allocatable :: values(:)
+
+ integer :: p,q,r,s
+ double precision :: c
+ allocate( T(n_core_inact_act_orb,n_core_inact_act_orb,ao_num,ao_num) , &
+ T2(n_core_inact_act_orb,n_core_inact_act_orb,ao_num,ao_num) )
+
+ !$OMP PARALLEL DEFAULT(NONE) &
+ !$OMP SHARED(mo_num,ao_num,T,n_core_inact_act_orb, mo_coef_transp, &
+ !$OMP mo_integrals_threshold,mo_coef,mo_integrals_map, &
+ !$OMP list_core_inact_act,T2,ao_integrals_map) &
+ !$OMP PRIVATE(i,j,k,l,p,q,r,s,idx,values,n_integrals, &
+ !$OMP f,f2,d,c)
+ allocate(f(ao_num,ao_num,ao_num), f2(ao_num,ao_num,ao_num), d(mo_num,mo_num), &
+ idx(mo_num*mo_num), values(mo_num*mo_num) )
+
+ !
+ !$OMP DO
+ do s=1,ao_num
+ do r=1,ao_num
+ do q=1,ao_num
+ do p=1,r
+ f (p,q,r) = get_ao_two_e_integral(p,q,r,s,ao_integrals_map)
+ f (r,q,p) = f(p,q,r)
+ enddo
+ enddo
+ enddo
+ do r=1,ao_num
+ do q=1,ao_num
+ do p=1,ao_num
+ f2(p,q,r) = f(p,r,q)
+ enddo
+ enddo
+ enddo
+ ! f (p,q,r) =
+ ! f2(p,q,r) =
+
+ do r=1,ao_num
+ call ao_to_mo_novirt(f (1,1,r),size(f ,1),T (1,1,r,s),size(T,1))
+ call ao_to_mo_novirt(f2(1,1,r),size(f2,1),T2(1,1,r,s),size(T,1))
+ enddo
+ ! T (i,j,p,q) =
+ ! T2(i,j,p,q) =
+
+ enddo
+ !$OMP END DO
+
+ !$OMP DO
+ do j=1,n_core_inact_act_orb
+ do i=1,n_core_inact_act_orb
+ do s=1,ao_num
+ do r=1,ao_num
+ f (r,s,1) = T (i,j,r,s)
+ f2(r,s,1) = T2(i,j,r,s)
+ enddo
+ enddo
+ call ao_to_mo(f ,size(f ,1),d,size(d,1))
+ n_integrals = 0
+ do l=1,mo_num
+ do k=1,mo_num
+ n_integrals+=1
+ call two_e_integrals_index(list_core_inact_act(i),list_core_inact_act(j),k,l,idx(n_integrals))
+ values(n_integrals) = d(k,l)
+ enddo
+ enddo
+ call map_append(mo_integrals_map, idx, values, n_integrals)
+
+ call ao_to_mo(f2,size(f2,1),d,size(d,1))
+ n_integrals = 0
+ do l=1,mo_num
+ do k=1,mo_num
+ n_integrals+=1
+ call two_e_integrals_index(list_core_inact_act(i),k,list_core_inact_act(j),l,idx(n_integrals))
+ values(n_integrals) = d(k,l)
+ enddo
+ enddo
+ call map_append(mo_integrals_map, idx, values, n_integrals)
+ enddo
+ enddo
+ !$OMP END DO
+ deallocate(f,f2,d,idx,values)
+
+ !$OMP END PARALLEL
+
+ deallocate(T,T2)
+
+
+ call map_sort(mo_integrals_map)
+ call map_unique(mo_integrals_map)
+ call map_shrink(mo_integrals_map,real(mo_integrals_threshold,integral_kind))
+
+end
+
+subroutine four_idx_novvvv2
+ use bitmasks
+ implicit none
+ integer :: i
+ integer(bit_kind) :: mask_ijkl(N_int,4)
+
+ print*, ''
+ do i = 1,N_int
+ mask_ijkl(i,1) = core_inact_act_bitmask_4(i,1)
+ mask_ijkl(i,2) = full_ijkl_bitmask_4(i,1)
+ mask_ijkl(i,3) = core_inact_act_bitmask_4(i,1)
+ mask_ijkl(i,4) = full_ijkl_bitmask_4(i,1)
+ enddo
+ call add_integrals_to_map(mask_ijkl)
+
+ print*, ''
+ do i = 1,N_int
+ mask_ijkl(i,1) = core_inact_act_bitmask_4(i,1)
+ mask_ijkl(i,2) = core_inact_act_bitmask_4(i,1)
+ mask_ijkl(i,3) = virt_bitmask(i,1)
+ mask_ijkl(i,4) = virt_bitmask(i,1)
+ enddo
+ call add_integrals_to_map(mask_ijkl)
+
+end
diff --git a/src/mo_two_e_ints/map_integrals.irp.f b/src/mo_two_e_ints/map_integrals.irp.f
index 0baf4da8..83ca98cd 100644
--- a/src/mo_two_e_ints/map_integrals.irp.f
+++ b/src/mo_two_e_ints/map_integrals.irp.f
@@ -145,7 +145,6 @@ subroutine get_mo_two_e_integrals(j,k,l,sze,out_val,map)
type(map_type), intent(inout) :: map
integer :: i
double precision, external :: get_two_e_integral
- PROVIDE mo_two_e_integrals_in_map mo_integrals_cache
integer :: ii, ii0
integer*8 :: ii_8, ii0_8
@@ -154,6 +153,13 @@ subroutine get_mo_two_e_integrals(j,k,l,sze,out_val,map)
integer(key_kind) :: p,q,r,s,i2
PROVIDE mo_two_e_integrals_in_map mo_integrals_cache
+!DEBUG
+! do i=1,sze
+! out_val(i) = get_two_e_integral(i,j,k,l,map)
+! enddo
+! return
+!DEBUG
+
ii0 = l-mo_integrals_cache_min
ii0 = ior(ii0, k-mo_integrals_cache_min)
ii0 = ior(ii0, j-mo_integrals_cache_min)
diff --git a/src/mo_two_e_ints/mo_bi_integrals.irp.f b/src/mo_two_e_ints/mo_bi_integrals.irp.f
index fccf22a6..a9983e51 100644
--- a/src/mo_two_e_ints/mo_bi_integrals.irp.f
+++ b/src/mo_two_e_ints/mo_bi_integrals.irp.f
@@ -22,16 +22,13 @@ end
BEGIN_PROVIDER [ logical, mo_two_e_integrals_in_map ]
use map_module
implicit none
- integer(bit_kind) :: mask_ijkl(N_int,4)
- integer(bit_kind) :: mask_ijk(N_int,3)
-
BEGIN_DOC
! If True, the map of MO two-electron integrals is provided
END_DOC
+ integer(bit_kind) :: mask_ijkl(N_int,4)
+ integer(bit_kind) :: mask_ijk(N_int,3)
+ double precision :: cpu_1, cpu_2, wall_1, wall_2
- ! The following line avoids a subsequent crash when the memory used is more
- ! than half of the virtual memory, due to a fork in zcat when reading arrays
- ! with EZFIO
PROVIDE mo_class
mo_two_e_integrals_in_map = .True.
@@ -49,106 +46,28 @@ BEGIN_PROVIDER [ logical, mo_two_e_integrals_in_map ]
print *, '---------------------------------'
print *, ''
+ call wall_time(wall_1)
+ call cpu_time(cpu_1)
+
if(no_vvvv_integrals)then
- integer :: i,j,k,l
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! I I I I !!!!!!!!!!!!!!!!!!!!
- ! (core+inact+act) ^ 4
- !
- print*, ''
- print*, ''
- do i = 1,N_int
- mask_ijkl(i,1) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,2) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,3) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,4) = core_inact_act_bitmask_4(i,1)
- enddo
- call add_integrals_to_map(mask_ijkl)
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! I I V V !!!!!!!!!!!!!!!!!!!!
- ! (core+inact+act) ^ 2 (virt) ^2
- ! = J_iv
- print*, ''
- print*, ''
- do i = 1,N_int
- mask_ijkl(i,1) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,2) = virt_bitmask(i,1)
- mask_ijkl(i,3) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,4) = virt_bitmask(i,1)
- enddo
- call add_integrals_to_map(mask_ijkl)
-
- ! (core+inact+act) ^ 2 (virt) ^2
- ! = (iv|iv)
- print*, ''
- print*, ''
- do i = 1,N_int
- mask_ijkl(i,1) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,2) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,3) = virt_bitmask(i,1)
- mask_ijkl(i,4) = virt_bitmask(i,1)
- enddo
- call add_integrals_to_map(mask_ijkl)
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! V V V !!!!!!!!!!!!!!!!!!!!!!!
- if(.not.no_vvv_integrals)then
- print*, ''
- print*, ' and '
- do i = 1,N_int
- mask_ijk(i,1) = virt_bitmask(i,1)
- mask_ijk(i,2) = virt_bitmask(i,1)
- mask_ijk(i,3) = virt_bitmask(i,1)
- enddo
- call add_integrals_to_map_three_indices(mask_ijk)
- endif
-
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! I I I V !!!!!!!!!!!!!!!!!!!!
- ! (core+inact+act) ^ 3 (virt) ^1
- !
- print*, ''
- print*, ''
- do i = 1,N_int
- mask_ijkl(i,1) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,2) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,3) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,4) = virt_bitmask(i,1)
- enddo
- call add_integrals_to_map(mask_ijkl)
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! I V V V !!!!!!!!!!!!!!!!!!!!
- ! (core+inact+act) ^ 1 (virt) ^3
- !
- if(.not.no_ivvv_integrals)then
- print*, ''
- print*, ''
- do i = 1,N_int
- mask_ijkl(i,1) = core_inact_act_bitmask_4(i,1)
- mask_ijkl(i,2) = virt_bitmask(i,1)
- mask_ijkl(i,3) = virt_bitmask(i,1)
- mask_ijkl(i,4) = virt_bitmask(i,1)
- enddo
- call add_integrals_to_map_no_exit_34(mask_ijkl)
- endif
-
+ call four_idx_novvvv
else
call add_integrals_to_map(full_ijkl_bitmask_4)
-
-! call four_index_transform_zmq(ao_integrals_map,mo_integrals_map, &
-! mo_coef, size(mo_coef,1), &
-! 1, 1, 1, 1, ao_num, ao_num, ao_num, ao_num, &
-! 1, 1, 1, 1, mo_num, mo_num, mo_num, mo_num)
-!
-! call four_index_transform_block(ao_integrals_map,mo_integrals_map, &
-! mo_coef, size(mo_coef,1), &
-! 1, 1, 1, 1, ao_num, ao_num, ao_num, ao_num, &
-! 1, 1, 1, 1, mo_num, mo_num, mo_num, mo_num)
-!
-! call four_index_transform(ao_integrals_map,mo_integrals_map, &
-! mo_coef, size(mo_coef,1), &
-! 1, 1, 1, 1, ao_num, ao_num, ao_num, ao_num, &
-! 1, 1, 1, 1, mo_num, mo_num, mo_num, mo_num)
-
- integer*8 :: get_mo_map_size, mo_map_size
- mo_map_size = get_mo_map_size()
-
- print*,'Molecular integrals provided'
endif
+
+ call wall_time(wall_2)
+ call cpu_time(cpu_2)
+
+ integer*8 :: get_mo_map_size, mo_map_size
+ mo_map_size = get_mo_map_size()
+
+ double precision, external :: map_mb
+ print*,'Molecular integrals provided:'
+ print*,' Size of MO map ', map_mb(mo_integrals_map) ,'MB'
+ print*,' Number of MO integrals: ', mo_map_size
+ print*,' cpu time :',cpu_2 - cpu_1, 's'
+ print*,' wall time :',wall_2 - wall_1, 's ( x ', (cpu_2-cpu_1)/(wall_2-wall_1), ')'
+
if (write_mo_two_e_integrals.and.mpi_master) then
call ezfio_set_work_empty(.False.)
call map_save_to_disk(trim(ezfio_filename)//'/work/mo_ints',mo_integrals_map)
@@ -185,7 +104,7 @@ subroutine add_integrals_to_map(mask_ijkl)
integer :: size_buffer
integer(key_kind),allocatable :: buffer_i(:)
real(integral_kind),allocatable :: buffer_value(:)
- double precision :: map_mb
+ double precision, external :: map_mb
integer :: i1,j1,k1,l1, ii1, kmax, thread_num
integer :: i2,i3,i4
@@ -201,10 +120,6 @@ subroutine add_integrals_to_map(mask_ijkl)
call bitstring_to_list( mask_ijkl(1,2), list_ijkl(1,2), n_j, N_int )
call bitstring_to_list( mask_ijkl(1,3), list_ijkl(1,3), n_k, N_int )
call bitstring_to_list( mask_ijkl(1,4), list_ijkl(1,4), n_l, N_int )
- character*(2048) :: output(1)
- print *, 'i'
- call bitstring_to_str( output(1), mask_ijkl(1,1), N_int )
- print *, trim(output(1))
j = 0
do i = 1, N_int
j += popcnt(mask_ijkl(i,1))
@@ -213,9 +128,6 @@ subroutine add_integrals_to_map(mask_ijkl)
return
endif
- print*, 'j'
- call bitstring_to_str( output(1), mask_ijkl(1,2), N_int )
- print *, trim(output(1))
j = 0
do i = 1, N_int
j += popcnt(mask_ijkl(i,2))
@@ -224,9 +136,6 @@ subroutine add_integrals_to_map(mask_ijkl)
return
endif
- print*, 'k'
- call bitstring_to_str( output(1), mask_ijkl(1,3), N_int )
- print *, trim(output(1))
j = 0
do i = 1, N_int
j += popcnt(mask_ijkl(i,3))
@@ -235,9 +144,6 @@ subroutine add_integrals_to_map(mask_ijkl)
return
endif
- print*, 'l'
- call bitstring_to_str( output(1), mask_ijkl(1,4), N_int )
- print *, trim(output(1))
j = 0
do i = 1, N_int
j += popcnt(mask_ijkl(i,4))
@@ -247,14 +153,12 @@ subroutine add_integrals_to_map(mask_ijkl)
endif
size_buffer = min(ao_num*ao_num*ao_num,16000000)
- print*, 'Providing the molecular integrals '
print*, 'Buffers : ', 8.*(mo_num*(n_j)*(n_k+1) + mo_num+&
ao_num+ao_num*ao_num+ size_buffer*3)/(1024*1024), 'MB / core'
- call wall_time(wall_1)
- call cpu_time(cpu_1)
double precision :: accu_bis
accu_bis = 0.d0
+ call wall_time(wall_1)
!$OMP PARALLEL PRIVATE(l1,k1,j1,i1,i2,i3,i4,i,j,k,l,c, ii1,kmax, &
!$OMP two_e_tmp_0_idx, two_e_tmp_0, two_e_tmp_1,two_e_tmp_2,two_e_tmp_3,&
@@ -452,12 +356,6 @@ subroutine add_integrals_to_map(mask_ijkl)
deallocate(list_ijkl)
- print*,'Molecular integrals provided:'
- print*,' Size of MO map ', map_mb(mo_integrals_map) ,'MB'
- print*,' Number of MO integrals: ', mo_map_size
- print*,' cpu time :',cpu_2 - cpu_1, 's'
- print*,' wall time :',wall_2 - wall_1, 's ( x ', (cpu_2-cpu_1)/(wall_2-wall_1), ')'
-
end
@@ -504,10 +402,6 @@ subroutine add_integrals_to_map_three_indices(mask_ijk)
call bitstring_to_list( mask_ijk(1,1), list_ijkl(1,1), n_i, N_int )
call bitstring_to_list( mask_ijk(1,2), list_ijkl(1,2), n_j, N_int )
call bitstring_to_list( mask_ijk(1,3), list_ijkl(1,3), n_k, N_int )
- character*(2048) :: output(1)
- print*, 'i'
- call bitstring_to_str( output(1), mask_ijk(1,1), N_int )
- print *, trim(output(1))
j = 0
do i = 1, N_int
j += popcnt(mask_ijk(i,1))
@@ -516,9 +410,6 @@ subroutine add_integrals_to_map_three_indices(mask_ijk)
return
endif
- print*, 'j'
- call bitstring_to_str( output(1), mask_ijk(1,2), N_int )
- print *, trim(output(1))
j = 0
do i = 1, N_int
j += popcnt(mask_ijk(i,2))
@@ -527,9 +418,6 @@ subroutine add_integrals_to_map_three_indices(mask_ijk)
return
endif
- print*, 'k'
- call bitstring_to_str( output(1), mask_ijk(1,3), N_int )
- print *, trim(output(1))
j = 0
do i = 1, N_int
j += popcnt(mask_ijk(i,3))
diff --git a/src/nuclei/atomic_radii.irp.f b/src/nuclei/atomic_radii.irp.f
index 439b5cec..c189effd 100644
--- a/src/nuclei/atomic_radii.irp.f
+++ b/src/nuclei/atomic_radii.irp.f
@@ -50,7 +50,58 @@ BEGIN_PROVIDER [ double precision, slater_bragg_radii, (0:100)]
slater_bragg_radii(33) = 1.15d0
slater_bragg_radii(34) = 1.15d0
slater_bragg_radii(35) = 1.15d0
- slater_bragg_radii(36) = 1.15d0
+ slater_bragg_radii(36) = 1.10d0
+
+ slater_bragg_radii(37) = 2.35d0
+ slater_bragg_radii(38) = 2.00d0
+ slater_bragg_radii(39) = 1.80d0
+ slater_bragg_radii(40) = 1.55d0
+ slater_bragg_radii(41) = 1.45d0
+ slater_bragg_radii(42) = 1.45d0
+ slater_bragg_radii(43) = 1.35d0
+ slater_bragg_radii(44) = 1.30d0
+ slater_bragg_radii(45) = 1.35d0
+ slater_bragg_radii(46) = 1.40d0
+ slater_bragg_radii(47) = 1.60d0
+ slater_bragg_radii(48) = 1.55d0
+ slater_bragg_radii(49) = 1.55d0
+ slater_bragg_radii(50) = 1.45d0
+ slater_bragg_radii(51) = 1.45d0
+ slater_bragg_radii(52) = 1.40d0
+ slater_bragg_radii(53) = 1.40d0
+ slater_bragg_radii(54) = 1.40d0
+ slater_bragg_radii(55) = 2.60d0
+ slater_bragg_radii(56) = 2.15d0
+ slater_bragg_radii(57) = 1.95d0
+ slater_bragg_radii(58) = 1.85d0
+ slater_bragg_radii(59) = 1.85d0
+ slater_bragg_radii(60) = 1.85d0
+ slater_bragg_radii(61) = 1.85d0
+ slater_bragg_radii(62) = 1.85d0
+ slater_bragg_radii(63) = 1.85d0
+ slater_bragg_radii(64) = 1.80d0
+ slater_bragg_radii(65) = 1.75d0
+ slater_bragg_radii(66) = 1.75d0
+ slater_bragg_radii(67) = 1.75d0
+ slater_bragg_radii(68) = 1.75d0
+ slater_bragg_radii(69) = 1.75d0
+ slater_bragg_radii(70) = 1.75d0
+ slater_bragg_radii(71) = 1.75d0
+ slater_bragg_radii(72) = 1.55d0
+ slater_bragg_radii(73) = 1.45d0
+ slater_bragg_radii(74) = 1.35d0
+ slater_bragg_radii(75) = 1.30d0
+ slater_bragg_radii(76) = 1.30d0
+ slater_bragg_radii(77) = 1.35d0
+ slater_bragg_radii(78) = 1.35d0
+ slater_bragg_radii(79) = 1.35d0
+ slater_bragg_radii(80) = 1.50d0
+ slater_bragg_radii(81) = 1.90d0
+ slater_bragg_radii(82) = 1.75d0
+ slater_bragg_radii(83) = 1.60d0
+ slater_bragg_radii(84) = 1.90d0
+ slater_bragg_radii(85) = 1.50d0
+ slater_bragg_radii(86) = 1.50d0
END_PROVIDER
diff --git a/src/selectors_full/selectors.irp.f b/src/selectors_full/selectors.irp.f
index 4e14d65a..0531f731 100644
--- a/src/selectors_full/selectors.irp.f
+++ b/src/selectors_full/selectors.irp.f
@@ -38,35 +38,18 @@ END_PROVIDER
END_DOC
integer :: i,k
-! if (threshold_selectors == 1.d0) then
-!
-! do i=1,N_det_selectors
-! do k=1,N_int
-! psi_selectors(k,1,i) = psi_det(k,1,i)
-! psi_selectors(k,2,i) = psi_det(k,2,i)
-! enddo
-! enddo
-! do k=1,N_states
-! do i=1,N_det_selectors
-! psi_selectors_coef(i,k) = psi_coef(i,k)
-! enddo
-! enddo
-!
-! else
-
+ do i=1,N_det_selectors
+ do k=1,N_int
+ psi_selectors(k,1,i) = psi_det_sorted(k,1,i)
+ psi_selectors(k,2,i) = psi_det_sorted(k,2,i)
+ enddo
+ enddo
+ do k=1,N_states
do i=1,N_det_selectors
- do k=1,N_int
- psi_selectors(k,1,i) = psi_det_sorted(k,1,i)
- psi_selectors(k,2,i) = psi_det_sorted(k,2,i)
- enddo
- enddo
- do k=1,N_states
- do i=1,N_det_selectors
- psi_selectors_coef(i,k) = psi_coef_sorted(i,k)
- enddo
+ psi_selectors_coef(i,k) = psi_coef_sorted(i,k)
enddo
+ enddo
-! endif
END_PROVIDER
diff --git a/src/tools/molden.irp.f b/src/tools/molden.irp.f
index 6bbbfa39..f70ed0de 100644
--- a/src/tools/molden.irp.f
+++ b/src/tools/molden.irp.f
@@ -6,6 +6,7 @@ program molden
character*(128) :: output
integer :: i_unit_output,getUnitAndOpen
integer :: i,j,k,l
+ double precision, parameter :: a0 = 0.529177249d0
PROVIDE ezfio_filename
@@ -22,7 +23,7 @@ program molden
trim(element_name(int(nucl_charge(i)))), &
i, &
int(nucl_charge(i)), &
- nucl_coord(i,1), nucl_coord(i,2), nucl_coord(i,3)
+ nucl_coord(i,1)*a0, nucl_coord(i,2)*a0, nucl_coord(i,3)*a0
enddo
write(i_unit_output,'(A)') '[GTO]'
diff --git a/src/tools/print_wf.irp.f b/src/tools/print_wf.irp.f
index 01fc8948..a92d1a51 100644
--- a/src/tools/print_wf.irp.f
+++ b/src/tools/print_wf.irp.f
@@ -14,7 +14,7 @@ program print_wf
! this has to be done in order to be sure that N_det, psi_det and
- ! psi_coef are the wave function stored in the |EZFIO| directory.
+ ! psi_coef_sorted are the wave function stored in the |EZFIO| directory.
read_wf = .True.
touch read_wf
call routine
@@ -45,15 +45,15 @@ subroutine routine
do i = 1, min(N_det_print_wf,N_det)
print*,''
print*,'i = ',i
- call debug_det(psi_det(1,1,i),N_int)
- call get_excitation_degree(psi_det(1,1,i),psi_det(1,1,1),degree,N_int)
+ call debug_det(psi_det_sorted(1,1,i),N_int)
+ call get_excitation_degree(psi_det_sorted(1,1,i),psi_det_sorted(1,1,1),degree,N_int)
print*,'degree = ',degree
if(degree == 0)then
print*,'Reference determinant '
- call i_H_j(psi_det(1,1,i),psi_det(1,1,i),N_int,h00)
- else
- call i_H_j(psi_det(1,1,i),psi_det(1,1,i),N_int,hii)
- call i_H_j(psi_det(1,1,1),psi_det(1,1,i),N_int,hij)
+ call i_H_j(psi_det_sorted(1,1,i),psi_det_sorted(1,1,i),N_int,h00)
+ else if(degree .le. 2)then
+ call i_H_j(psi_det_sorted(1,1,i),psi_det_sorted(1,1,i),N_int,hii)
+ call i_H_j(psi_det_sorted(1,1,1),psi_det_sorted(1,1,i),N_int,hij)
delta_e = hii - h00
coef_1 = hij/(h00-hii)
if(hij.ne.0.d0)then
@@ -65,25 +65,25 @@ subroutine routine
else
coef_2_2 = 0.d0
endif
- call get_excitation(psi_det(1,1,1),psi_det(1,1,i),exc,degree,phase,N_int)
+ call get_excitation(psi_det_sorted(1,1,1),psi_det_sorted(1,1,i),exc,degree,phase,N_int)
call decode_exc(exc,degree,h1,p1,h2,p2,s1,s2)
print*,'phase = ',phase
if(degree == 1)then
print*,'s1',s1
print*,'h1,p1 = ',h1,p1
if(s1 == 1)then
- norm_mono_a += dabs(psi_coef(i,1)/psi_coef(1,1))
- norm_mono_a_2 += dabs(psi_coef(i,1)/psi_coef(1,1))**2
+ norm_mono_a += dabs(psi_coef_sorted(i,1)/psi_coef_sorted(1,1))
+ norm_mono_a_2 += dabs(psi_coef_sorted(i,1)/psi_coef_sorted(1,1))**2
norm_mono_a_pert += dabs(coef_1)
norm_mono_a_pert_2 += dabs(coef_1)**2
else
- norm_mono_b += dabs(psi_coef(i,1)/psi_coef(1,1))
- norm_mono_b_2 += dabs(psi_coef(i,1)/psi_coef(1,1))**2
+ norm_mono_b += dabs(psi_coef_sorted(i,1)/psi_coef_sorted(1,1))
+ norm_mono_b_2 += dabs(psi_coef_sorted(i,1)/psi_coef_sorted(1,1))**2
norm_mono_b_pert += dabs(coef_1)
norm_mono_b_pert_2 += dabs(coef_1)**2
endif
double precision :: hmono,hdouble
- call i_H_j_verbose(psi_det(1,1,1),psi_det(1,1,i),N_int,hij,hmono,hdouble,phase)
+ call i_H_j_verbose(psi_det_sorted(1,1,1),psi_det_sorted(1,1,i),N_int,hij,hmono,hdouble,phase)
print*,'hmono = ',hmono
print*,'hdouble = ',hdouble
print*,'hmono+hdouble = ',hmono+hdouble
@@ -99,9 +99,9 @@ subroutine routine
print*,'Delta E = ',h00-hii
print*,'coef pert (1) = ',coef_1
print*,'coef 2x2 = ',coef_2_2
- print*,'Delta E_corr = ',psi_coef(i,1)/psi_coef(1,1) * hij
+ print*,'Delta E_corr = ',psi_coef_sorted(i,1)/psi_coef_sorted(1,1) * hij
endif
- print*,'amplitude = ',psi_coef(i,1)/psi_coef(1,1)
+ print*,'amplitude = ',psi_coef_sorted(i,1)/psi_coef_sorted(1,1)
enddo
diff --git a/src/two_body_rdm/NEED b/src/two_body_rdm/NEED
new file mode 100644
index 00000000..711fbf96
--- /dev/null
+++ b/src/two_body_rdm/NEED
@@ -0,0 +1 @@
+davidson_undressed
diff --git a/src/two_body_rdm/README.rst b/src/two_body_rdm/README.rst
new file mode 100644
index 00000000..978240c9
--- /dev/null
+++ b/src/two_body_rdm/README.rst
@@ -0,0 +1,8 @@
+============
+two_body_rdm
+============
+
+Contains the two rdms $\alpha\alpha$, $\beta\beta$ and $\alpha\beta$ stored as
+arrays, with pysicists notation, consistent with the two-electron integrals in the
+MO basis.
+
diff --git a/src/two_body_rdm/ab_only_routines.irp.f b/src/two_body_rdm/ab_only_routines.irp.f
new file mode 100644
index 00000000..fb3c421c
--- /dev/null
+++ b/src/two_body_rdm/ab_only_routines.irp.f
@@ -0,0 +1,402 @@
+
+ subroutine two_rdm_ab_nstates(big_array,dim1,dim2,dim3,dim4,u_0,N_st,sze)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes the alpha/beta part of the two-body density matrix IN CHEMIST NOTATIONS
+ !
+ ! Assumes that the determinants are in psi_det
+ !
+ ! istart, iend, ishift, istep are used in ZMQ parallelization.
+ END_DOC
+ integer, intent(in) :: N_st,sze
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: u_0(sze,N_st)
+ integer :: k
+ double precision, allocatable :: u_t(:,:)
+ !DIR$ ATTRIBUTES ALIGN : $IRP_ALIGN :: u_t
+ allocate(u_t(N_st,N_det))
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order,N_det)
+ enddo
+ call dtranspose( &
+ u_0, &
+ size(u_0, 1), &
+ u_t, &
+ size(u_t, 1), &
+ N_det, N_st)
+
+ call two_rdm_ab_nstates_work(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,1,N_det,0,1)
+ deallocate(u_t)
+
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order_reverse,N_det)
+ enddo
+
+ end
+
+
+ subroutine two_rdm_ab_nstates_work(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes the alpha/beta part of the two-body density matrix
+ !
+ ! Default should be 1,N_det,0,1
+ END_DOC
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(in) :: u_t(N_st,N_det)
+
+
+ PROVIDE N_int
+
+ select case (N_int)
+ case (1)
+ call two_rdm_ab_nstates_work_1(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (2)
+ call two_rdm_ab_nstates_work_2(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (3)
+ call two_rdm_ab_nstates_work_3(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (4)
+ call two_rdm_ab_nstates_work_4(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case default
+ call two_rdm_ab_nstates_work_N_int(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ end select
+ end
+ BEGIN_TEMPLATE
+
+ subroutine two_rdm_ab_nstates_work_$N_int(big_array,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(in) :: u_t(N_st,N_det)
+
+ double precision :: hij, sij
+ integer :: i,j,k,l
+ integer :: k_a, k_b, l_a, l_b, m_a, m_b
+ integer :: istate
+ integer :: krow, kcol, krow_b, kcol_b
+ integer :: lrow, lcol
+ integer :: mrow, mcol
+ integer(bit_kind) :: spindet($N_int)
+ integer(bit_kind) :: tmp_det($N_int,2)
+ integer(bit_kind) :: tmp_det2($N_int,2)
+ integer(bit_kind) :: tmp_det3($N_int,2)
+ integer(bit_kind), allocatable :: buffer(:,:)
+ integer :: n_doubles
+ integer, allocatable :: doubles(:)
+ integer, allocatable :: singles_a(:)
+ integer, allocatable :: singles_b(:)
+ integer, allocatable :: idx(:), idx0(:)
+ integer :: maxab, n_singles_a, n_singles_b, kcol_prev, nmax
+ integer*8 :: k8
+
+ maxab = max(N_det_alpha_unique, N_det_beta_unique)+1
+ allocate(idx0(maxab))
+
+ do i=1,maxab
+ idx0(i) = i
+ enddo
+
+ ! Prepare the array of all alpha single excitations
+ ! -------------------------------------------------
+
+ PROVIDE N_int nthreads_davidson
+
+ ! Alpha/Beta double excitations
+ ! =============================
+
+ allocate( buffer($N_int,maxab), &
+ singles_a(maxab), &
+ singles_b(maxab), &
+ doubles(maxab), &
+ idx(maxab))
+
+ kcol_prev=-1
+
+ ASSERT (iend <= N_det)
+ ASSERT (istart > 0)
+ ASSERT (istep > 0)
+
+ do k_a=istart+ishift,iend,istep
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ if (kcol /= kcol_prev) then
+ call get_all_spin_singles_$N_int( &
+ psi_det_beta_unique, idx0, &
+ tmp_det(1,2), N_det_beta_unique, &
+ singles_b, n_singles_b)
+ endif
+ kcol_prev = kcol
+
+ ! Loop over singly excited beta columns
+ ! -------------------------------------
+
+ do i=1,n_singles_b
+ lcol = singles_b(i)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique(1:$N_int, lcol)
+
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ ASSERT (l_a <= N_det)
+
+ do j=1,psi_bilinear_matrix_columns_loc(lcol+1) - l_a
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,j) = psi_det_alpha_unique(1:$N_int, lrow)
+
+ ASSERT (l_a <= N_det)
+ idx(j) = l_a
+ l_a = l_a+1
+ enddo
+ j = j-1
+
+ call get_all_spin_singles_$N_int( &
+ buffer, idx, tmp_det(1,1), j, &
+ singles_a, n_singles_a )
+
+ ! Loop over alpha singles
+ ! -----------------------
+
+ do k = 1,n_singles_a
+ l_a = singles_a(k)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ !!!!!!!!!!!!!!!!!! ALPHA BETA
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ call off_diagonal_double_to_two_rdm_ab_dm(tmp_det,tmp_det2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ enddo
+
+ enddo
+
+ enddo
+
+
+ do k_a=istart+ishift,iend,istep
+
+
+ ! Single and double alpha excitations
+ ! ===================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! ----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,1)
+
+ ! Loop inside the beta column to gather all the connected alphas
+ lcol = psi_bilinear_matrix_columns(k_a)
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ do i=1,N_det_alpha_unique
+ if (l_a > N_det) exit
+ lcol = psi_bilinear_matrix_columns(l_a)
+ if (lcol /= kcol) exit
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,i) = psi_det_alpha_unique(1:$N_int, lrow)
+ idx(i) = l_a
+ l_a = l_a+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_a, doubles, n_singles_a, n_doubles )
+
+ ! Compute Hij for all alpha singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+ do i=1,n_singles_a
+ l_a = singles_a(i)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ !!!! MONO SPIN
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ call off_diagonal_single_to_two_rdm_ab_dm(tmp_det, tmp_det2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+
+ enddo
+
+
+ !! Compute Hij for all alpha doubles
+ !! ----------------------------------
+ !
+ !do i=1,n_doubles
+ ! l_a = doubles(i)
+ ! ASSERT (l_a <= N_det)
+
+ ! lrow = psi_bilinear_matrix_rows(l_a)
+ ! ASSERT (lrow <= N_det_alpha_unique)
+
+ ! call i_H_j_double_spin_erf( tmp_det(1,1), psi_det_alpha_unique(1, lrow), $N_int, hij)
+ ! do l=1,N_st
+ ! v_t(l,k_a) = v_t(l,k_a) + hij * u_t(l,l_a)
+ ! ! same spin => sij = 0
+ ! enddo
+ !enddo
+
+
+
+ ! Single and double beta excitations
+ ! ==================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ kcol = psi_bilinear_matrix_columns(k_a)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,2)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! -----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+
+ ! Loop inside the alpha row to gather all the connected betas
+ lrow = psi_bilinear_matrix_transp_rows(k_b)
+ l_b = psi_bilinear_matrix_transp_rows_loc(lrow)
+ do i=1,N_det_beta_unique
+ if (l_b > N_det) exit
+ lrow = psi_bilinear_matrix_transp_rows(l_b)
+ if (lrow /= krow) exit
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ buffer(1:$N_int,i) = psi_det_beta_unique(1:$N_int, lcol)
+ idx(i) = l_b
+ l_b = l_b+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_b, doubles, n_singles_b, n_doubles )
+
+ ! Compute Hij for all beta singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ do i=1,n_singles_b
+ l_b = singles_b(i)
+ ASSERT (l_b <= N_det)
+
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, lcol)
+ l_a = psi_bilinear_matrix_transp_order(l_b)
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ call off_diagonal_single_to_two_rdm_ab_dm(tmp_det, tmp_det2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ ASSERT (l_a <= N_det)
+ enddo
+ !
+ !! Compute Hij for all beta doubles
+ !! ----------------------------------
+ !
+ !do i=1,n_doubles
+ ! l_b = doubles(i)
+ ! ASSERT (l_b <= N_det)
+
+ ! lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ! ASSERT (lcol <= N_det_beta_unique)
+
+ ! call i_H_j_double_spin_erf( tmp_det(1,2), psi_det_beta_unique(1, lcol), $N_int, hij)
+ ! l_a = psi_bilinear_matrix_transp_order(l_b)
+ ! ASSERT (l_a <= N_det)
+
+ ! do l=1,N_st
+ ! v_t(l,k_a) = v_t(l,k_a) + hij * u_t(l,l_a)
+ ! ! same spin => sij = 0
+ ! enddo
+ !enddo
+
+
+ ! Diagonal contribution
+ ! =====================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ double precision, external :: diag_H_mat_elem_erf, diag_S_mat_elem
+ double precision :: c_1(N_states),c_2(N_states)
+ do l = 1, N_states
+ c_1(l) = u_t(l,k_a)
+ enddo
+
+ call diagonal_contrib_to_two_rdm_ab_dm(tmp_det,c_1,big_array,dim1,dim2,dim3,dim4)
+
+ end do
+ deallocate(buffer, singles_a, singles_b, doubles, idx)
+
+ end
+
+ SUBST [ N_int ]
+
+ 1;;
+ 2;;
+ 3;;
+ 4;;
+ N_int;;
+
+ END_TEMPLATE
diff --git a/src/two_body_rdm/all_2rdm_routines.irp.f b/src/two_body_rdm/all_2rdm_routines.irp.f
new file mode 100644
index 00000000..fa036e6a
--- /dev/null
+++ b/src/two_body_rdm/all_2rdm_routines.irp.f
@@ -0,0 +1,442 @@
+subroutine all_two_rdm_dm_nstates(big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4,u_0,N_st,sze)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes the alpha/alpha, beta/beta and alpha/beta part of the two-body density matrix IN CHEMIST NOTATIONS
+ !
+ ! Assumes that the determinants are in psi_det
+ !
+ ! istart, iend, ishift, istep are used in ZMQ parallelization.
+ END_DOC
+ integer, intent(in) :: N_st,sze
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array_aa(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: big_array_bb(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: big_array_ab(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: u_0(sze,N_st)
+ integer :: k
+ double precision, allocatable :: u_t(:,:)
+ !DIR$ ATTRIBUTES ALIGN : $IRP_ALIGN :: u_t
+ allocate(u_t(N_st,N_det))
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order,N_det)
+ enddo
+ call dtranspose( &
+ u_0, &
+ size(u_0, 1), &
+ u_t, &
+ size(u_t, 1), &
+ N_det, N_st)
+
+ call all_two_rdm_dm_nstates_work(big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4,u_t,N_st,sze,1,N_det,0,1)
+ deallocate(u_t)
+
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order_reverse,N_det)
+ enddo
+
+end
+
+
+subroutine all_two_rdm_dm_nstates_work(big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes two-rdm
+ !
+ ! Default should be 1,N_det,0,1
+ END_DOC
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array_aa(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: big_array_bb(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: big_array_ab(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(in) :: u_t(N_st,N_det)
+
+
+ PROVIDE N_int
+
+ select case (N_int)
+ case (1)
+ call all_two_rdm_dm_nstates_work_1(big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (2)
+ call all_two_rdm_dm_nstates_work_2(big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (3)
+ call all_two_rdm_dm_nstates_work_3(big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (4)
+ call all_two_rdm_dm_nstates_work_4(big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ case default
+ call all_two_rdm_dm_nstates_work_N_int(big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ end select
+end
+
+ BEGIN_TEMPLATE
+
+subroutine all_two_rdm_dm_nstates_work_$N_int(big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes $v_t = H | u_t \\rangle$ and $s_t = S^2 | u_t \\rangle$
+ !
+ ! Default should be 1,N_det,0,1
+ END_DOC
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ double precision, intent(in) :: u_t(N_st,N_det)
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array_aa(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: big_array_bb(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: big_array_ab(dim1,dim2,dim3,dim4,N_states)
+
+ integer :: i,j,k,l
+ integer :: k_a, k_b, l_a, l_b, m_a, m_b
+ integer :: istate
+ integer :: krow, kcol, krow_b, kcol_b
+ integer :: lrow, lcol
+ integer :: mrow, mcol
+ integer(bit_kind) :: spindet($N_int)
+ integer(bit_kind) :: tmp_det($N_int,2)
+ integer(bit_kind) :: tmp_det2($N_int,2)
+ integer(bit_kind) :: tmp_det3($N_int,2)
+ integer(bit_kind), allocatable :: buffer(:,:)
+ integer :: n_doubles
+ integer, allocatable :: doubles(:)
+ integer, allocatable :: singles_a(:)
+ integer, allocatable :: singles_b(:)
+ integer, allocatable :: idx(:), idx0(:)
+ integer :: maxab, n_singles_a, n_singles_b, kcol_prev
+ integer*8 :: k8
+
+ maxab = max(N_det_alpha_unique, N_det_beta_unique)+1
+ allocate(idx0(maxab))
+
+ do i=1,maxab
+ idx0(i) = i
+ enddo
+
+ ! Prepare the array of all alpha single excitations
+ ! -------------------------------------------------
+
+ PROVIDE N_int nthreads_davidson
+ !!$OMP PARALLEL DEFAULT(NONE) NUM_THREADS(nthreads_davidson) &
+ ! !$OMP SHARED(psi_bilinear_matrix_rows, N_det, &
+ ! !$OMP psi_bilinear_matrix_columns, &
+ ! !$OMP psi_det_alpha_unique, psi_det_beta_unique,&
+ ! !$OMP n_det_alpha_unique, n_det_beta_unique, N_int,&
+ ! !$OMP psi_bilinear_matrix_transp_rows, &
+ ! !$OMP psi_bilinear_matrix_transp_columns, &
+ ! !$OMP psi_bilinear_matrix_transp_order, N_st, &
+ ! !$OMP psi_bilinear_matrix_order_transp_reverse, &
+ ! !$OMP psi_bilinear_matrix_columns_loc, &
+ ! !$OMP psi_bilinear_matrix_transp_rows_loc, &
+ ! !$OMP istart, iend, istep, irp_here, v_t, s_t, &
+ ! !$OMP ishift, idx0, u_t, maxab) &
+ ! !$OMP PRIVATE(krow, kcol, tmp_det, spindet, k_a, k_b, i,&
+ ! !$OMP lcol, lrow, l_a, l_b, &
+ ! !$OMP buffer, doubles, n_doubles, &
+ ! !$OMP tmp_det2, idx, l, kcol_prev, &
+ ! !$OMP singles_a, n_singles_a, singles_b, &
+ ! !$OMP n_singles_b, k8)
+
+ ! Alpha/Beta double excitations
+ ! =============================
+
+ allocate( buffer($N_int,maxab), &
+ singles_a(maxab), &
+ singles_b(maxab), &
+ doubles(maxab), &
+ idx(maxab))
+
+ kcol_prev=-1
+
+ ASSERT (iend <= N_det)
+ ASSERT (istart > 0)
+ ASSERT (istep > 0)
+
+ !!$OMP DO SCHEDULE(dynamic,64)
+ do k_a=istart+ishift,iend,istep
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ if (kcol /= kcol_prev) then
+ call get_all_spin_singles_$N_int( &
+ psi_det_beta_unique, idx0, &
+ tmp_det(1,2), N_det_beta_unique, &
+ singles_b, n_singles_b)
+ endif
+ kcol_prev = kcol
+
+ ! Loop over singly excited beta columns
+ ! -------------------------------------
+
+ do i=1,n_singles_b
+ lcol = singles_b(i)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique(1:$N_int, lcol)
+
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ ASSERT (l_a <= N_det)
+
+ do j=1,psi_bilinear_matrix_columns_loc(lcol+1) - l_a
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,j) = psi_det_alpha_unique(1:$N_int, lrow)
+
+ ASSERT (l_a <= N_det)
+ idx(j) = l_a
+ l_a = l_a+1
+ enddo
+ j = j-1
+
+ call get_all_spin_singles_$N_int( &
+ buffer, idx, tmp_det(1,1), j, &
+ singles_a, n_singles_a )
+
+ ! Loop over alpha singles
+ ! -----------------------
+
+ do k = 1,n_singles_a
+ l_a = singles_a(k)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ !call i_H_j_double_alpha_beta(tmp_det,tmp_det2,$N_int,hij)
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ call off_diagonal_double_to_two_rdm_ab_dm(tmp_det,tmp_det2,c_1,c_2,big_array_ab,dim1,dim2,dim3,dim4)
+ enddo
+
+ enddo
+
+ enddo
+ ! !$OMP END DO
+
+ ! !$OMP DO SCHEDULE(dynamic,64)
+ do k_a=istart+ishift,iend,istep
+
+
+ ! Single and double alpha exitations
+ ! ===================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! ----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+ ASSERT (k_b <= N_det)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,1)
+
+ ! Loop inside the beta column to gather all the connected alphas
+ lcol = psi_bilinear_matrix_columns(k_a)
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ do i=1,N_det_alpha_unique
+ if (l_a > N_det) exit
+ lcol = psi_bilinear_matrix_columns(l_a)
+ if (lcol /= kcol) exit
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,i) = psi_det_alpha_unique(1:$N_int, lrow)
+ idx(i) = l_a
+ l_a = l_a+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_a, doubles, n_singles_a, n_doubles )
+
+ ! Compute Hij for all alpha singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+ do i=1,n_singles_a
+ l_a = singles_a(i)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ ! increment the alpha/beta part for single excitations
+ call off_diagonal_single_to_two_rdm_ab_dm(tmp_det, tmp_det2,c_1,c_2,big_array_ab,dim1,dim2,dim3,dim4)
+ ! increment the alpha/alpha part for single excitations
+ call off_diagonal_single_to_two_rdm_aa_dm(tmp_det,tmp_det2,c_1,c_2,big_array_aa,dim1,dim2,dim3,dim4)
+
+ enddo
+
+
+ ! Compute Hij for all alpha doubles
+ ! ----------------------------------
+
+ do i=1,n_doubles
+ l_a = doubles(i)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ call off_diagonal_double_to_two_rdm_aa_dm(tmp_det(1,1),psi_det_alpha_unique(1, lrow),c_1,c_2,big_array_aa,dim1,dim2,dim3,dim4)
+ enddo
+
+
+ ! Single and double beta excitations
+ ! ==================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ kcol = psi_bilinear_matrix_columns(k_a)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,2)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! -----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+ ASSERT (k_b <= N_det)
+
+ ! Loop inside the alpha row to gather all the connected betas
+ lrow = psi_bilinear_matrix_transp_rows(k_b)
+ l_b = psi_bilinear_matrix_transp_rows_loc(lrow)
+ do i=1,N_det_beta_unique
+ if (l_b > N_det) exit
+ lrow = psi_bilinear_matrix_transp_rows(l_b)
+ if (lrow /= krow) exit
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ buffer(1:$N_int,i) = psi_det_beta_unique(1:$N_int, lcol)
+ idx(i) = l_b
+ l_b = l_b+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_b, doubles, n_singles_b, n_doubles )
+
+ ! Compute Hij for all beta singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ do i=1,n_singles_b
+ l_b = singles_b(i)
+ ASSERT (l_b <= N_det)
+
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, lcol)
+ l_a = psi_bilinear_matrix_transp_order(l_b)
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ ! increment the alpha/beta part for single excitations
+ call off_diagonal_single_to_two_rdm_ab_dm(tmp_det, tmp_det2,c_1,c_2,big_array_ab,dim1,dim2,dim3,dim4)
+ ! increment the beta /beta part for single excitations
+ call off_diagonal_single_to_two_rdm_bb_dm(tmp_det, tmp_det2,c_1,c_2,big_array_bb,dim1,dim2,dim3,dim4)
+ enddo
+
+ ! Compute Hij for all beta doubles
+ ! ----------------------------------
+
+ do i=1,n_doubles
+ l_b = doubles(i)
+ ASSERT (l_b <= N_det)
+
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ l_a = psi_bilinear_matrix_transp_order(l_b)
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ enddo
+ call off_diagonal_double_to_two_rdm_bb_dm(tmp_det(1,2),psi_det_beta_unique(1, lcol),c_1,c_2,big_array_bb,dim1,dim2,dim3,dim4)
+ ASSERT (l_a <= N_det)
+
+ enddo
+
+
+ ! Diagonal contribution
+ ! =====================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ double precision, external :: diag_wee_mat_elem, diag_S_mat_elem
+
+ double precision :: c_1(N_states),c_2(N_states)
+ do l = 1, N_states
+ c_1(l) = u_t(l,k_a)
+ enddo
+
+ call diagonal_contrib_to_all_two_rdm_dm(tmp_det,c_1,big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4)
+
+ end do
+ !!$OMP END DO
+ deallocate(buffer, singles_a, singles_b, doubles, idx)
+ !!$OMP END PARALLEL
+
+end
+
+ SUBST [ N_int ]
+
+ 1;;
+ 2;;
+ 3;;
+ 4;;
+ N_int;;
+
+ END_TEMPLATE
+
diff --git a/src/two_body_rdm/all_states_2_rdm.irp.f b/src/two_body_rdm/all_states_2_rdm.irp.f
new file mode 100644
index 00000000..bc503223
--- /dev/null
+++ b/src/two_body_rdm/all_states_2_rdm.irp.f
@@ -0,0 +1,83 @@
+
+
+
+ BEGIN_PROVIDER [double precision, all_states_act_two_rdm_alpha_alpha_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb,N_states)]
+ implicit none
+ double precision, allocatable :: state_weights(:)
+ BEGIN_DOC
+! all_states_act_two_rdm_alpha_alpha_mo(i,j,k,l) = state average physicist two-body rdm restricted to the ACTIVE indices for alpha-alpha electron pairs
+! =
+ END_DOC
+ allocate(state_weights(N_states))
+ state_weights = 1.d0/dble(N_states)
+ integer :: ispin
+ ! condition for alpha/beta spin
+ ispin = 1
+ all_states_act_two_rdm_alpha_alpha_mo = 0.D0
+ call orb_range_all_states_two_rdm(all_states_act_two_rdm_alpha_alpha_mo,n_act_orb,n_act_orb,list_act,list_act_reverse,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, all_states_act_two_rdm_beta_beta_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb,N_states)]
+ implicit none
+ double precision, allocatable :: state_weights(:)
+ BEGIN_DOC
+! all_states_act_two_rdm_beta_beta_mo(i,j,k,l) = state average physicist two-body rdm restricted to the ACTIVE indices for beta-beta electron pairs
+! =
+ END_DOC
+ allocate(state_weights(N_states))
+ state_weights = 1.d0/dble(N_states)
+ integer :: ispin
+ ! condition for alpha/beta spin
+ ispin = 2
+ all_states_act_two_rdm_beta_beta_mo = 0.d0
+ call orb_range_all_states_two_rdm(all_states_act_two_rdm_beta_beta_mo,n_act_orb,n_act_orb,list_act,list_act_reverse,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, all_states_act_two_rdm_alpha_beta_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb,N_states)]
+ implicit none
+ double precision, allocatable :: state_weights(:)
+ BEGIN_DOC
+! all_states_act_two_rdm_alpha_beta_mo(i,j,k,l) = state average physicist two-body rdm restricted to the ACTIVE indices for alpha-beta electron pairs
+! =
+ END_DOC
+ allocate(state_weights(N_states))
+ state_weights = 1.d0/dble(N_states)
+ integer :: ispin
+ ! condition for alpha/beta spin
+ print*,''
+ print*,''
+ print*,''
+ print*,'providint all_states_act_two_rdm_alpha_beta_mo '
+ ispin = 3
+ print*,'ispin = ',ispin
+ all_states_act_two_rdm_alpha_beta_mo = 0.d0
+ call orb_range_all_states_two_rdm(all_states_act_two_rdm_alpha_beta_mo,n_act_orb,n_act_orb,list_act,list_act_reverse,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ END_PROVIDER
+
+
+ BEGIN_PROVIDER [double precision, all_states_act_two_rdm_spin_trace_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb,N_states)]
+ implicit none
+ BEGIN_DOC
+! all_states_act_two_rdm_spin_trace_mo(i,j,k,l) = state average physicist spin trace two-body rdm restricted to the ACTIVE indices
+! The active part of the two-electron energy can be computed as:
+!
+! \sum_{i,j,k,l = 1, n_act_orb} all_states_act_two_rdm_spin_trace_mo(i,j,k,l) * < ii jj | kk ll >
+!
+! with ii = list_act(i), jj = list_act(j), kk = list_act(k), ll = list_act(l)
+ END_DOC
+ double precision, allocatable :: state_weights(:)
+ allocate(state_weights(N_states))
+ state_weights = 1.d0/dble(N_states)
+ integer :: ispin
+ ! condition for alpha/beta spin
+ ispin = 4
+ all_states_act_two_rdm_spin_trace_mo = 0.d0
+ integer :: i
+
+ call orb_range_all_states_two_rdm(all_states_act_two_rdm_spin_trace_mo,n_act_orb,n_act_orb,list_act,list_act_reverse,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ END_PROVIDER
+
diff --git a/src/two_body_rdm/all_states_routines.irp.f b/src/two_body_rdm/all_states_routines.irp.f
new file mode 100644
index 00000000..8f40f32a
--- /dev/null
+++ b/src/two_body_rdm/all_states_routines.irp.f
@@ -0,0 +1,495 @@
+subroutine orb_range_all_states_two_rdm(big_array,dim1,norb,list_orb,list_orb_reverse,ispin,u_0,N_st,sze)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! if ispin == 1 :: alpha/alpha 2rdm
+ ! == 2 :: beta /beta 2rdm
+ ! == 3 :: alpha/beta 2rdm
+ ! == 4 :: spin traced 2rdm :: aa + bb + 0.5 (ab + ba))
+ !
+ ! Assumes that the determinants are in psi_det
+ !
+ ! istart, iend, ishift, istep are used in ZMQ parallelization.
+ END_DOC
+ integer, intent(in) :: N_st,sze
+ integer, intent(in) :: dim1,norb,list_orb(norb),ispin
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+ double precision, intent(in) :: u_0(sze,N_st)
+
+ integer :: k
+ double precision, allocatable :: u_t(:,:)
+ !DIR$ ATTRIBUTES ALIGN : $IRP_ALIGN :: u_t
+ allocate(u_t(N_st,N_det))
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order,N_det)
+ enddo
+ call dtranspose( &
+ u_0, &
+ size(u_0, 1), &
+ u_t, &
+ size(u_t, 1), &
+ N_det, N_st)
+
+ call orb_range_all_states_two_rdm_work(big_array,dim1,norb,list_orb,list_orb_reverse,ispin,u_t,N_st,sze,1,N_det,0,1)
+ deallocate(u_t)
+
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order_reverse,N_det)
+ enddo
+
+end
+
+subroutine orb_range_all_states_two_rdm_work(big_array,dim1,norb,list_orb,list_orb_reverse,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes two-rdm
+ !
+ ! Default should be 1,N_det,0,1
+ END_DOC
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ integer, intent(in) :: dim1,norb,list_orb(norb),ispin
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+ double precision, intent(in) :: u_t(N_st,N_det)
+
+ integer :: k
+
+ PROVIDE N_int
+
+ select case (N_int)
+ case (1)
+ call orb_range_all_states_two_rdm_work_1(big_array,dim1,norb,list_orb,list_orb_reverse,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (2)
+ call orb_range_all_states_two_rdm_work_2(big_array,dim1,norb,list_orb,list_orb_reverse,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (3)
+ call orb_range_all_states_two_rdm_work_3(big_array,dim1,norb,list_orb,list_orb_reverse,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (4)
+ call orb_range_all_states_two_rdm_work_4(big_array,dim1,norb,list_orb,list_orb_reverse,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case default
+ call orb_range_all_states_two_rdm_work_N_int(big_array,dim1,norb,list_orb,list_orb_reverse,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ end select
+end
+
+
+
+
+ BEGIN_TEMPLATE
+subroutine orb_range_all_states_two_rdm_work_$N_int(big_array,dim1,norb,list_orb,list_orb_reverse,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes the two rdm for the N_st vectors |u_t>
+ ! if ispin == 1 :: alpha/alpha 2rdm
+ ! == 2 :: beta /beta 2rdm
+ ! == 3 :: alpha/beta 2rdm
+ ! == 4 :: spin traced 2rdm :: aa + bb + 0.5 (ab + ba))
+ ! The 2rdm will be computed only on the list of orbitals list_orb, which contains norb
+ ! Default should be 1,N_det,0,1 for istart,iend,ishift,istep
+ END_DOC
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ double precision, intent(in) :: u_t(N_st,N_det)
+ integer, intent(in) :: dim1,norb,list_orb(norb),ispin
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+
+ integer :: i,j,k,l
+ integer :: k_a, k_b, l_a, l_b, m_a, m_b
+ integer :: istate
+ integer :: krow, kcol, krow_b, kcol_b
+ integer :: lrow, lcol
+ integer :: mrow, mcol
+ integer(bit_kind) :: spindet($N_int)
+ integer(bit_kind) :: tmp_det($N_int,2)
+ integer(bit_kind) :: tmp_det2($N_int,2)
+ integer(bit_kind) :: tmp_det3($N_int,2)
+ integer(bit_kind), allocatable :: buffer(:,:)
+ integer :: n_doubles
+ integer, allocatable :: doubles(:)
+ integer, allocatable :: singles_a(:)
+ integer, allocatable :: singles_b(:)
+ integer, allocatable :: idx(:), idx0(:)
+ integer :: maxab, n_singles_a, n_singles_b, kcol_prev
+ integer*8 :: k8
+ double precision,allocatable :: c_contrib(:)
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ integer(bit_kind) :: orb_bitmask($N_int)
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ else
+ print*,'Wrong parameter for ispin in general_two_rdm_dm_nstates_work'
+ print*,'ispin = ',ispin
+ stop
+ endif
+
+ PROVIDE N_int
+
+ call list_to_bitstring( orb_bitmask, list_orb, norb, N_int)
+
+ maxab = max(N_det_alpha_unique, N_det_beta_unique)+1
+ allocate(idx0(maxab))
+
+ do i=1,maxab
+ idx0(i) = i
+ enddo
+
+ ! Prepare the array of all alpha single excitations
+ ! -------------------------------------------------
+
+ PROVIDE N_int nthreads_davidson
+ !!$OMP PARALLEL DEFAULT(NONE) NUM_THREADS(nthreads_davidson) &
+ ! !$OMP SHARED(psi_bilinear_matrix_rows, N_det, &
+ ! !$OMP psi_bilinear_matrix_columns, &
+ ! !$OMP psi_det_alpha_unique, psi_det_beta_unique,&
+ ! !$OMP n_det_alpha_unique, n_det_beta_unique, N_int,&
+ ! !$OMP psi_bilinear_matrix_transp_rows, &
+ ! !$OMP psi_bilinear_matrix_transp_columns, &
+ ! !$OMP psi_bilinear_matrix_transp_order, N_st, &
+ ! !$OMP psi_bilinear_matrix_order_transp_reverse, &
+ ! !$OMP psi_bilinear_matrix_columns_loc, &
+ ! !$OMP psi_bilinear_matrix_transp_rows_loc, &
+ ! !$OMP istart, iend, istep, irp_here, v_t, s_t, &
+ ! !$OMP ishift, idx0, u_t, maxab) &
+ ! !$OMP PRIVATE(krow, kcol, tmp_det, spindet, k_a, k_b, i,&
+ ! !$OMP lcol, lrow, l_a, l_b, &
+ ! !$OMP buffer, doubles, n_doubles, &
+ ! !$OMP tmp_det2, idx, l, kcol_prev, &
+ ! !$OMP singles_a, n_singles_a, singles_b, &
+ ! !$OMP n_singles_b, k8)
+
+ ! Alpha/Beta double excitations
+ ! =============================
+
+ allocate( buffer($N_int,maxab), &
+ singles_a(maxab), &
+ singles_b(maxab), &
+ doubles(maxab), &
+ idx(maxab),c_contrib(N_st))
+
+ kcol_prev=-1
+
+ ASSERT (iend <= N_det)
+ ASSERT (istart > 0)
+ ASSERT (istep > 0)
+
+ !!$OMP DO SCHEDULE(dynamic,64)
+ do k_a=istart+ishift,iend,istep
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ if (kcol /= kcol_prev) then
+ call get_all_spin_singles_$N_int( &
+ psi_det_beta_unique, idx0, &
+ tmp_det(1,2), N_det_beta_unique, &
+ singles_b, n_singles_b)
+ endif
+ kcol_prev = kcol
+
+ ! Loop over singly excited beta columns
+ ! -------------------------------------
+
+ do i=1,n_singles_b
+ lcol = singles_b(i)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique(1:$N_int, lcol)
+
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ ASSERT (l_a <= N_det)
+
+ do j=1,psi_bilinear_matrix_columns_loc(lcol+1) - l_a
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,j) = psi_det_alpha_unique(1:$N_int, lrow)
+
+ ASSERT (l_a <= N_det)
+ idx(j) = l_a
+ l_a = l_a+1
+ enddo
+ j = j-1
+
+ call get_all_spin_singles_$N_int( &
+ buffer, idx, tmp_det(1,1), j, &
+ singles_a, n_singles_a )
+
+ ! Loop over alpha singles
+ ! -----------------------
+
+ if(alpha_beta.or.spin_trace)then
+ do k = 1,n_singles_a
+ l_a = singles_a(k)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ c_contrib = 0.d0
+ do l= 1, N_st
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_contrib(l) = c_1(l) * c_2(l)
+ enddo
+ call orb_range_off_diagonal_double_to_two_rdm_ab_dm_all_states(tmp_det,tmp_det2,c_contrib,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ enddo
+ endif
+
+ enddo
+
+ enddo
+ ! !$OMP END DO
+
+ ! !$OMP DO SCHEDULE(dynamic,64)
+ do k_a=istart+ishift,iend,istep
+
+
+ ! Single and double alpha exitations
+ ! ===================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! ----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+ ASSERT (k_b <= N_det)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,1)
+
+ ! Loop inside the beta column to gather all the connected alphas
+ lcol = psi_bilinear_matrix_columns(k_a)
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ do i=1,N_det_alpha_unique
+ if (l_a > N_det) exit
+ lcol = psi_bilinear_matrix_columns(l_a)
+ if (lcol /= kcol) exit
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,i) = psi_det_alpha_unique(1:$N_int, lrow)
+ idx(i) = l_a
+ l_a = l_a+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_a, doubles, n_singles_a, n_doubles )
+
+ ! Compute Hij for all alpha singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+ do i=1,n_singles_a
+ l_a = singles_a(i)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ c_contrib = 0.d0
+ do l= 1, N_st
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_contrib(l) = c_1(l) * c_2(l)
+ enddo
+ if(alpha_beta.or.spin_trace.or.alpha_alpha)then
+ ! increment the alpha/beta part for single excitations
+ call orb_range_off_diagonal_single_to_two_rdm_ab_dm_all_states(tmp_det, tmp_det2,c_contrib,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ ! increment the alpha/alpha part for single excitations
+ call orb_range_off_diagonal_single_to_two_rdm_aa_dm_all_states(tmp_det,tmp_det2,c_contrib,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ endif
+
+ enddo
+
+
+ ! Compute Hij for all alpha doubles
+ ! ----------------------------------
+
+ if(alpha_alpha.or.spin_trace)then
+ do i=1,n_doubles
+ l_a = doubles(i)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ c_contrib = 0.d0
+ do l= 1, N_st
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_contrib(l) += c_1(l) * c_2(l)
+ enddo
+ call orb_range_off_diagonal_double_to_two_rdm_aa_dm_all_states(tmp_det(1,1),psi_det_alpha_unique(1, lrow),c_contrib,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ enddo
+ endif
+
+
+ ! Single and double beta excitations
+ ! ==================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ kcol = psi_bilinear_matrix_columns(k_a)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,2)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! -----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+ ASSERT (k_b <= N_det)
+
+ ! Loop inside the alpha row to gather all the connected betas
+ lrow = psi_bilinear_matrix_transp_rows(k_b)
+ l_b = psi_bilinear_matrix_transp_rows_loc(lrow)
+ do i=1,N_det_beta_unique
+ if (l_b > N_det) exit
+ lrow = psi_bilinear_matrix_transp_rows(l_b)
+ if (lrow /= krow) exit
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ buffer(1:$N_int,i) = psi_det_beta_unique(1:$N_int, lcol)
+ idx(i) = l_b
+ l_b = l_b+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_b, doubles, n_singles_b, n_doubles )
+
+ ! Compute Hij for all beta singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ do i=1,n_singles_b
+ l_b = singles_b(i)
+ ASSERT (l_b <= N_det)
+
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, lcol)
+ l_a = psi_bilinear_matrix_transp_order(l_b)
+ c_contrib = 0.d0
+ do l= 1, N_st
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_contrib(l) = c_1(l) * c_2(l)
+ enddo
+ if(alpha_beta.or.spin_trace.or.beta_beta)then
+ ! increment the alpha/beta part for single excitations
+ call orb_range_off_diagonal_single_to_two_rdm_ab_dm_all_states(tmp_det, tmp_det2,c_contrib,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ ! increment the beta /beta part for single excitations
+ call orb_range_off_diagonal_single_to_two_rdm_bb_dm_all_states(tmp_det, tmp_det2,c_contrib,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ endif
+ enddo
+
+ ! Compute Hij for all beta doubles
+ ! ----------------------------------
+
+ if(beta_beta.or.spin_trace)then
+ do i=1,n_doubles
+ l_b = doubles(i)
+ ASSERT (l_b <= N_det)
+
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ l_a = psi_bilinear_matrix_transp_order(l_b)
+ c_contrib = 0.d0
+ do l= 1, N_st
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_contrib(l) = c_1(l) * c_2(l)
+ enddo
+ call orb_range_off_diagonal_double_to_two_rdm_bb_dm_all_states(tmp_det(1,2),psi_det_beta_unique(1, lcol),c_contrib,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ ASSERT (l_a <= N_det)
+
+ enddo
+ endif
+
+
+ ! Diagonal contribution
+ ! =====================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ double precision, external :: diag_wee_mat_elem, diag_S_mat_elem
+
+ double precision :: c_1(N_states),c_2(N_states)
+ c_contrib = 0.d0
+ do l = 1, N_st
+ c_1(l) = u_t(l,k_a)
+ c_contrib(l) = c_1(l) * c_1(l)
+ enddo
+
+ call orb_range_diagonal_contrib_to_all_two_rdm_dm_all_states(tmp_det,c_contrib,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+
+ end do
+ !!$OMP END DO
+ deallocate(buffer, singles_a, singles_b, doubles, idx)
+ !!$OMP END PARALLEL
+
+end
+
+ SUBST [ N_int ]
+
+ 1;;
+ 2;;
+ 3;;
+ 4;;
+ N_int;;
+
+ END_TEMPLATE
+
diff --git a/src/two_body_rdm/compute.irp.f b/src/two_body_rdm/compute.irp.f
new file mode 100644
index 00000000..112d2e36
--- /dev/null
+++ b/src/two_body_rdm/compute.irp.f
@@ -0,0 +1,269 @@
+
+
+ subroutine diagonal_contrib_to_two_rdm_ab_dm(det_1,c_1,big_array,dim1,dim2,dim3,dim4)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the DIAGONAL PART of the alpha/beta two body rdm IN CHEMIST NOTATIONS
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int,2)
+ double precision, intent(in) :: c_1(N_states)
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate
+ double precision :: c_1_bis
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ do istate = 1, N_states
+ c_1_bis = c_1(istate) * c_1(istate)
+ do i = 1, n_occ_ab(1)
+ h1 = occ(i,1)
+ do j = 1, n_occ_ab(2)
+ h2 = occ(j,2)
+ big_array(h1,h1,h2,h2,istate) += c_1_bis
+ enddo
+ enddo
+ enddo
+ end
+
+
+ subroutine diagonal_contrib_to_all_two_rdm_dm(det_1,c_1,big_array_aa,big_array_bb,big_array_ab,dim1,dim2,dim3,dim4)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the DIAGONAL PART of ALL THREE two body rdm IN CHEMIST NOTATIONS
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array_ab(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: big_array_aa(dim1,dim2,dim3,dim4,N_states)
+ double precision, intent(inout) :: big_array_bb(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int,2)
+ double precision, intent(in) :: c_1(N_states)
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate
+ double precision :: c_1_bis
+ BEGIN_DOC
+! no factor 1/2 have to be taken into account as the permutations are already taken into account
+ END_DOC
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ do istate = 1, N_states
+ c_1_bis = c_1(istate) * c_1(istate)
+ do i = 1, n_occ_ab(1)
+ h1 = occ(i,1)
+ do j = 1, n_occ_ab(2)
+ h2 = occ(j,2)
+ big_array_ab(h1,h1,h2,h2,istate) += c_1_bis
+ enddo
+ do j = 1, n_occ_ab(1)
+ h2 = occ(j,1)
+ big_array_aa(h1,h1,h2,h2,istate) += 0.5d0 * c_1_bis
+ big_array_aa(h1,h2,h2,h1,istate) -= 0.5d0 * c_1_bis
+ enddo
+ enddo
+ do i = 1, n_occ_ab(2)
+ h1 = occ(i,2)
+ do j = 1, n_occ_ab(2)
+ h2 = occ(j,2)
+ big_array_bb(h1,h1,h2,h2,istate) += 0.5d0 * c_1_bis
+ big_array_bb(h1,h2,h2,h1,istate) -= 0.5d0 * c_1_bis
+ enddo
+ enddo
+ enddo
+ end
+
+
+ subroutine off_diagonal_double_to_two_rdm_ab_dm(det_1,det_2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the alpha/beta 2RDM only for DOUBLE EXCITATIONS IN CHEMIST NOTATIONS
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ double precision, intent(in) :: c_1(N_states),c_2(N_states)
+ integer :: i,j,h1,h2,p1,p2,istate
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ call get_double_excitation(det_1,det_2,exc,phase,N_int)
+ h1 = exc(1,1,1)
+ h2 = exc(1,1,2)
+ p1 = exc(1,2,1)
+ p2 = exc(1,2,2)
+ do istate = 1, N_states
+ big_array(h1,p1,h2,p2,istate) += c_1(istate) * phase * c_2(istate)
+! big_array(p1,h1,p2,h2,istate) += c_1(istate) * phase * c_2(istate)
+ enddo
+ end
+
+ subroutine off_diagonal_single_to_two_rdm_ab_dm(det_1,det_2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the alpha/beta 2RDM only for SINGLE EXCITATIONS IN CHEMIST NOTATIONS
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ double precision, intent(in) :: c_1(N_states),c_2(N_states)
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ p1 = exc(1,2,1)
+ do istate = 1, N_states
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ big_array(h1,p1,h2,h2,istate) += 1.d0 * c_1(istate) * c_2(istate) * phase
+ enddo
+ enddo
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ p1 = exc(1,2,2)
+ do istate = 1, N_states
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ big_array(h2,h2,h1,p1,istate) += 1.d0 * c_1(istate) * c_2(istate) * phase
+ enddo
+ enddo
+ endif
+ end
+
+ subroutine off_diagonal_single_to_two_rdm_aa_dm(det_1,det_2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the alpha/alpha 2RDM only for SINGLE EXCITATIONS IN CHEMIST NOTATIONS
+ END_DOC
+ use bitmasks
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ double precision, intent(in) :: c_1(N_states),c_2(N_states)
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ p1 = exc(1,2,1)
+ do istate = 1, N_states
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ big_array(h1,p1,h2,h2,istate) += 0.5d0 * c_1(istate) * c_2(istate) * phase
+ big_array(h1,h2,h2,p1,istate) -= 0.5d0 * c_1(istate) * c_2(istate) * phase
+
+ big_array(h2,h2,h1,p1,istate) += 0.5d0 * c_1(istate) * c_2(istate) * phase
+ big_array(h2,p1,h1,h2,istate) -= 0.5d0 * c_1(istate) * c_2(istate) * phase
+ enddo
+ enddo
+ else
+ return
+ endif
+ end
+
+ subroutine off_diagonal_single_to_two_rdm_bb_dm(det_1,det_2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the beta /beta 2RDM only for SINGLE EXCITATIONS IN CHEMIST NOTATIONS
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ double precision, intent(in) :: c_1(N_states),c_2(N_states)
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if (exc(0,1,1) == 1) then
+ return
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ p1 = exc(1,2,2)
+ do istate = 1, N_states
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ big_array(h1,p1,h2,h2,istate) += 0.5d0 * c_1(istate) * c_2(istate) * phase
+ big_array(h1,h2,h2,p1,istate) -= 0.5d0 * c_1(istate) * c_2(istate) * phase
+
+ big_array(h2,h2,h1,p1,istate) += 0.5d0 * c_1(istate) * c_2(istate) * phase
+ big_array(h2,p1,h1,h2,istate) -= 0.5d0 * c_1(istate) * c_2(istate) * phase
+ enddo
+ enddo
+ endif
+ end
+
+
+ subroutine off_diagonal_double_to_two_rdm_aa_dm(det_1,det_2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the alpha/alpha 2RDM only for DOUBLE EXCITATIONS IN CHEMIST NOTATIONS
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int),det_2(N_int)
+ double precision, intent(in) :: c_1(N_states),c_2(N_states)
+ integer :: i,j,h1,h2,p1,p2,istate
+ integer :: exc(0:2,2)
+ double precision :: phase
+ call get_double_excitation_spin(det_1,det_2,exc,phase,N_int)
+ h1 =exc(1,1)
+ h2 =exc(2,1)
+ p1 =exc(1,2)
+ p2 =exc(2,2)
+!print*,'h1,p1,h2,p2',h1,p1,h2,p2,c_1(istate) * phase * c_2(istate)
+ do istate = 1, N_states
+ big_array(h1,p1,h2,p2,istate) += 0.5d0 * c_1(istate) * phase * c_2(istate)
+ big_array(h1,p2,h2,p1,istate) -= 0.5d0 * c_1(istate) * phase * c_2(istate)
+
+ big_array(h2,p2,h1,p1,istate) += 0.5d0 * c_1(istate) * phase * c_2(istate)
+ big_array(h2,p1,h1,p2,istate) -= 0.5d0 * c_1(istate) * phase * c_2(istate)
+ enddo
+ end
+
+ subroutine off_diagonal_double_to_two_rdm_bb_dm(det_1,det_2,c_1,c_2,big_array,dim1,dim2,dim3,dim4)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the beta /beta 2RDM only for DOUBLE EXCITATIONS
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,dim2,dim3,dim4
+ double precision, intent(inout) :: big_array(dim1,dim2,dim3,dim4,N_states)
+ integer(bit_kind), intent(in) :: det_1(N_int),det_2(N_int)
+ double precision, intent(in) :: c_1(N_states),c_2(N_states)
+ integer :: i,j,h1,h2,p1,p2,istate
+ integer :: exc(0:2,2)
+ double precision :: phase
+ call get_double_excitation_spin(det_1,det_2,exc,phase,N_int)
+ h1 =exc(1,1)
+ h2 =exc(2,1)
+ p1 =exc(1,2)
+ p2 =exc(2,2)
+!print*,'h1,p1,h2,p2',h1,p1,h2,p2,c_1(istate) * phase * c_2(istate)
+ do istate = 1, N_states
+ big_array(h1,p1,h2,p2,istate) += 0.5d0 * c_1(istate) * phase * c_2(istate)
+ big_array(h1,p2,h2,p1,istate) -= 0.5d0 * c_1(istate) * phase * c_2(istate)
+
+ big_array(h2,p2,h1,p1,istate) += 0.5d0 * c_1(istate) * phase * c_2(istate)
+ big_array(h2,p1,h1,p2,istate) -= 0.5d0 * c_1(istate) * phase * c_2(istate)
+ enddo
+ end
+
diff --git a/src/two_body_rdm/compute_all_states.irp.f b/src/two_body_rdm/compute_all_states.irp.f
new file mode 100644
index 00000000..7606e353
--- /dev/null
+++ b/src/two_body_rdm/compute_all_states.irp.f
@@ -0,0 +1,660 @@
+
+ subroutine orb_range_diagonal_contrib_to_two_rdm_ab_dm_all_states(det_1,c_1,N_st,big_array,dim1,orb_bitmask)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the DIAGONAL PART of the alpha/beta two body rdm in a specific range of orbitals
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,N_st
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+ integer(bit_kind), intent(in) :: det_1(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ double precision, intent(in) :: c_1(N_st)
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ do istate = 1, N_st
+ do i = 1, n_occ_ab(1)
+ h1 = occ(i,1)
+ do j = 1, n_occ_ab(2)
+ h2 = occ(j,2)
+ big_array(h1,h2,h1,h2,istate) += c_1(istate)
+ enddo
+ enddo
+ enddo
+ end
+
+
+ subroutine orb_range_diagonal_contrib_to_all_two_rdm_dm_all_states(det_1,c_1,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the DIAGONAL PART of the two body rdms in a specific range of orbitals for a given determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1,N_st) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,N_st,ispin
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+ integer(bit_kind), intent(in) :: det_1(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ double precision, intent(in) :: c_1(N_st)
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate
+ integer(bit_kind) :: det_1_act(N_int,2)
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ do i = 1, N_int
+ det_1_act(i,1) = iand(det_1(i,1),orb_bitmask(i))
+ det_1_act(i,2) = iand(det_1(i,2),orb_bitmask(i))
+ enddo
+
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+ call bitstring_to_list_ab(det_1_act, occ, n_occ_ab, N_int)
+ logical :: is_integer_in_string
+ integer :: i1,i2
+ if(alpha_beta)then
+ do istate = 1, N_st
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2,istate) += c_1(istate)
+ enddo
+ enddo
+ enddo
+ else if (alpha_alpha)then
+ do istate = 1, N_st
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+ do j = 1, n_occ_ab(1)
+ i2 = occ(j,1)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2,istate) += 0.5d0 * c_1(istate)
+ big_array(h1,h2,h2,h1,istate) -= 0.5d0 * c_1(istate)
+ enddo
+ enddo
+ enddo
+ else if (beta_beta)then
+ do istate = 1, N_st
+ do i = 1, n_occ_ab(2)
+ i1 = occ(i,2)
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2,istate) += 0.5d0 * c_1(istate)
+ big_array(h1,h2,h2,h1,istate) -= 0.5d0 * c_1(istate)
+ enddo
+ enddo
+ enddo
+ else if(spin_trace)then
+ ! 0.5 * (alpha beta + beta alpha)
+ do istate = 1, N_st
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2,istate) += 0.5d0 * c_1(istate)
+ big_array(h2,h1,h2,h1,istate) += 0.5d0 * c_1(istate)
+ enddo
+ enddo
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+ do j = 1, n_occ_ab(1)
+ i2 = occ(j,1)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2,istate) += 0.5d0 * c_1(istate)
+ big_array(h1,h2,h2,h1,istate) -= 0.5d0 * c_1(istate)
+ enddo
+ enddo
+ do i = 1, n_occ_ab(2)
+ i1 = occ(i,2)
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2,istate) += 0.5d0 * c_1(istate)
+ big_array(h1,h2,h2,h1,istate) -= 0.5d0 * c_1(istate)
+ enddo
+ enddo
+ enddo
+ endif
+ end
+
+
+ subroutine orb_range_off_diagonal_double_to_two_rdm_ab_dm_all_states(det_1,det_2,c_1,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a alpha/beta DOUBLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1,N_st) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 3 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,N_st,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1(N_st)
+ integer :: i,j,h1,h2,p1,p2,istate
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+ call get_double_excitation(det_1,det_2,exc,phase,N_int)
+ h1 = exc(1,1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ h2 = exc(1,1,2)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))return
+ h2 = list_orb_reverse(h2)
+ p1 = exc(1,2,1)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ p2 = exc(1,2,2)
+ if(.not.is_integer_in_string(p2,orb_bitmask,N_int))return
+ p2 = list_orb_reverse(p2)
+ do istate = 1, N_st
+ if(alpha_beta)then
+ big_array(h1,h2,p1,p2,istate) += c_1(istate) * phase
+ else if(spin_trace)then
+ big_array(h1,h2,p1,p2,istate) += 0.5d0 * c_1(istate) * phase
+ big_array(p1,p2,h1,h2,istate) += 0.5d0 * c_1(istate) * phase
+ endif
+ enddo
+ end
+
+ subroutine orb_range_off_diagonal_single_to_two_rdm_ab_dm_all_states(det_1,det_2,c_1,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a SINGLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1,N_st) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 3 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,N_st,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1(N_st)
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if(alpha_beta)then
+ do istate = 1, N_st
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,1)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h1,h2,p1,h2,istate) += c_1(istate) * phase
+ enddo
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,2)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h2,h1,h2,p1,istate) += c_1(istate) * phase
+ enddo
+ endif
+ enddo
+ else if(spin_trace)then
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,1)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do istate = 1, N_st
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h1,h2,p1,h2,istate) += 0.5d0 * c_1(istate) * phase
+ big_array(h2,h1,h2,p1,istate) += 0.5d0 * c_1(istate) * phase
+ enddo
+ enddo
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,2)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do istate = 1, N_st
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h1,h2,p1,h2,istate) += 0.5d0 * c_1(istate) * phase
+ big_array(h2,h1,h2,p1,istate) += 0.5d0 * c_1(istate) * phase
+ enddo
+ enddo
+ endif
+ endif
+ end
+
+ subroutine orb_range_off_diagonal_single_to_two_rdm_aa_dm_all_states(det_1,det_2,c_1,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a ALPHA SINGLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1,N_st) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 1 or 4 will do something
+ END_DOC
+ use bitmasks
+ implicit none
+ integer, intent(in) :: dim1,N_st,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1(N_st)
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if(alpha_alpha.or.spin_trace)then
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,1)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do istate = 1, N_st
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h1,h2,p1,h2,istate) += 0.5d0 * c_1(istate) * phase
+ big_array(h1,h2,h2,p1,istate) -= 0.5d0 * c_1(istate) * phase
+
+ big_array(h2,h1,h2,p1,istate) += 0.5d0 * c_1(istate) * phase
+ big_array(h2,h1,p1,h2,istate) -= 0.5d0 * c_1(istate) * phase
+ enddo
+ enddo
+ else
+ return
+ endif
+ endif
+ end
+
+ subroutine orb_range_off_diagonal_single_to_two_rdm_bb_dm_all_states(det_1,det_2,c_1,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a BETA SINGLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1,N_st) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 2 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,N_st,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1(N_st)
+
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,istate,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if(beta_beta.or.spin_trace)then
+ if (exc(0,1,1) == 1) then
+ return
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,2)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do istate = 1, N_st
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h1,h2,p1,h2,istate) += 0.5d0 * c_1(istate) * phase
+ big_array(h1,h2,h2,p1,istate) -= 0.5d0 * c_1(istate) * phase
+
+ big_array(h2,h1,h2,p1,istate) += 0.5d0 * c_1(istate) * phase
+ big_array(h2,h1,p1,h2,istate) -= 0.5d0 * c_1(istate) * phase
+ enddo
+ enddo
+ endif
+ endif
+ end
+
+
+ subroutine orb_range_off_diagonal_double_to_two_rdm_aa_dm_all_states(det_1,det_2,c_1,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a ALPHA/ALPHA DOUBLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1,N_st) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 1 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,N_st,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+ integer(bit_kind), intent(in) :: det_1(N_int),det_2(N_int)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1(N_st)
+
+ integer :: i,j,h1,h2,p1,p2,istate
+ integer :: exc(0:2,2)
+ double precision :: phase
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+ call get_double_excitation_spin(det_1,det_2,exc,phase,N_int)
+ h1 =exc(1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ h2 =exc(2,1)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))return
+ h2 = list_orb_reverse(h2)
+ p1 =exc(1,2)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ p2 =exc(2,2)
+ if(.not.is_integer_in_string(p2,orb_bitmask,N_int))return
+ p2 = list_orb_reverse(p2)
+ if(alpha_alpha.or.spin_trace)then
+ do istate = 1, N_st
+ big_array(h1,h2,p1,p2,istate) += 0.5d0 * c_1(istate) * phase
+ big_array(h1,h2,p2,p1,istate) -= 0.5d0 * c_1(istate) * phase
+
+ big_array(h2,h1,p2,p1,istate) += 0.5d0 * c_1(istate) * phase
+ big_array(h2,h1,p1,p2,istate) -= 0.5d0 * c_1(istate) * phase
+ enddo
+ endif
+ end
+
+ subroutine orb_range_off_diagonal_double_to_two_rdm_bb_dm_all_states(det_1,det_2,c_1,N_st,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a BETA /BETA DOUBLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1,N_st) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 2 or 4 will do something
+ END_DOC
+ implicit none
+
+ integer, intent(in) :: dim1,N_st,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st)
+ integer(bit_kind), intent(in) :: det_1(N_int),det_2(N_int)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1(N_st)
+
+ integer :: i,j,h1,h2,p1,p2,istate
+ integer :: exc(0:2,2)
+ double precision :: phase
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+ call get_double_excitation_spin(det_1,det_2,exc,phase,N_int)
+ h1 =exc(1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ h2 =exc(2,1)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))return
+ h2 = list_orb_reverse(h2)
+ p1 =exc(1,2)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ p2 =exc(2,2)
+ if(.not.is_integer_in_string(p2,orb_bitmask,N_int))return
+ p2 = list_orb_reverse(p2)
+ do istate = 1, N_st
+ if(beta_beta.or.spin_trace)then
+ big_array(h1,h2,p1,p2,istate) += 0.5d0 * c_1(istate)* phase
+ big_array(h1,h2,p2,p1,istate) -= 0.5d0 * c_1(istate)* phase
+
+ big_array(h2,h1,p2,p1,istate) += 0.5d0 * c_1(istate)* phase
+ big_array(h2,h1,p1,p2,istate) -= 0.5d0 * c_1(istate)* phase
+ endif
+ enddo
+ end
+
diff --git a/src/two_body_rdm/compute_orb_range.irp.f b/src/two_body_rdm/compute_orb_range.irp.f
new file mode 100644
index 00000000..52cccbf3
--- /dev/null
+++ b/src/two_body_rdm/compute_orb_range.irp.f
@@ -0,0 +1,670 @@
+
+ subroutine orb_range_diagonal_contrib_to_two_rdm_ab_dm(det_1,c_1,big_array,dim1,orb_bitmask)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the DIAGONAL PART of the alpha/beta two body rdm in a specific range of orbitals
+! c_1 is supposed to be a scalar quantity, such as state averaged coef
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ integer(bit_kind), intent(in) :: det_1(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ double precision, intent(in) :: c_1
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ do i = 1, n_occ_ab(1)
+ h1 = occ(i,1)
+ do j = 1, n_occ_ab(2)
+ h2 = occ(j,2)
+ big_array(h1,h2,h1,h2) += c_1
+ enddo
+ enddo
+ end
+
+
+ subroutine orb_range_diagonal_contrib_to_all_two_rdm_dm(det_1,c_1,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the DIAGONAL PART of the two body rdms in a specific range of orbitals for a given determinant det_1
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,ispin
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ integer(bit_kind), intent(in) :: det_1(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ double precision, intent(in) :: c_1
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2
+ integer(bit_kind) :: det_1_act(N_int,2)
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ do i = 1, N_int
+ det_1_act(i,1) = iand(det_1(i,1),orb_bitmask(i))
+ det_1_act(i,2) = iand(det_1(i,2),orb_bitmask(i))
+ enddo
+
+!print*,'ahah'
+!call debug_det(det_1_act,N_int)
+!pause
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+ BEGIN_DOC
+! no factor 1/2 have to be taken into account as the permutations are already taken into account
+ END_DOC
+ call bitstring_to_list_ab(det_1_act, occ, n_occ_ab, N_int)
+ logical :: is_integer_in_string
+ integer :: i1,i2
+ if(alpha_beta)then
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+! if(.not.is_integer_in_string(i1,orb_bitmask,N_int))cycle
+ do j = 1, n_occ_ab(2)
+! if(.not.is_integer_in_string(i2,orb_bitmask,N_int))cycle
+ i2 = occ(j,2)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2) += c_1
+ enddo
+ enddo
+ else if (alpha_alpha)then
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+! if(.not.is_integer_in_string(i1,orb_bitmask,N_int))cycle
+ do j = 1, n_occ_ab(1)
+ i2 = occ(j,1)
+! if(.not.is_integer_in_string(i2,orb_bitmask,N_int))cycle
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2) += 0.5d0 * c_1
+ big_array(h1,h2,h2,h1) -= 0.5d0 * c_1
+ enddo
+ enddo
+ else if (beta_beta)then
+ do i = 1, n_occ_ab(2)
+ i1 = occ(i,2)
+! if(.not.is_integer_in_string(i1,orb_bitmask,N_int))cycle
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+! if(.not.is_integer_in_string(i2,orb_bitmask,N_int))cycle
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2) += 0.5d0 * c_1
+ big_array(h1,h2,h2,h1) -= 0.5d0 * c_1
+ enddo
+ enddo
+ else if(spin_trace)then
+ ! 0.5 * (alpha beta + beta alpha)
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+! if(.not.is_integer_in_string(i1,orb_bitmask,N_int))cycle
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+! if(.not.is_integer_in_string(i2,orb_bitmask,N_int))cycle
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2) += 0.5d0 * (c_1 )
+ big_array(h2,h1,h2,h1) += 0.5d0 * (c_1 )
+ enddo
+ enddo
+ !stop
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+! if(.not.is_integer_in_string(i1,orb_bitmask,N_int))cycle
+ do j = 1, n_occ_ab(1)
+ i2 = occ(j,1)
+! if(.not.is_integer_in_string(i2,orb_bitmask,N_int))cycle
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2) += 0.5d0 * c_1
+ big_array(h1,h2,h2,h1) -= 0.5d0 * c_1
+ enddo
+ enddo
+ do i = 1, n_occ_ab(2)
+ i1 = occ(i,2)
+! if(.not.is_integer_in_string(i1,orb_bitmask,N_int))cycle
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+! if(.not.is_integer_in_string(i2,orb_bitmask,N_int))cycle
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ big_array(h1,h2,h1,h2) += 0.5d0 * c_1
+ big_array(h1,h2,h2,h1) -= 0.5d0 * c_1
+ enddo
+ enddo
+ endif
+ end
+
+
+ subroutine orb_range_off_diagonal_double_to_two_rdm_ab_dm(det_1,det_2,c_1,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a alpha/beta DOUBLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 3 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+ integer :: i,j,h1,h2,p1,p2
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+!print*,''
+!do i = 1, mo_num
+! print*,'list_orb',i,list_orb_reverse(i)
+!enddo
+ call get_double_excitation(det_1,det_2,exc,phase,N_int)
+ h1 = exc(1,1,1)
+!print*,'h1',h1
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+!print*,'passed h1 = ',h1
+ h2 = exc(1,1,2)
+!print*,'h2',h2
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))return
+ h2 = list_orb_reverse(h2)
+!print*,'passed h2 = ',h2
+ p1 = exc(1,2,1)
+!print*,'p1',p1
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+!print*,'passed p1 = ',p1
+ p2 = exc(1,2,2)
+!print*,'p2',p2
+ if(.not.is_integer_in_string(p2,orb_bitmask,N_int))return
+ p2 = list_orb_reverse(p2)
+!print*,'passed p2 = ',p2
+ if(alpha_beta)then
+ big_array(h1,h2,p1,p2) += c_1 * phase
+ else if(spin_trace)then
+ big_array(h1,h2,p1,p2) += 0.5d0 * c_1 * phase
+ big_array(p1,p2,h1,h2) += 0.5d0 * c_1 * phase
+ !print*,'h1,h2,p1,p2',h1,h2,p1,p2
+ !print*,'',big_array(h1,h2,p1,p2)
+ endif
+ end
+
+ subroutine orb_range_off_diagonal_single_to_two_rdm_ab_dm(det_1,det_2,c_1,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a SINGLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 3 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if(alpha_beta)then
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,1)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h1,h2,p1,h2) += c_1 * phase
+ enddo
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,2)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h2,h1,h2,p1) += c_1 * phase
+ enddo
+ endif
+ else if(spin_trace)then
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,1)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h1,h2,p1,h2) += 0.5d0 * c_1 * phase
+ big_array(h2,h1,h2,p1) += 0.5d0 * c_1 * phase
+ enddo
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,2)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h1,h2,p1,h2) += 0.5d0 * c_1 * phase
+ big_array(h2,h1,h2,p1) += 0.5d0 * c_1 * phase
+ enddo
+ endif
+ endif
+ end
+
+ subroutine orb_range_off_diagonal_single_to_two_rdm_aa_dm(det_1,det_2,c_1,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a ALPHA SINGLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 1 or 4 will do something
+ END_DOC
+ use bitmasks
+ implicit none
+ integer, intent(in) :: dim1,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if(alpha_alpha.or.spin_trace)then
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,1)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h1,h2,p1,h2) += 0.5d0 * c_1 * phase
+ big_array(h1,h2,h2,p1) -= 0.5d0 * c_1 * phase
+
+ big_array(h2,h1,h2,p1) += 0.5d0 * c_1 * phase
+ big_array(h2,h1,p1,h2) -= 0.5d0 * c_1 * phase
+ enddo
+ else
+ return
+ endif
+ endif
+ end
+
+ subroutine orb_range_off_diagonal_single_to_two_rdm_bb_dm(det_1,det_2,c_1,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a BETA SINGLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 2 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if(beta_beta.or.spin_trace)then
+ if (exc(0,1,1) == 1) then
+ return
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,2)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))cycle
+ h2 = list_orb_reverse(h2)
+ big_array(h1,h2,p1,h2) += 0.5d0 * c_1 * phase
+ big_array(h1,h2,h2,p1) -= 0.5d0 * c_1 * phase
+
+ big_array(h2,h1,h2,p1) += 0.5d0 * c_1 * phase
+ big_array(h2,h1,p1,h2) -= 0.5d0 * c_1 * phase
+ enddo
+ endif
+ endif
+ end
+
+
+ subroutine orb_range_off_diagonal_double_to_two_rdm_aa_dm(det_1,det_2,c_1,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a ALPHA/ALPHA DOUBLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 1 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: dim1,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ integer(bit_kind), intent(in) :: det_1(N_int),det_2(N_int)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+
+ integer :: i,j,h1,h2,p1,p2
+ integer :: exc(0:2,2)
+ double precision :: phase
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+ call get_double_excitation_spin(det_1,det_2,exc,phase,N_int)
+ h1 =exc(1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ h2 =exc(2,1)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))return
+ h2 = list_orb_reverse(h2)
+ p1 =exc(1,2)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ p2 =exc(2,2)
+ if(.not.is_integer_in_string(p2,orb_bitmask,N_int))return
+ p2 = list_orb_reverse(p2)
+ if(alpha_alpha.or.spin_trace)then
+ big_array(h1,h2,p1,p2) += 0.5d0 * c_1 * phase
+ big_array(h1,h2,p2,p1) -= 0.5d0 * c_1 * phase
+
+ big_array(h2,h1,p2,p1) += 0.5d0 * c_1 * phase
+ big_array(h2,h1,p1,p2) -= 0.5d0 * c_1 * phase
+ endif
+ end
+
+ subroutine orb_range_off_diagonal_double_to_two_rdm_bb_dm(det_1,det_2,c_1,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a BETA /BETA DOUBLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 2 or 4 will do something
+ END_DOC
+ implicit none
+
+ integer, intent(in) :: dim1,ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ integer(bit_kind), intent(in) :: det_1(N_int),det_2(N_int)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+
+ integer :: i,j,h1,h2,p1,p2
+ integer :: exc(0:2,2)
+ double precision :: phase
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+ call get_double_excitation_spin(det_1,det_2,exc,phase,N_int)
+ h1 =exc(1,1)
+ if(.not.is_integer_in_string(h1,orb_bitmask,N_int))return
+ h1 = list_orb_reverse(h1)
+ h2 =exc(2,1)
+ if(.not.is_integer_in_string(h2,orb_bitmask,N_int))return
+ h2 = list_orb_reverse(h2)
+ p1 =exc(1,2)
+ if(.not.is_integer_in_string(p1,orb_bitmask,N_int))return
+ p1 = list_orb_reverse(p1)
+ p2 =exc(2,2)
+ if(.not.is_integer_in_string(p2,orb_bitmask,N_int))return
+ p2 = list_orb_reverse(p2)
+ if(beta_beta.or.spin_trace)then
+ big_array(h1,h2,p1,p2) += 0.5d0 * c_1* phase
+ big_array(h1,h2,p2,p1) -= 0.5d0 * c_1* phase
+
+ big_array(h2,h1,p2,p1) += 0.5d0 * c_1* phase
+ big_array(h2,h1,p1,p2) -= 0.5d0 * c_1* phase
+ endif
+ end
+
diff --git a/src/two_body_rdm/compute_orb_range_omp.irp.f b/src/two_body_rdm/compute_orb_range_omp.irp.f
new file mode 100644
index 00000000..0ba934d7
--- /dev/null
+++ b/src/two_body_rdm/compute_orb_range_omp.irp.f
@@ -0,0 +1,807 @@
+ subroutine orb_range_diag_to_all_two_rdm_dm_buffer(det_1,c_1,orb_bitmask,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ use bitmasks
+ BEGIN_DOC
+ ! routine that update the DIAGONAL PART of the two body rdms in a specific range of orbitals for a given determinant det_1
+ !
+ ! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+ !
+ ! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+ !
+ ! ispin determines which spin-spin component of the two-rdm you will update
+ !
+ ! ispin == 1 :: alpha/ alpha
+ ! ispin == 2 :: beta / beta
+ ! ispin == 3 :: alpha/ beta
+ ! ispin == 4 :: spin traced <=> total two-rdm
+ END_DOC
+ implicit none
+ integer, intent(in) :: ispin,sze_buff
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ integer(bit_kind), intent(in) :: det_1(N_int,2)
+ integer(bit_kind), intent(in) :: orb_bitmask(N_int)
+ double precision, intent(in) :: c_1
+ double precision, intent(out) :: values(sze_buff)
+ integer , intent(out) :: keys(4,sze_buff)
+ integer , intent(inout):: nkeys
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2
+ integer(bit_kind) :: det_1_act(N_int,2)
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ do i = 1, N_int
+ det_1_act(i,1) = iand(det_1(i,1),orb_bitmask(i))
+ det_1_act(i,2) = iand(det_1(i,2),orb_bitmask(i))
+ enddo
+
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+ call bitstring_to_list_ab(det_1_act, occ, n_occ_ab, N_int)
+ logical :: is_integer_in_string
+ integer :: i1,i2
+ if(alpha_beta)then
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ nkeys += 1
+ values(nkeys) = c_1
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h1
+ keys(4,nkeys) = h2
+ enddo
+ enddo
+ else if (alpha_alpha)then
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+ do j = 1, n_occ_ab(1)
+ i2 = occ(j,1)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h1
+ keys(4,nkeys) = h2
+ nkeys += 1
+ values(nkeys) = -0.5d0 * c_1
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = h1
+ enddo
+ enddo
+ else if (beta_beta)then
+ do i = 1, n_occ_ab(2)
+ i1 = occ(i,2)
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h1
+ keys(4,nkeys) = h2
+ nkeys += 1
+ values(nkeys) = -0.5d0 * c_1
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = h1
+ enddo
+ enddo
+ else if(spin_trace)then
+ ! 0.5 * (alpha beta + beta alpha)
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h1
+ keys(4,nkeys) = h2
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = h1
+ enddo
+ enddo
+ do i = 1, n_occ_ab(1)
+ i1 = occ(i,1)
+ do j = 1, n_occ_ab(1)
+ i2 = occ(j,1)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h1
+ keys(4,nkeys) = h2
+ nkeys += 1
+ values(nkeys) = -0.5d0 * c_1
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = h1
+ enddo
+ enddo
+ do i = 1, n_occ_ab(2)
+ i1 = occ(i,2)
+ do j = 1, n_occ_ab(2)
+ i2 = occ(j,2)
+ h1 = list_orb_reverse(i1)
+ h2 = list_orb_reverse(i2)
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h1
+ keys(4,nkeys) = h2
+ nkeys += 1
+ values(nkeys) = -0.5d0 * c_1
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = h1
+ enddo
+ enddo
+ endif
+ end
+
+
+ subroutine orb_range_off_diag_double_to_two_rdm_ab_dm_buffer(det_1,det_2,c_1,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ use bitmasks
+ BEGIN_DOC
+! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+!
+! a given couple of determinant det_1, det_2 being a alpha/beta DOUBLE excitation with respect to one another
+!
+! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+!
+! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+!
+! ispin determines which spin-spin component of the two-rdm you will update
+!
+! ispin == 1 :: alpha/ alpha
+! ispin == 2 :: beta / beta
+! ispin == 3 :: alpha/ beta
+! ispin == 4 :: spin traced <=> total two-rdm
+!
+! here, only ispin == 3 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: ispin,sze_buff
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+ double precision, intent(out) :: values(sze_buff)
+ integer , intent(out) :: keys(4,sze_buff)
+ integer , intent(inout):: nkeys
+ integer :: i,j,h1,h2,p1,p2
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+ call get_double_excitation(det_1,det_2,exc,phase,N_int)
+ h1 = exc(1,1,1)
+ if(list_orb_reverse(h1).lt.0)return
+ h1 = list_orb_reverse(h1)
+ h2 = exc(1,1,2)
+ if(list_orb_reverse(h2).lt.0)return
+ h2 = list_orb_reverse(h2)
+ p1 = exc(1,2,1)
+ if(list_orb_reverse(p1).lt.0)return
+ p1 = list_orb_reverse(p1)
+ p2 = exc(1,2,2)
+ if(list_orb_reverse(p2).lt.0)return
+ p2 = list_orb_reverse(p2)
+ if(alpha_beta)then
+ nkeys += 1
+ values(nkeys) = c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = p2
+ else if(spin_trace)then
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = p2
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = p1
+ keys(2,nkeys) = p2
+ keys(3,nkeys) = h1
+ keys(4,nkeys) = h2
+ endif
+ end
+
+ subroutine orb_range_off_diag_single_to_two_rdm_ab_dm_buffer(det_1,det_2,c_1,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ use bitmasks
+ BEGIN_DOC
+ ! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+ !
+ ! a given couple of determinant det_1, det_2 being a SINGLE excitation with respect to one another
+ !
+ ! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+ !
+ ! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+ !
+ ! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+ !
+ ! ispin determines which spin-spin component of the two-rdm you will update
+ !
+ ! ispin == 1 :: alpha/ alpha
+ ! ispin == 2 :: beta / beta
+ ! ispin == 3 :: alpha/ beta
+ ! ispin == 4 :: spin traced <=> total two-rdm
+ !
+ ! here, only ispin == 3 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: ispin,sze_buff
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+ double precision, intent(out) :: values(sze_buff)
+ integer , intent(out) :: keys(4,sze_buff)
+ integer , intent(inout):: nkeys
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if(alpha_beta)then
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ if(list_orb_reverse(h1).lt.0)return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,1)
+ if(list_orb_reverse(p1).lt.0)return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ if(list_orb_reverse(h2).lt.0)return
+ h2 = list_orb_reverse(h2)
+ nkeys += 1
+ values(nkeys) = c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = h2
+ enddo
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ if(list_orb_reverse(h1).lt.0)return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,2)
+ if(list_orb_reverse(p1).lt.0)return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ if(list_orb_reverse(h2).lt.0)return
+ h2 = list_orb_reverse(h2)
+ nkeys += 1
+ values(nkeys) = c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = h2
+ enddo
+ endif
+ else if(spin_trace)then
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ if(list_orb_reverse(h1).lt.0)return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,1)
+ if(list_orb_reverse(p1).lt.0)return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ if(list_orb_reverse(h2).lt.0)return
+ h2 = list_orb_reverse(h2)
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = h2
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = p1
+ enddo
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ if(list_orb_reverse(h1).lt.0)return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,2)
+ if(list_orb_reverse(p1).lt.0)return
+ p1 = list_orb_reverse(p1)
+ !print*,'****************'
+ !print*,'****************'
+ !print*,'h1,p1',h1,p1
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ if(list_orb_reverse(h2).lt.0)return
+ h2 = list_orb_reverse(h2)
+ ! print*,'h2 = ',h2
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = h2
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = p1
+ enddo
+ endif
+ endif
+ end
+
+ subroutine orb_range_off_diag_single_to_two_rdm_aa_dm_buffer(det_1,det_2,c_1,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ BEGIN_DOC
+ ! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+ !
+ ! a given couple of determinant det_1, det_2 being a ALPHA SINGLE excitation with respect to one another
+ !
+ ! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+ !
+ ! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+ !
+ ! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+ !
+ ! ispin determines which spin-spin component of the two-rdm you will update
+ !
+ ! ispin == 1 :: alpha/ alpha
+ ! ispin == 2 :: beta / beta
+ ! ispin == 3 :: alpha/ beta
+ ! ispin == 4 :: spin traced <=> total two-rdm
+ !
+ ! here, only ispin == 1 or 4 will do something
+ END_DOC
+ use bitmasks
+ implicit none
+ integer, intent(in) :: ispin,sze_buff
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+ double precision, intent(out) :: values(sze_buff)
+ integer , intent(out) :: keys(4,sze_buff)
+ integer , intent(inout):: nkeys
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if(alpha_alpha.or.spin_trace)then
+ if (exc(0,1,1) == 1) then
+ ! Mono alpha
+ h1 = exc(1,1,1)
+ if(list_orb_reverse(h1).lt.0)return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,1)
+ if(list_orb_reverse(p1).lt.0)return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(1)
+ h2 = occ(i,1)
+ if(list_orb_reverse(h2).lt.0)return
+ h2 = list_orb_reverse(h2)
+
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = h2
+
+ nkeys += 1
+ values(nkeys) = - 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = p1
+
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = p1
+
+ nkeys += 1
+ values(nkeys) = - 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = h2
+ enddo
+ else
+ return
+ endif
+ endif
+ end
+
+ subroutine orb_range_off_diag_single_to_two_rdm_bb_dm_buffer(det_1,det_2,c_1,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ use bitmasks
+ BEGIN_DOC
+ ! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+ !
+ ! a given couple of determinant det_1, det_2 being a BETA SINGLE excitation with respect to one another
+ !
+ ! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+ !
+ ! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+ !
+ ! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+ !
+ ! ispin determines which spin-spin component of the two-rdm you will update
+ !
+ ! ispin == 1 :: alpha/ alpha
+ ! ispin == 2 :: beta / beta
+ ! ispin == 3 :: alpha/ beta
+ ! ispin == 4 :: spin traced <=> total two-rdm
+ !
+ ! here, only ispin == 2 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: ispin,sze_buff
+ integer(bit_kind), intent(in) :: det_1(N_int,2),det_2(N_int,2)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+ double precision, intent(out) :: values(sze_buff)
+ integer , intent(out) :: keys(4,sze_buff)
+ integer , intent(inout):: nkeys
+
+ integer :: occ(N_int*bit_kind_size,2)
+ integer :: n_occ_ab(2)
+ integer :: i,j,h1,h2,p1
+ integer :: exc(0:2,2,2)
+ double precision :: phase
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+
+ call bitstring_to_list_ab(det_1, occ, n_occ_ab, N_int)
+ call get_single_excitation(det_1,det_2,exc,phase,N_int)
+ if(beta_beta.or.spin_trace)then
+ if (exc(0,1,1) == 1) then
+ return
+ else
+ ! Mono beta
+ h1 = exc(1,1,2)
+ if(list_orb_reverse(h1).lt.0)return
+ h1 = list_orb_reverse(h1)
+ p1 = exc(1,2,2)
+ if(list_orb_reverse(p1).lt.0)return
+ p1 = list_orb_reverse(p1)
+ do i = 1, n_occ_ab(2)
+ h2 = occ(i,2)
+ if(list_orb_reverse(h2).lt.0)return
+ h2 = list_orb_reverse(h2)
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = h2
+
+ nkeys += 1
+ values(nkeys) = - 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = p1
+
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = h2
+ keys(4,nkeys) = p1
+
+ nkeys += 1
+ values(nkeys) = - 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = h2
+ enddo
+ endif
+ endif
+ end
+
+
+ subroutine orb_range_off_diag_double_to_two_rdm_aa_dm_buffer(det_1,det_2,c_1,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ use bitmasks
+ BEGIN_DOC
+ ! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+ !
+ ! a given couple of determinant det_1, det_2 being a ALPHA/ALPHA DOUBLE excitation with respect to one another
+ !
+ ! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+ !
+ ! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+ !
+ ! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+ !
+ ! ispin determines which spin-spin component of the two-rdm you will update
+ !
+ ! ispin == 1 :: alpha/ alpha
+ ! ispin == 2 :: beta / beta
+ ! ispin == 3 :: alpha/ beta
+ ! ispin == 4 :: spin traced <=> total two-rdm
+ !
+ ! here, only ispin == 1 or 4 will do something
+ END_DOC
+ implicit none
+ integer, intent(in) :: ispin,sze_buff
+ integer(bit_kind), intent(in) :: det_1(N_int),det_2(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+ double precision, intent(out) :: values(sze_buff)
+ integer , intent(out) :: keys(4,sze_buff)
+ integer , intent(inout):: nkeys
+
+
+ integer :: i,j,h1,h2,p1,p2
+ integer :: exc(0:2,2)
+ double precision :: phase
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+ call get_double_excitation_spin(det_1,det_2,exc,phase,N_int)
+ h1 =exc(1,1)
+ if(list_orb_reverse(h1).lt.0)return
+ h1 = list_orb_reverse(h1)
+ h2 =exc(2,1)
+ if(list_orb_reverse(h2).lt.0)return
+ h2 = list_orb_reverse(h2)
+ p1 =exc(1,2)
+ if(list_orb_reverse(p1).lt.0)return
+ p1 = list_orb_reverse(p1)
+ p2 =exc(2,2)
+ if(list_orb_reverse(p2).lt.0)return
+ p2 = list_orb_reverse(p2)
+ if(alpha_alpha.or.spin_trace)then
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = p2
+
+ nkeys += 1
+ values(nkeys) = - 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p2
+ keys(4,nkeys) = p1
+
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = p2
+ keys(4,nkeys) = p1
+
+ nkeys += 1
+ values(nkeys) = - 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = p2
+ endif
+ end
+
+ subroutine orb_range_off_diag_double_to_two_rdm_bb_dm_buffer(det_1,det_2,c_1,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ use bitmasks
+ BEGIN_DOC
+ ! routine that update the OFF DIAGONAL PART of the two body rdms in a specific range of orbitals for
+ !
+ ! a given couple of determinant det_1, det_2 being a BETA /BETA DOUBLE excitation with respect to one another
+ !
+ ! c_1 is supposed to be a scalar quantity, such as state averaged coef of the determinant det_1
+ !
+ ! big_array(dim1,dim1,dim1,dim1) is the two-body rdm to be updated in physicist notation
+ !
+ ! orb_bitmask(N_int) is the bitmask for the orbital range, list_orb_reverse(mo_num) is the inverse range of orbitals
+ !
+ ! ispin determines which spin-spin component of the two-rdm you will update
+ !
+ ! ispin == 1 :: alpha/ alpha
+ ! ispin == 2 :: beta / beta
+ ! ispin == 3 :: alpha/ beta
+ ! ispin == 4 :: spin traced <=> total two-rdm
+ !
+ ! here, only ispin == 2 or 4 will do something
+ END_DOC
+ implicit none
+
+ integer, intent(in) :: ispin,sze_buff
+ integer(bit_kind), intent(in) :: det_1(N_int),det_2(N_int)
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(in) :: c_1
+ double precision, intent(out) :: values(sze_buff)
+ integer , intent(out) :: keys(4,sze_buff)
+ integer , intent(inout):: nkeys
+
+ integer :: i,j,h1,h2,p1,p2
+ integer :: exc(0:2,2)
+ double precision :: phase
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ logical :: is_integer_in_string
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ endif
+
+ call get_double_excitation_spin(det_1,det_2,exc,phase,N_int)
+ h1 =exc(1,1)
+ if(list_orb_reverse(h1).lt.0)return
+ h1 = list_orb_reverse(h1)
+ h2 =exc(2,1)
+ if(list_orb_reverse(h2).lt.0)return
+ h2 = list_orb_reverse(h2)
+ p1 =exc(1,2)
+ if(list_orb_reverse(p1).lt.0)return
+ p1 = list_orb_reverse(p1)
+ p2 =exc(2,2)
+ if(list_orb_reverse(p2).lt.0)return
+ p2 = list_orb_reverse(p2)
+ if(beta_beta.or.spin_trace)then
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = p2
+
+ nkeys += 1
+ values(nkeys) = - 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h1
+ keys(2,nkeys) = h2
+ keys(3,nkeys) = p2
+ keys(4,nkeys) = p1
+
+ nkeys += 1
+ values(nkeys) = 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = p2
+ keys(4,nkeys) = p1
+
+ nkeys += 1
+ values(nkeys) = - 0.5d0 * c_1 * phase
+ keys(1,nkeys) = h2
+ keys(2,nkeys) = h1
+ keys(3,nkeys) = p1
+ keys(4,nkeys) = p2
+ endif
+ end
+
diff --git a/src/two_body_rdm/orb_range.irp.f b/src/two_body_rdm/orb_range.irp.f
new file mode 100644
index 00000000..2bcd04dc
--- /dev/null
+++ b/src/two_body_rdm/orb_range.irp.f
@@ -0,0 +1,89 @@
+
+
+
+ BEGIN_PROVIDER [double precision, state_av_act_two_rdm_alpha_alpha_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb)]
+ implicit none
+ double precision, allocatable :: state_weights(:)
+ BEGIN_DOC
+! state_av_act_two_rdm_alpha_alpha_mo(i,j,k,l) = state average physicist two-body rdm restricted to the ACTIVE indices for alpha-alpha electron pairs
+! =
+ END_DOC
+ allocate(state_weights(N_states))
+ state_weights = state_average_weight
+ integer :: ispin
+ ! condition for alpha/beta spin
+ ispin = 1
+ state_av_act_two_rdm_alpha_alpha_mo = 0.D0
+ call orb_range_two_rdm_state_av(state_av_act_two_rdm_alpha_alpha_mo,n_act_orb,n_act_orb,list_act,list_act_reverse,state_weights,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, state_av_act_two_rdm_beta_beta_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb)]
+ implicit none
+ double precision, allocatable :: state_weights(:)
+ BEGIN_DOC
+! state_av_act_two_rdm_beta_beta_mo(i,j,k,l) = state average physicist two-body rdm restricted to the ACTIVE indices for beta-beta electron pairs
+! =
+ END_DOC
+ allocate(state_weights(N_states))
+ state_weights = state_average_weight
+ integer :: ispin
+ ! condition for alpha/beta spin
+ ispin = 2
+ state_av_act_two_rdm_beta_beta_mo = 0.d0
+ call orb_range_two_rdm_state_av(state_av_act_two_rdm_beta_beta_mo,n_act_orb,n_act_orb,list_act,list_act_reverse,state_weights,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, state_av_act_two_rdm_alpha_beta_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb)]
+ implicit none
+ double precision, allocatable :: state_weights(:)
+ BEGIN_DOC
+! state_av_act_two_rdm_alpha_beta_mo(i,j,k,l) = state average physicist two-body rdm restricted to the ACTIVE indices for alpha-beta electron pairs
+! =
+ END_DOC
+ allocate(state_weights(N_states))
+ state_weights = state_average_weight
+ integer :: ispin
+ ! condition for alpha/beta spin
+ print*,''
+ print*,''
+ print*,''
+ print*,'providint state_av_act_two_rdm_alpha_beta_mo '
+ ispin = 3
+ print*,'ispin = ',ispin
+ state_av_act_two_rdm_alpha_beta_mo = 0.d0
+ call orb_range_two_rdm_state_av(state_av_act_two_rdm_alpha_beta_mo,n_act_orb,n_act_orb,list_act,list_act_reverse,state_weights,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ END_PROVIDER
+
+
+ BEGIN_PROVIDER [double precision, state_av_act_two_rdm_spin_trace_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb)]
+ implicit none
+ BEGIN_DOC
+! state_av_act_two_rdm_spin_trace_mo(i,j,k,l) = state average physicist spin trace two-body rdm restricted to the ACTIVE indices
+! The active part of the two-electron energy can be computed as:
+!
+! \sum_{i,j,k,l = 1, n_act_orb} state_av_act_two_rdm_spin_trace_mo(i,j,k,l) * < ii jj | kk ll >
+!
+! with ii = list_act(i), jj = list_act(j), kk = list_act(k), ll = list_act(l)
+ END_DOC
+ double precision, allocatable :: state_weights(:)
+ allocate(state_weights(N_states))
+ state_weights = state_average_weight
+ integer :: ispin
+ ! condition for alpha/beta spin
+ ispin = 4
+ state_av_act_two_rdm_spin_trace_mo = 0.d0
+ integer :: i
+ double precision :: wall_0,wall_1
+ call wall_time(wall_0)
+ print*,'providing the state average TWO-RDM ...'
+ print*,'psi_det_size = ',psi_det_size
+ print*,'N_det = ',N_det
+ call orb_range_two_rdm_state_av(state_av_act_two_rdm_spin_trace_mo,n_act_orb,n_act_orb,list_act,list_act_reverse,state_weights,ispin,psi_coef,N_states,size(psi_coef,1))
+
+ call wall_time(wall_1)
+ print*,'Time to provide the state average TWO-RDM',wall_1 - wall_0
+ END_PROVIDER
+
diff --git a/src/two_body_rdm/orb_range_omp.irp.f b/src/two_body_rdm/orb_range_omp.irp.f
new file mode 100644
index 00000000..baa26ced
--- /dev/null
+++ b/src/two_body_rdm/orb_range_omp.irp.f
@@ -0,0 +1,85 @@
+
+ BEGIN_PROVIDER [double precision, state_av_act_two_rdm_openmp_alpha_alpha_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb)]
+ implicit none
+ double precision, allocatable :: state_weights(:)
+ BEGIN_DOC
+! state_av_act_two_rdm_openmp_alpha_alpha_mo(i,j,k,l) = state average physicist two-body rdm restricted to the ACTIVE indices for alpha-alpha electron pairs
+! =
+ END_DOC
+ allocate(state_weights(N_states))
+ state_weights = state_average_weight
+ integer :: ispin
+ ! condition for alpha/beta spin
+ ispin = 1
+ state_av_act_two_rdm_openmp_alpha_alpha_mo = 0.D0
+ call orb_range_two_rdm_state_av_openmp(state_av_act_two_rdm_openmp_alpha_alpha_mo,n_act_orb,n_act_orb,list_act,state_weights,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, state_av_act_two_rdm_openmp_beta_beta_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb)]
+ implicit none
+ double precision, allocatable :: state_weights(:)
+ BEGIN_DOC
+! state_av_act_two_rdm_openmp_beta_beta_mo(i,j,k,l) = state average physicist two-body rdm restricted to the ACTIVE indices for beta-beta electron pairs
+! =
+ END_DOC
+ allocate(state_weights(N_states))
+ state_weights = state_average_weight
+ integer :: ispin
+ ! condition for alpha/beta spin
+ ispin = 2
+ state_av_act_two_rdm_openmp_beta_beta_mo = 0.d0
+ call orb_range_two_rdm_state_av_openmp(state_av_act_two_rdm_openmp_beta_beta_mo,n_act_orb,n_act_orb,list_act,state_weights,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ END_PROVIDER
+
+ BEGIN_PROVIDER [double precision, state_av_act_two_rdm_openmp_alpha_beta_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb)]
+ implicit none
+ double precision, allocatable :: state_weights(:)
+ BEGIN_DOC
+! state_av_act_two_rdm_openmp_alpha_beta_mo(i,j,k,l) = state average physicist two-body rdm restricted to the ACTIVE indices for alpha-beta electron pairs
+! =
+ END_DOC
+ allocate(state_weights(N_states))
+ state_weights = state_average_weight
+ integer :: ispin
+ ! condition for alpha/beta spin
+ print*,''
+ print*,''
+ print*,''
+ print*,'providint state_av_act_two_rdm_openmp_alpha_beta_mo '
+ ispin = 3
+ print*,'ispin = ',ispin
+ state_av_act_two_rdm_openmp_alpha_beta_mo = 0.d0
+ call orb_range_two_rdm_state_av_openmp(state_av_act_two_rdm_openmp_alpha_beta_mo,n_act_orb,n_act_orb,list_act,state_weights,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ END_PROVIDER
+
+
+ BEGIN_PROVIDER [double precision, state_av_act_two_rdm_openmp_spin_trace_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb)]
+ implicit none
+ BEGIN_DOC
+! state_av_act_two_rdm_openmp_spin_trace_mo(i,j,k,l) = state average physicist spin trace two-body rdm restricted to the ACTIVE indices
+! The active part of the two-electron energy can be computed as:
+!
+! \sum_{i,j,k,l = 1, n_act_orb} state_av_act_two_rdm_openmp_spin_trace_mo(i,j,k,l) * < ii jj | kk ll >
+!
+! with ii = list_act(i), jj = list_act(j), kk = list_act(k), ll = list_act(l)
+ END_DOC
+ double precision, allocatable :: state_weights(:)
+ allocate(state_weights(N_states))
+ state_weights = state_average_weight
+ integer :: ispin
+ ! condition for alpha/beta spin
+ ispin = 4
+ state_av_act_two_rdm_openmp_spin_trace_mo = 0.d0
+ integer :: i
+ double precision :: wall_0,wall_1
+ call wall_time(wall_0)
+ print*,'providing the state average TWO-RDM ...'
+ call orb_range_two_rdm_state_av_openmp(state_av_act_two_rdm_openmp_spin_trace_mo,n_act_orb,n_act_orb,list_act,state_weights,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
+
+ call wall_time(wall_1)
+ print*,'Time to provide the state average TWO-RDM',wall_1 - wall_0
+ END_PROVIDER
+
diff --git a/src/two_body_rdm/orb_range_routines.irp.f b/src/two_body_rdm/orb_range_routines.irp.f
new file mode 100644
index 00000000..058ed1c5
--- /dev/null
+++ b/src/two_body_rdm/orb_range_routines.irp.f
@@ -0,0 +1,499 @@
+subroutine orb_range_two_rdm_state_av(big_array,dim1,norb,list_orb,list_orb_reverse,state_weights,ispin,u_0,N_st,sze)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! if ispin == 1 :: alpha/alpha 2rdm
+ ! == 2 :: beta /beta 2rdm
+ ! == 3 :: alpha/beta 2rdm
+ ! == 4 :: spin traced 2rdm :: aa + bb + 0.5 (ab + ba))
+ !
+ ! Assumes that the determinants are in psi_det
+ !
+ ! istart, iend, ishift, istep are used in ZMQ parallelization.
+ END_DOC
+ integer, intent(in) :: N_st,sze
+ integer, intent(in) :: dim1,norb,list_orb(norb),ispin
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ double precision, intent(in) :: u_0(sze,N_st),state_weights(N_st)
+
+ integer :: k
+ double precision, allocatable :: u_t(:,:)
+ !DIR$ ATTRIBUTES ALIGN : $IRP_ALIGN :: u_t
+ allocate(u_t(N_st,N_det))
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order,N_det)
+ enddo
+ call dtranspose( &
+ u_0, &
+ size(u_0, 1), &
+ u_t, &
+ size(u_t, 1), &
+ N_det, N_st)
+
+
+ call orb_range_two_rdm_state_av_work(big_array,dim1,norb,list_orb,list_orb_reverse,state_weights,ispin,u_t,N_st,sze,1,N_det,0,1)
+ deallocate(u_t)
+
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order_reverse,N_det)
+ enddo
+
+end
+
+subroutine orb_range_two_rdm_state_av_work(big_array,dim1,norb,list_orb,list_orb_reverse,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes two-rdm
+ !
+ ! Default should be 1,N_det,0,1
+ END_DOC
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ integer, intent(in) :: dim1,norb,list_orb(norb),ispin
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ double precision, intent(in) :: u_t(N_st,N_det),state_weights(N_st)
+
+ integer :: k
+
+ PROVIDE N_int
+
+ select case (N_int)
+ case (1)
+ call orb_range_two_rdm_state_av_work_1(big_array,dim1,norb,list_orb,list_orb_reverse,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (2)
+ call orb_range_two_rdm_state_av_work_2(big_array,dim1,norb,list_orb,list_orb_reverse,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (3)
+ call orb_range_two_rdm_state_av_work_3(big_array,dim1,norb,list_orb,list_orb_reverse,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (4)
+ call orb_range_two_rdm_state_av_work_4(big_array,dim1,norb,list_orb,list_orb_reverse,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case default
+ call orb_range_two_rdm_state_av_work_N_int(big_array,dim1,norb,list_orb,list_orb_reverse,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ end select
+end
+
+
+
+
+ BEGIN_TEMPLATE
+subroutine orb_range_two_rdm_state_av_work_$N_int(big_array,dim1,norb,list_orb,list_orb_reverse,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes the two rdm for the N_st vectors |u_t>
+ ! if ispin == 1 :: alpha/alpha 2rdm
+ ! == 2 :: beta /beta 2rdm
+ ! == 3 :: alpha/beta 2rdm
+ ! == 4 :: spin traced 2rdm :: aa + bb + 0.5 (ab + ba))
+ ! The 2rdm will be computed only on the list of orbitals list_orb, which contains norb
+ ! In any cases, the state average weights will be used with an array state_weights
+ ! Default should be 1,N_det,0,1 for istart,iend,ishift,istep
+ END_DOC
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ double precision, intent(in) :: u_t(N_st,N_det),state_weights(N_st)
+ integer, intent(in) :: dim1,norb,list_orb(norb),ispin
+ integer, intent(in) :: list_orb_reverse(mo_num)
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+
+ integer :: i,j,k,l
+ integer :: k_a, k_b, l_a, l_b, m_a, m_b
+ integer :: istate
+ integer :: krow, kcol, krow_b, kcol_b
+ integer :: lrow, lcol
+ integer :: mrow, mcol
+ integer(bit_kind) :: spindet($N_int)
+ integer(bit_kind) :: tmp_det($N_int,2)
+ integer(bit_kind) :: tmp_det2($N_int,2)
+ integer(bit_kind) :: tmp_det3($N_int,2)
+ integer(bit_kind), allocatable :: buffer(:,:)
+ integer :: n_doubles
+ integer, allocatable :: doubles(:)
+ integer, allocatable :: singles_a(:)
+ integer, allocatable :: singles_b(:)
+ integer, allocatable :: idx(:), idx0(:)
+ integer :: maxab, n_singles_a, n_singles_b, kcol_prev
+ integer*8 :: k8
+ double precision :: c_average
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ integer(bit_kind) :: orb_bitmask($N_int)
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ else
+ print*,'Wrong parameter for ispin in general_two_rdm_state_av_work'
+ print*,'ispin = ',ispin
+ stop
+ endif
+
+
+ PROVIDE N_int
+
+ call list_to_bitstring( orb_bitmask, list_orb, norb, N_int)
+
+ maxab = max(N_det_alpha_unique, N_det_beta_unique)+1
+ allocate(idx0(maxab))
+
+ do i=1,maxab
+ idx0(i) = i
+ enddo
+
+
+ ! Prepare the array of all alpha single excitations
+ ! -------------------------------------------------
+
+ PROVIDE N_int nthreads_davidson
+ !!$OMP PARALLEL DEFAULT(NONE) NUM_THREADS(nthreads_davidson) &
+ ! !$OMP SHARED(psi_bilinear_matrix_rows, N_det, &
+ ! !$OMP psi_bilinear_matrix_columns, &
+ ! !$OMP psi_det_alpha_unique, psi_det_beta_unique,&
+ ! !$OMP n_det_alpha_unique, n_det_beta_unique, N_int,&
+ ! !$OMP psi_bilinear_matrix_transp_rows, &
+ ! !$OMP psi_bilinear_matrix_transp_columns, &
+ ! !$OMP psi_bilinear_matrix_transp_order, N_st, &
+ ! !$OMP psi_bilinear_matrix_order_transp_reverse, &
+ ! !$OMP psi_bilinear_matrix_columns_loc, &
+ ! !$OMP psi_bilinear_matrix_transp_rows_loc, &
+ ! !$OMP istart, iend, istep, irp_here, v_t, s_t, &
+ ! !$OMP ishift, idx0, u_t, maxab) &
+ ! !$OMP PRIVATE(krow, kcol, tmp_det, spindet, k_a, k_b, i,&
+ ! !$OMP lcol, lrow, l_a, l_b, &
+ ! !$OMP buffer, doubles, n_doubles, &
+ ! !$OMP tmp_det2, idx, l, kcol_prev, &
+ ! !$OMP singles_a, n_singles_a, singles_b, &
+ ! !$OMP n_singles_b, k8)
+
+ ! Alpha/Beta double excitations
+ ! =============================
+
+ allocate( buffer($N_int,maxab), &
+ singles_a(maxab), &
+ singles_b(maxab), &
+ doubles(maxab), &
+ idx(maxab))
+
+ kcol_prev=-1
+
+ ASSERT (iend <= N_det)
+ ASSERT (istart > 0)
+ ASSERT (istep > 0)
+
+ !!$OMP DO SCHEDULE(dynamic,64)
+ do k_a=istart+ishift,iend,istep
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ if (kcol /= kcol_prev) then
+ call get_all_spin_singles_$N_int( &
+ psi_det_beta_unique, idx0, &
+ tmp_det(1,2), N_det_beta_unique, &
+ singles_b, n_singles_b)
+ endif
+ kcol_prev = kcol
+
+ ! Loop over singly excited beta columns
+ ! -------------------------------------
+
+ do i=1,n_singles_b
+ lcol = singles_b(i)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique(1:$N_int, lcol)
+
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ ASSERT (l_a <= N_det)
+
+ do j=1,psi_bilinear_matrix_columns_loc(lcol+1) - l_a
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,j) = psi_det_alpha_unique(1:$N_int, lrow)
+
+ ASSERT (l_a <= N_det)
+ idx(j) = l_a
+ l_a = l_a+1
+ enddo
+ j = j-1
+
+ call get_all_spin_singles_$N_int( &
+ buffer, idx, tmp_det(1,1), j, &
+ singles_a, n_singles_a )
+
+ ! Loop over alpha singles
+ ! -----------------------
+
+ if(alpha_beta.or.spin_trace)then
+ do k = 1,n_singles_a
+ l_a = singles_a(k)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ c_average = 0.d0
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_2(l) * state_weights(l)
+ enddo
+ call orb_range_off_diagonal_double_to_two_rdm_ab_dm(tmp_det,tmp_det2,c_average,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ enddo
+ endif
+
+ enddo
+
+ enddo
+ ! !$OMP END DO
+
+ ! !$OMP DO SCHEDULE(dynamic,64)
+ do k_a=istart+ishift,iend,istep
+
+
+ ! Single and double alpha exitations
+ ! ===================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! ----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+ ASSERT (k_b <= N_det)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,1)
+
+ ! Loop inside the beta column to gather all the connected alphas
+ lcol = psi_bilinear_matrix_columns(k_a)
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ do i=1,N_det_alpha_unique
+ if (l_a > N_det) exit
+ lcol = psi_bilinear_matrix_columns(l_a)
+ if (lcol /= kcol) exit
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,i) = psi_det_alpha_unique(1:$N_int, lrow)
+ idx(i) = l_a
+ l_a = l_a+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_a, doubles, n_singles_a, n_doubles )
+
+ ! Compute Hij for all alpha singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+ do i=1,n_singles_a
+ l_a = singles_a(i)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ c_average = 0.d0
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_2(l) * state_weights(l)
+ enddo
+ if(alpha_beta.or.spin_trace.or.alpha_alpha)then
+ ! increment the alpha/beta part for single excitations
+ call orb_range_off_diagonal_single_to_two_rdm_ab_dm(tmp_det, tmp_det2,c_average,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ ! increment the alpha/alpha part for single excitations
+ call orb_range_off_diagonal_single_to_two_rdm_aa_dm(tmp_det,tmp_det2,c_average,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ endif
+
+ enddo
+
+
+ ! Compute Hij for all alpha doubles
+ ! ----------------------------------
+
+ if(alpha_alpha.or.spin_trace)then
+ do i=1,n_doubles
+ l_a = doubles(i)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ c_average = 0.d0
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_2(l) * state_weights(l)
+ enddo
+ call orb_range_off_diagonal_double_to_two_rdm_aa_dm(tmp_det(1,1),psi_det_alpha_unique(1, lrow),c_average,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ enddo
+ endif
+
+
+ ! Single and double beta excitations
+ ! ==================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ kcol = psi_bilinear_matrix_columns(k_a)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,2)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! -----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+ ASSERT (k_b <= N_det)
+
+ ! Loop inside the alpha row to gather all the connected betas
+ lrow = psi_bilinear_matrix_transp_rows(k_b)
+ l_b = psi_bilinear_matrix_transp_rows_loc(lrow)
+ do i=1,N_det_beta_unique
+ if (l_b > N_det) exit
+ lrow = psi_bilinear_matrix_transp_rows(l_b)
+ if (lrow /= krow) exit
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ buffer(1:$N_int,i) = psi_det_beta_unique(1:$N_int, lcol)
+ idx(i) = l_b
+ l_b = l_b+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_b, doubles, n_singles_b, n_doubles )
+
+ ! Compute Hij for all beta singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ do i=1,n_singles_b
+ l_b = singles_b(i)
+ ASSERT (l_b <= N_det)
+
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, lcol)
+ l_a = psi_bilinear_matrix_transp_order(l_b)
+ c_average = 0.d0
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_2(l) * state_weights(l)
+ enddo
+ if(alpha_beta.or.spin_trace.or.beta_beta)then
+ ! increment the alpha/beta part for single excitations
+ call orb_range_off_diagonal_single_to_two_rdm_ab_dm(tmp_det, tmp_det2,c_average,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ ! increment the beta /beta part for single excitations
+ call orb_range_off_diagonal_single_to_two_rdm_bb_dm(tmp_det, tmp_det2,c_average,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ endif
+ enddo
+
+ ! Compute Hij for all beta doubles
+ ! ----------------------------------
+
+ if(beta_beta.or.spin_trace)then
+ do i=1,n_doubles
+ l_b = doubles(i)
+ ASSERT (l_b <= N_det)
+
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ l_a = psi_bilinear_matrix_transp_order(l_b)
+ c_average = 0.d0
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_2(l) * state_weights(l)
+ enddo
+ call orb_range_off_diagonal_double_to_two_rdm_bb_dm(tmp_det(1,2),psi_det_beta_unique(1, lcol),c_average,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+ ASSERT (l_a <= N_det)
+
+ enddo
+ endif
+
+
+ ! Diagonal contribution
+ ! =====================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ double precision, external :: diag_wee_mat_elem, diag_S_mat_elem
+
+ double precision :: c_1(N_states),c_2(N_states)
+ c_average = 0.d0
+ do l = 1, N_states
+ c_1(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_1(l) * state_weights(l)
+ enddo
+
+ call orb_range_diagonal_contrib_to_all_two_rdm_dm(tmp_det,c_average,big_array,dim1,orb_bitmask,list_orb_reverse,ispin)
+
+ end do
+ !!$OMP END DO
+ deallocate(buffer, singles_a, singles_b, doubles, idx)
+ !!$OMP END PARALLEL
+
+end
+
+ SUBST [ N_int ]
+
+ 1;;
+ 2;;
+ 3;;
+ 4;;
+ N_int;;
+
+ END_TEMPLATE
+
diff --git a/src/two_body_rdm/orb_range_routines_omp.irp.f b/src/two_body_rdm/orb_range_routines_omp.irp.f
new file mode 100644
index 00000000..b6e59540
--- /dev/null
+++ b/src/two_body_rdm/orb_range_routines_omp.irp.f
@@ -0,0 +1,568 @@
+subroutine orb_range_two_rdm_state_av_openmp(big_array,dim1,norb,list_orb,state_weights,ispin,u_0,N_st,sze)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! if ispin == 1 :: alpha/alpha 2rdm
+ ! == 2 :: beta /beta 2rdm
+ ! == 3 :: alpha/beta 2rdm
+ ! == 4 :: spin traced 2rdm :: aa + bb + 0.5 (ab + ba))
+ !
+ ! Assumes that the determinants are in psi_det
+ !
+ ! istart, iend, ishift, istep are used in ZMQ parallelization.
+ END_DOC
+ integer, intent(in) :: N_st,sze
+ integer, intent(in) :: dim1,norb,list_orb(norb),ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ double precision, intent(in) :: u_0(sze,N_st),state_weights(N_st)
+
+ integer :: k
+ double precision, allocatable :: u_t(:,:)
+ !DIR$ ATTRIBUTES ALIGN : $IRP_ALIGN :: u_t
+ allocate(u_t(N_st,N_det))
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order,N_det)
+ enddo
+ call dtranspose( &
+ u_0, &
+ size(u_0, 1), &
+ u_t, &
+ size(u_t, 1), &
+ N_det, N_st)
+
+ call orb_range_two_rdm_state_av_openmp_work(big_array,dim1,norb,list_orb,state_weights,ispin,u_t,N_st,sze,1,N_det,0,1)
+ deallocate(u_t)
+
+ do k=1,N_st
+ call dset_order(u_0(1,k),psi_bilinear_matrix_order_reverse,N_det)
+ enddo
+
+end
+
+subroutine orb_range_two_rdm_state_av_openmp_work(big_array,dim1,norb,list_orb,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ implicit none
+ BEGIN_DOC
+ ! Computes two-rdm
+ !
+ ! Default should be 1,N_det,0,1
+ END_DOC
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ integer, intent(in) :: dim1,norb,list_orb(norb),ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+ double precision, intent(in) :: u_t(N_st,N_det),state_weights(N_st)
+
+ integer :: k
+
+ PROVIDE N_int
+
+ select case (N_int)
+ case (1)
+ call orb_range_two_rdm_state_av_openmp_work_1(big_array,dim1,norb,list_orb,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (2)
+ call orb_range_two_rdm_state_av_openmp_work_2(big_array,dim1,norb,list_orb,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (3)
+ call orb_range_two_rdm_state_av_openmp_work_3(big_array,dim1,norb,list_orb,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case (4)
+ call orb_range_two_rdm_state_av_openmp_work_4(big_array,dim1,norb,list_orb,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ case default
+ call orb_range_two_rdm_state_av_openmp_work_N_int(big_array,dim1,norb,list_orb,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ end select
+end
+
+
+
+
+ BEGIN_TEMPLATE
+subroutine orb_range_two_rdm_state_av_openmp_work_$N_int(big_array,dim1,norb,list_orb,state_weights,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
+ use bitmasks
+ use omp_lib
+ implicit none
+ BEGIN_DOC
+ ! Computes the two rdm for the N_st vectors |u_t>
+ ! if ispin == 1 :: alpha/alpha 2rdm
+ ! == 2 :: beta /beta 2rdm
+ ! == 3 :: alpha/beta 2rdm
+ ! == 4 :: spin traced 2rdm :: aa + bb + 0.5 (ab + ba))
+ ! The 2rdm will be computed only on the list of orbitals list_orb, which contains norb
+ ! In any cases, the state average weights will be used with an array state_weights
+ ! Default should be 1,N_det,0,1 for istart,iend,ishift,istep
+ END_DOC
+ integer, intent(in) :: N_st,sze,istart,iend,ishift,istep
+ double precision, intent(in) :: u_t(N_st,N_det),state_weights(N_st)
+ integer, intent(in) :: dim1,norb,list_orb(norb),ispin
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+
+ integer(omp_lock_kind) :: lock_2rdm
+ integer :: i,j,k,l
+ integer :: k_a, k_b, l_a, l_b
+ integer :: krow, kcol
+ integer :: lrow, lcol
+ integer(bit_kind) :: spindet($N_int)
+ integer(bit_kind) :: tmp_det($N_int,2)
+ integer(bit_kind) :: tmp_det2($N_int,2)
+ integer(bit_kind) :: tmp_det3($N_int,2)
+ integer(bit_kind), allocatable :: buffer(:,:)
+ integer :: n_doubles
+ integer, allocatable :: doubles(:)
+ integer, allocatable :: singles_a(:)
+ integer, allocatable :: singles_b(:)
+ integer, allocatable :: idx(:), idx0(:)
+ integer :: maxab, n_singles_a, n_singles_b, kcol_prev
+ double precision :: c_average
+
+ logical :: alpha_alpha,beta_beta,alpha_beta,spin_trace
+ integer(bit_kind) :: orb_bitmask($N_int)
+ integer :: list_orb_reverse(mo_num)
+ integer, allocatable :: keys(:,:)
+ double precision, allocatable :: values(:)
+ integer :: nkeys,sze_buff
+ alpha_alpha = .False.
+ beta_beta = .False.
+ alpha_beta = .False.
+ spin_trace = .False.
+ if( ispin == 1)then
+ alpha_alpha = .True.
+ else if(ispin == 2)then
+ beta_beta = .True.
+ else if(ispin == 3)then
+ alpha_beta = .True.
+ else if(ispin == 4)then
+ spin_trace = .True.
+ else
+ print*,'Wrong parameter for ispin in general_two_rdm_state_av_openmp_work'
+ print*,'ispin = ',ispin
+ stop
+ endif
+
+
+ PROVIDE N_int
+
+ call list_to_bitstring( orb_bitmask, list_orb, norb, N_int)
+ sze_buff = norb ** 3 + 6 * norb
+ list_orb_reverse = -1000
+ do i = 1, norb
+ list_orb_reverse(list_orb(i)) = i
+ enddo
+ maxab = max(N_det_alpha_unique, N_det_beta_unique)+1
+ allocate(idx0(maxab))
+
+ do i=1,maxab
+ idx0(i) = i
+ enddo
+ call omp_init_lock(lock_2rdm)
+
+ ! Prepare the array of all alpha single excitations
+ ! -------------------------------------------------
+
+ PROVIDE N_int nthreads_davidson elec_alpha_num
+ !$OMP PARALLEL DEFAULT(NONE) NUM_THREADS(nthreads_davidson) &
+ !$OMP SHARED(psi_bilinear_matrix_rows, N_det,lock_2rdm,&
+ !$OMP psi_bilinear_matrix_columns, &
+ !$OMP psi_det_alpha_unique, psi_det_beta_unique,&
+ !$OMP n_det_alpha_unique, n_det_beta_unique, N_int,&
+ !$OMP psi_bilinear_matrix_transp_rows, &
+ !$OMP psi_bilinear_matrix_transp_columns, &
+ !$OMP psi_bilinear_matrix_transp_order, N_st, &
+ !$OMP psi_bilinear_matrix_order_transp_reverse, &
+ !$OMP psi_bilinear_matrix_columns_loc, &
+ !$OMP psi_bilinear_matrix_transp_rows_loc,elec_alpha_num, &
+ !$OMP istart, iend, istep, irp_here,list_orb_reverse, n_states, state_weights, dim1, &
+ !$OMP ishift, idx0, u_t, maxab, alpha_alpha,beta_beta,alpha_beta,spin_trace,ispin,big_array,sze_buff,orb_bitmask) &
+ !$OMP PRIVATE(krow, kcol, tmp_det, spindet, k_a, k_b, i,c_1, c_2, &
+ !$OMP lcol, lrow, l_a, l_b, &
+ !$OMP buffer, doubles, n_doubles, &
+ !$OMP tmp_det2, idx, l, kcol_prev, &
+ !$OMP singles_a, n_singles_a, singles_b, &
+ !$OMP n_singles_b, nkeys, keys, values, c_average)
+
+ ! Alpha/Beta double excitations
+ ! =============================
+ nkeys = 0
+ allocate( keys(4,sze_buff), values(sze_buff))
+ allocate( buffer($N_int,maxab), &
+ singles_a(maxab), &
+ singles_b(maxab), &
+ doubles(maxab), &
+ idx(maxab))
+
+ kcol_prev=-1
+
+ ASSERT (iend <= N_det)
+ ASSERT (istart > 0)
+ ASSERT (istep > 0)
+
+ !$OMP DO SCHEDULE(dynamic,64)
+ do k_a=istart+ishift,iend,istep
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ if (kcol /= kcol_prev) then
+ call get_all_spin_singles_$N_int( &
+ psi_det_beta_unique, idx0, &
+ tmp_det(1,2), N_det_beta_unique, &
+ singles_b, n_singles_b)
+ endif
+ kcol_prev = kcol
+
+ ! Loop over singly excited beta columns
+ ! -------------------------------------
+
+ do i=1,n_singles_b
+ lcol = singles_b(i)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique(1:$N_int, lcol)
+
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ ASSERT (l_a <= N_det)
+
+ do j=1,psi_bilinear_matrix_columns_loc(lcol+1) - l_a
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,j) = psi_det_alpha_unique(1:$N_int, lrow)
+
+ ASSERT (l_a <= N_det)
+ idx(j) = l_a
+ l_a = l_a+1
+ enddo
+ j = j-1
+
+ call get_all_spin_singles_$N_int( &
+ buffer, idx, tmp_det(1,1), j, &
+ singles_a, n_singles_a )
+
+ ! Loop over alpha singles
+ ! -----------------------
+
+ if(alpha_beta.or.spin_trace)then
+ do k = 1,n_singles_a
+ l_a = singles_a(k)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ c_average = 0.d0
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_2(l) * state_weights(l)
+ enddo
+ if(alpha_beta)then
+ ! only ONE contribution
+ if (nkeys+1 .ge. size(values)) then
+ call update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ nkeys = 0
+ endif
+ else if (spin_trace)then
+ ! TWO contributions
+ if (nkeys+2 .ge. size(values)) then
+ call update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ nkeys = 0
+ endif
+ endif
+ call orb_range_off_diag_double_to_two_rdm_ab_dm_buffer(tmp_det,tmp_det2,c_average,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+
+ enddo
+ endif
+
+ enddo
+
+ enddo
+ !$OMP END DO
+
+ !$OMP DO SCHEDULE(dynamic,64)
+ do k_a=istart+ishift,iend,istep
+
+
+ ! Single and double alpha exitations
+ ! ===================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! ----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+ ASSERT (k_b <= N_det)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,1)
+
+ ! Loop inside the beta column to gather all the connected alphas
+ lcol = psi_bilinear_matrix_columns(k_a)
+ l_a = psi_bilinear_matrix_columns_loc(lcol)
+ do i=1,N_det_alpha_unique
+ if (l_a > N_det) exit
+ lcol = psi_bilinear_matrix_columns(l_a)
+ if (lcol /= kcol) exit
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ buffer(1:$N_int,i) = psi_det_alpha_unique(1:$N_int, lrow)
+ idx(i) = l_a
+ l_a = l_a+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_a, doubles, n_singles_a, n_doubles )
+
+ ! Compute Hij for all alpha singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+ do i=1,n_singles_a
+ l_a = singles_a(i)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, lrow)
+ c_average = 0.d0
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_2(l) * state_weights(l)
+ enddo
+ if(alpha_beta.or.spin_trace.or.alpha_alpha)then
+ ! increment the alpha/beta part for single excitations
+ if (nkeys+ 2 * elec_alpha_num .ge. sze_buff) then
+ call update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ nkeys = 0
+ endif
+ call orb_range_off_diag_single_to_two_rdm_ab_dm_buffer(tmp_det, tmp_det2,c_average,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ ! increment the alpha/alpha part for single excitations
+ if (nkeys+4 * elec_alpha_num .ge. sze_buff ) then
+ call update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ nkeys = 0
+ endif
+ call orb_range_off_diag_single_to_two_rdm_aa_dm_buffer(tmp_det,tmp_det2,c_average,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ endif
+
+ enddo
+
+
+ ! Compute Hij for all alpha doubles
+ ! ----------------------------------
+
+ if(alpha_alpha.or.spin_trace)then
+ do i=1,n_doubles
+ l_a = doubles(i)
+ ASSERT (l_a <= N_det)
+
+ lrow = psi_bilinear_matrix_rows(l_a)
+ ASSERT (lrow <= N_det_alpha_unique)
+
+ c_average = 0.d0
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_2(l) * state_weights(l)
+ enddo
+ if (nkeys+4 .ge. sze_buff) then
+ call update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ nkeys = 0
+ endif
+ call orb_range_off_diag_double_to_two_rdm_aa_dm_buffer(tmp_det(1,1),psi_det_alpha_unique(1, lrow),c_average,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ enddo
+ endif
+
+
+ ! Single and double beta excitations
+ ! ==================================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ kcol = psi_bilinear_matrix_columns(k_a)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ spindet(1:$N_int) = tmp_det(1:$N_int,2)
+
+ ! Initial determinant is at k_b in beta-major representation
+ ! -----------------------------------------------------------------------
+
+ k_b = psi_bilinear_matrix_order_transp_reverse(k_a)
+ ASSERT (k_b <= N_det)
+
+ ! Loop inside the alpha row to gather all the connected betas
+ lrow = psi_bilinear_matrix_transp_rows(k_b)
+ l_b = psi_bilinear_matrix_transp_rows_loc(lrow)
+ do i=1,N_det_beta_unique
+ if (l_b > N_det) exit
+ lrow = psi_bilinear_matrix_transp_rows(l_b)
+ if (lrow /= krow) exit
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ buffer(1:$N_int,i) = psi_det_beta_unique(1:$N_int, lcol)
+ idx(i) = l_b
+ l_b = l_b+1
+ enddo
+ i = i-1
+
+ call get_all_spin_singles_and_doubles_$N_int( &
+ buffer, idx, spindet, i, &
+ singles_b, doubles, n_singles_b, n_doubles )
+
+ ! Compute Hij for all beta singles
+ ! ----------------------------------
+
+ tmp_det2(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ do i=1,n_singles_b
+ l_b = singles_b(i)
+ ASSERT (l_b <= N_det)
+
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ tmp_det2(1:$N_int,2) = psi_det_beta_unique (1:$N_int, lcol)
+ l_a = psi_bilinear_matrix_transp_order(l_b)
+ c_average = 0.d0
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_2(l) * state_weights(l)
+ enddo
+ if(alpha_beta.or.spin_trace.or.beta_beta)then
+ ! increment the alpha/beta part for single excitations
+ if (nkeys+2 * elec_alpha_num .ge. sze_buff ) then
+ call update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ nkeys = 0
+ endif
+ call orb_range_off_diag_single_to_two_rdm_ab_dm_buffer(tmp_det, tmp_det2,c_average,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ ! increment the beta /beta part for single excitations
+ if (nkeys+4 * elec_alpha_num .ge. sze_buff) then
+ call update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ nkeys = 0
+ endif
+ call orb_range_off_diag_single_to_two_rdm_bb_dm_buffer(tmp_det, tmp_det2,c_average,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ endif
+ enddo
+
+ ! Compute Hij for all beta doubles
+ ! ----------------------------------
+
+ if(beta_beta.or.spin_trace)then
+ do i=1,n_doubles
+ l_b = doubles(i)
+ ASSERT (l_b <= N_det)
+
+ lcol = psi_bilinear_matrix_transp_columns(l_b)
+ ASSERT (lcol <= N_det_beta_unique)
+
+ l_a = psi_bilinear_matrix_transp_order(l_b)
+ c_average = 0.d0
+ do l= 1, N_states
+ c_1(l) = u_t(l,l_a)
+ c_2(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_2(l) * state_weights(l)
+ enddo
+ if (nkeys+4 .ge. sze_buff) then
+ call update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ nkeys = 0
+ endif
+ call orb_range_off_diag_double_to_two_rdm_bb_dm_buffer(tmp_det(1,2),psi_det_beta_unique(1, lcol),c_average,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ ASSERT (l_a <= N_det)
+
+ enddo
+ endif
+
+
+ ! Diagonal contribution
+ ! =====================
+
+
+ ! Initial determinant is at k_a in alpha-major representation
+ ! -----------------------------------------------------------------------
+
+ krow = psi_bilinear_matrix_rows(k_a)
+ ASSERT (krow <= N_det_alpha_unique)
+
+ kcol = psi_bilinear_matrix_columns(k_a)
+ ASSERT (kcol <= N_det_beta_unique)
+
+ tmp_det(1:$N_int,1) = psi_det_alpha_unique(1:$N_int, krow)
+ tmp_det(1:$N_int,2) = psi_det_beta_unique (1:$N_int, kcol)
+
+ double precision, external :: diag_wee_mat_elem, diag_S_mat_elem
+
+ double precision :: c_1(N_states),c_2(N_states)
+ c_average = 0.d0
+ do l = 1, N_states
+ c_1(l) = u_t(l,k_a)
+ c_average += c_1(l) * c_1(l) * state_weights(l)
+ enddo
+
+ call update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ nkeys = 0
+ call orb_range_diag_to_all_two_rdm_dm_buffer(tmp_det,c_average,orb_bitmask,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
+ call update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ nkeys = 0
+
+ end do
+ !$OMP END DO
+ deallocate(buffer, singles_a, singles_b, doubles, idx, keys, values)
+ !$OMP END PARALLEL
+
+end
+
+ SUBST [ N_int ]
+
+ 1;;
+ 2;;
+ 3;;
+ 4;;
+ N_int;;
+
+ END_TEMPLATE
+
+
+subroutine update_keys_values(keys,values,nkeys,dim1,big_array,lock_2rdm)
+ use omp_lib
+ implicit none
+ integer, intent(in) :: nkeys,dim1
+ integer, intent(in) :: keys(4,nkeys)
+ double precision, intent(in) :: values(nkeys)
+ double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1)
+
+ integer(omp_lock_kind),intent(inout):: lock_2rdm
+ integer :: i,h1,h2,p1,p2
+ call omp_set_lock(lock_2rdm)
+ do i = 1, nkeys
+ h1 = keys(1,i)
+ h2 = keys(2,i)
+ p1 = keys(3,i)
+ p2 = keys(4,i)
+ big_array(h1,h2,p1,p2) += values(i)
+ enddo
+ call omp_unset_lock(lock_2rdm)
+
+end
+
diff --git a/src/two_body_rdm/two_rdm.irp.f b/src/two_body_rdm/two_rdm.irp.f
new file mode 100644
index 00000000..c162f365
--- /dev/null
+++ b/src/two_body_rdm/two_rdm.irp.f
@@ -0,0 +1,62 @@
+ BEGIN_PROVIDER [double precision, two_rdm_alpha_beta_mo, (mo_num,mo_num,mo_num,mo_num,N_states)]
+&BEGIN_PROVIDER [double precision, two_rdm_alpha_alpha_mo, (mo_num,mo_num,mo_num,mo_num,N_states)]
+&BEGIN_PROVIDER [double precision, two_rdm_beta_beta_mo, (mo_num,mo_num,mo_num,mo_num,N_states)]
+ implicit none
+ BEGIN_DOC
+ ! two_rdm_alpha_beta(i,j,k,l) =
+ ! 1 1 2 2 = chemist notations
+ ! note that no 1/2 factor is introduced in order to take into acccount for the spin symmetry
+ !
+ END_DOC
+ integer :: dim1,dim2,dim3,dim4
+ double precision :: cpu_0,cpu_1
+ dim1 = mo_num
+ dim2 = mo_num
+ dim3 = mo_num
+ dim4 = mo_num
+ two_rdm_alpha_beta_mo = 0.d0
+ two_rdm_alpha_alpha_mo= 0.d0
+ two_rdm_beta_beta_mo = 0.d0
+ print*,'providing two_rdm_alpha_beta ...'
+ call wall_time(cpu_0)
+ call all_two_rdm_dm_nstates(two_rdm_alpha_alpha_mo,two_rdm_beta_beta_mo,two_rdm_alpha_beta_mo,dim1,dim2,dim3,dim4,psi_coef,size(psi_coef,2),size(psi_coef,1))
+ call wall_time(cpu_1)
+ print*,'two_rdm_alpha_beta provided in',dabs(cpu_1-cpu_0)
+
+END_PROVIDER
+
+
+ BEGIN_PROVIDER [double precision, two_rdm_alpha_beta_mo_physicist, (mo_num,mo_num,mo_num,mo_num,N_states)]
+&BEGIN_PROVIDER [double precision, two_rdm_alpha_alpha_mo_physicist, (mo_num,mo_num,mo_num,mo_num,N_states)]
+&BEGIN_PROVIDER [double precision, two_rdm_beta_beta_mo_physicist, (mo_num,mo_num,mo_num,mo_num,N_states)]
+ implicit none
+ BEGIN_DOC
+ ! two_rdm_alpha_beta_mo_physicist,(i,j,k,l) =
+ ! 1 2 1 2 = physicist notations
+ ! note that no 1/2 factor is introduced in order to take into acccount for the spin symmetry
+ !
+ END_DOC
+ integer :: i,j,k,l,istate
+ double precision :: cpu_0,cpu_1
+ two_rdm_alpha_beta_mo_physicist = 0.d0
+ print*,'providing two_rdm_alpha_beta_mo_physicist ...'
+ call wall_time(cpu_0)
+ do istate = 1, N_states
+ do i = 1, mo_num
+ do j = 1, mo_num
+ do k = 1, mo_num
+ do l = 1, mo_num
+ ! 1 2 1 2 1 1 2 2
+ two_rdm_alpha_beta_mo_physicist(l,k,i,j,istate) = two_rdm_alpha_beta_mo(i,l,j,k,istate)
+ two_rdm_alpha_alpha_mo_physicist(l,k,i,j,istate) = two_rdm_alpha_alpha_mo(i,l,j,k,istate)
+ two_rdm_beta_beta_mo_physicist(l,k,i,j,istate) = two_rdm_beta_beta_mo(i,l,j,k,istate)
+ enddo
+ enddo
+ enddo
+ enddo
+ enddo
+ call wall_time(cpu_1)
+ print*,'two_rdm_alpha_beta_mo_physicist provided in',dabs(cpu_1-cpu_0)
+
+END_PROVIDER
+
diff --git a/src/utils/sort.irp.f b/src/utils/sort.irp.f
index ed9932c9..2a655eed 100644
--- a/src/utils/sort.irp.f
+++ b/src/utils/sort.irp.f
@@ -57,6 +57,8 @@ BEGIN_TEMPLATE
$type :: c, tmp
integer :: itmp
integer :: i, j
+
+ if(isize<2)return
c = x( shiftr(first+last,1) )
i = first
diff --git a/tests/bats/common.bats.sh b/tests/bats/common.bats.sh
index 10b8c5ad..f6ea4023 100644
--- a/tests/bats/common.bats.sh
+++ b/tests/bats/common.bats.sh
@@ -52,7 +52,7 @@ run_only_test() {
skip
fi
fi
- sleep 3
+# sleep 1
}
setup() {
diff --git a/tests/input/b2_stretched.zmt b/tests/input/b2_stretched.zmt
new file mode 100644
index 00000000..04950a9b
--- /dev/null
+++ b/tests/input/b2_stretched.zmt
@@ -0,0 +1,3 @@
+b
+b 1 3.0
+
diff --git a/tests/input/n2_stretched.xyz b/tests/input/n2_stretched.xyz
new file mode 100644
index 00000000..28e26041
--- /dev/null
+++ b/tests/input/n2_stretched.xyz
@@ -0,0 +1,4 @@
+2
+N2 stretched
+N 0. 0. 0.
+N 0. 0. 2.1167090