mirror of
https://github.com/QuantumPackage/qp2.git
synced 2024-12-23 04:43:45 +01:00
commit
6b9649fc2c
@ -1,3 +1,7 @@
|
|||||||
|
**Important**: The Intel ifx compiler is not able to produce correct
|
||||||
|
executables for Quantum Package. Please use ifort as long as you can, and
|
||||||
|
consider switching to gfortran in the long term.
|
||||||
|
|
||||||
# Quantum Package 2.2
|
# Quantum Package 2.2
|
||||||
|
|
||||||
<!--- img src="https://raw.githubusercontent.com/QuantumPackage/qp2/master/data/qp2.png" width="250" --->
|
<!--- img src="https://raw.githubusercontent.com/QuantumPackage/qp2/master/data/qp2.png" width="250" --->
|
||||||
|
62
config/gfortran_mkl.cfg
Normal file
62
config/gfortran_mkl.cfg
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# Common flags
|
||||||
|
##############
|
||||||
|
#
|
||||||
|
# -ffree-line-length-none : Needed for IRPF90 which produces long lines
|
||||||
|
# -lblas -llapack : Link with libblas and liblapack libraries provided by the system
|
||||||
|
# -I . : Include the curent directory (Mandatory)
|
||||||
|
#
|
||||||
|
# --ninja : Allow the utilisation of ninja. (Mandatory)
|
||||||
|
# --align=32 : Align all provided arrays on a 32-byte boundary
|
||||||
|
#
|
||||||
|
#
|
||||||
|
[COMMON]
|
||||||
|
FC : gfortran -ffree-line-length-none -I . -mavx -g -fPIC -std=legacy
|
||||||
|
LAPACK_LIB : -I${MKLROOT}/include -L${MKLROOT}/lib/intel64 -Wl,--no-as-needed -lmkl_gf_lp64 -lmkl_core -lpthread -lm -ldl -lmkl_gnu_thread -lgomp -fopenmp
|
||||||
|
IRPF90 : irpf90
|
||||||
|
IRPF90_FLAGS : --ninja --align=32 -DSET_NESTED
|
||||||
|
|
||||||
|
# Global options
|
||||||
|
################
|
||||||
|
#
|
||||||
|
# 1 : Activate
|
||||||
|
# 0 : Deactivate
|
||||||
|
#
|
||||||
|
[OPTION]
|
||||||
|
MODE : OPT ; [ OPT | PROFILE | DEBUG ] : Chooses the section below
|
||||||
|
CACHE : 0 ; Enable cache_compile.py
|
||||||
|
OPENMP : 1 ; Append OpenMP flags
|
||||||
|
|
||||||
|
# Optimization flags
|
||||||
|
####################
|
||||||
|
#
|
||||||
|
# -Ofast : Disregard strict standards compliance. Enables all -O3 optimizations.
|
||||||
|
# It also enables optimizations that are not valid
|
||||||
|
# for all standard-compliant programs. It turns on
|
||||||
|
# -ffast-math and the Fortran-specific
|
||||||
|
# -fno-protect-parens and -fstack-arrays.
|
||||||
|
[OPT]
|
||||||
|
FCFLAGS : -Ofast -mavx
|
||||||
|
|
||||||
|
# Profiling flags
|
||||||
|
#################
|
||||||
|
#
|
||||||
|
[PROFILE]
|
||||||
|
FC : -p -g
|
||||||
|
FCFLAGS : -Ofast
|
||||||
|
|
||||||
|
# Debugging flags
|
||||||
|
#################
|
||||||
|
#
|
||||||
|
# -fcheck=all : Checks uninitialized variables, array subscripts, etc...
|
||||||
|
# -g : Extra debugging information
|
||||||
|
#
|
||||||
|
[DEBUG]
|
||||||
|
FCFLAGS : -fcheck=all -g
|
||||||
|
|
||||||
|
# OpenMP flags
|
||||||
|
#################
|
||||||
|
#
|
||||||
|
[OPENMP]
|
||||||
|
FC : -fopenmp
|
||||||
|
IRPF90_FLAGS : --openmp
|
||||||
|
|
@ -6,7 +6,7 @@
|
|||||||
# --align=32 : Align all provided arrays on a 32-byte boundary
|
# --align=32 : Align all provided arrays on a 32-byte boundary
|
||||||
#
|
#
|
||||||
[COMMON]
|
[COMMON]
|
||||||
FC : ifort -fpic
|
FC : ifort -fpic -diag-disable=10448
|
||||||
LAPACK_LIB : -mkl=parallel
|
LAPACK_LIB : -mkl=parallel
|
||||||
IRPF90 : irpf90
|
IRPF90 : irpf90
|
||||||
IRPF90_FLAGS : --ninja --align=32 -DINTEL
|
IRPF90_FLAGS : --ninja --align=32 -DINTEL
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# --align=32 : Align all provided arrays on a 32-byte boundary
|
# --align=32 : Align all provided arrays on a 32-byte boundary
|
||||||
#
|
#
|
||||||
[COMMON]
|
[COMMON]
|
||||||
FC : mpiifort -fpic
|
FC : mpiifort -fpic -diag-disable=10448
|
||||||
LAPACK_LIB : -mkl=parallel
|
LAPACK_LIB : -mkl=parallel
|
||||||
IRPF90 : irpf90
|
IRPF90 : irpf90
|
||||||
IRPF90_FLAGS : --ninja --align=32 -DMPI -DINTEL
|
IRPF90_FLAGS : --ninja --align=32 -DMPI -DINTEL
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# --align=32 : Align all provided arrays on a 32-byte boundary
|
# --align=32 : Align all provided arrays on a 32-byte boundary
|
||||||
#
|
#
|
||||||
[COMMON]
|
[COMMON]
|
||||||
FC : ifort -fpic
|
FC : ifort -fpic -diag-disable=10448
|
||||||
LAPACK_LIB : -mkl=parallel
|
LAPACK_LIB : -mkl=parallel
|
||||||
IRPF90 : irpf90
|
IRPF90 : irpf90
|
||||||
IRPF90_FLAGS : --ninja --align=32 --define=WITHOUT_TRAILZ --define=WITHOUT_SHIFTRL
|
IRPF90_FLAGS : --ninja --align=32 --define=WITHOUT_TRAILZ --define=WITHOUT_SHIFTRL
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# --align=32 : Align all provided arrays on a 32-byte boundary
|
# --align=32 : Align all provided arrays on a 32-byte boundary
|
||||||
#
|
#
|
||||||
[COMMON]
|
[COMMON]
|
||||||
FC : ifort -fpic
|
FC : ifort -fpic -diag-disable=10448
|
||||||
LAPACK_LIB : -mkl=parallel
|
LAPACK_LIB : -mkl=parallel
|
||||||
IRPF90 : irpf90
|
IRPF90 : irpf90
|
||||||
IRPF90_FLAGS : --ninja --align=32 --assert -DINTEL
|
IRPF90_FLAGS : --ninja --align=32 --assert -DINTEL
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# --align=32 : Align all provided arrays on a 32-byte boundary
|
# --align=32 : Align all provided arrays on a 32-byte boundary
|
||||||
#
|
#
|
||||||
[COMMON]
|
[COMMON]
|
||||||
FC : mpiifort -fpic
|
FC : mpiifort -fpic -diag-disable=10448
|
||||||
LAPACK_LIB : -mkl=parallel
|
LAPACK_LIB : -mkl=parallel
|
||||||
IRPF90 : irpf90
|
IRPF90 : irpf90
|
||||||
IRPF90_FLAGS : --ninja --align=32 -DINTEL
|
IRPF90_FLAGS : --ninja --align=32 -DINTEL
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# --align=32 : Align all provided arrays on a 32-byte boundary
|
# --align=32 : Align all provided arrays on a 32-byte boundary
|
||||||
#
|
#
|
||||||
[COMMON]
|
[COMMON]
|
||||||
FC : ifort -fpic
|
FC : ifort -fpic -diag-disable=10448
|
||||||
LAPACK_LIB : -mkl=parallel
|
LAPACK_LIB : -mkl=parallel
|
||||||
IRPF90 : irpf90
|
IRPF90 : irpf90
|
||||||
IRPF90_FLAGS : --ninja --align=32 -DINTEL
|
IRPF90_FLAGS : --ninja --align=32 -DINTEL
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# --align=32 : Align all provided arrays on a 32-byte boundary
|
# --align=32 : Align all provided arrays on a 32-byte boundary
|
||||||
#
|
#
|
||||||
[COMMON]
|
[COMMON]
|
||||||
FC : ifort -fpic
|
FC : ifort -fpic -diag-disable=10448
|
||||||
LAPACK_LIB : -mkl=parallel
|
LAPACK_LIB : -mkl=parallel
|
||||||
IRPF90 : irpf90
|
IRPF90 : irpf90
|
||||||
IRPF90_FLAGS : --ninja --align=32 -DINTEL
|
IRPF90_FLAGS : --ninja --align=32 -DINTEL
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# --align=32 : Align all provided arrays on a 32-byte boundary
|
# --align=32 : Align all provided arrays on a 32-byte boundary
|
||||||
#
|
#
|
||||||
[COMMON]
|
[COMMON]
|
||||||
FC : mpiifort -fpic
|
FC : mpiifort -fpic -diag-disable=10448
|
||||||
LAPACK_LIB : -mkl=parallel
|
LAPACK_LIB : -mkl=parallel
|
||||||
IRPF90 : irpf90
|
IRPF90 : irpf90
|
||||||
IRPF90_FLAGS : --ninja --align=32 -DMPI -DINTEL
|
IRPF90_FLAGS : --ninja --align=32 -DMPI -DINTEL
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# --align=32 : Align all provided arrays on a 32-byte boundary
|
# --align=32 : Align all provided arrays on a 32-byte boundary
|
||||||
#
|
#
|
||||||
[COMMON]
|
[COMMON]
|
||||||
FC : ifort -fpic -diag-disable 5462
|
FC : ifort -fpic -diag-disable=5462 -diag-disable=10448
|
||||||
LAPACK_LIB : -mkl=parallel
|
LAPACK_LIB : -mkl=parallel
|
||||||
IRPF90 : irpf90
|
IRPF90 : irpf90
|
||||||
IRPF90_FLAGS : --ninja --align=64 -DINTEL
|
IRPF90_FLAGS : --ninja --align=64 -DINTEL
|
||||||
|
@ -58,17 +58,32 @@ let int_of_atom_id : atom_id -> int = fun x -> x
|
|||||||
let float_of_distance : float StringMap.t -> distance -> float =
|
let float_of_distance : float StringMap.t -> distance -> float =
|
||||||
fun map -> function
|
fun map -> function
|
||||||
| Value x -> x
|
| Value x -> x
|
||||||
| Label s -> StringMap.find s map
|
| Label s -> begin
|
||||||
|
try StringMap.find s map with
|
||||||
|
| Not_found ->
|
||||||
|
Printf.sprintf "Zmatrix error: distance %s undefined" s
|
||||||
|
|> failwith
|
||||||
|
end
|
||||||
|
|
||||||
let float_of_angle : float StringMap.t -> angle -> float =
|
let float_of_angle : float StringMap.t -> angle -> float =
|
||||||
fun map -> function
|
fun map -> function
|
||||||
| Value x -> x
|
| Value x -> x
|
||||||
| Label s -> StringMap.find s map
|
| Label s -> begin
|
||||||
|
try StringMap.find s map with
|
||||||
|
| Not_found ->
|
||||||
|
Printf.sprintf "Zmatrix error: angle %s undefined" s
|
||||||
|
|> failwith
|
||||||
|
end
|
||||||
|
|
||||||
let float_of_dihedral : float StringMap.t -> dihedral -> float =
|
let float_of_dihedral : float StringMap.t -> dihedral -> float =
|
||||||
fun map -> function
|
fun map -> function
|
||||||
| Value x -> x
|
| Value x -> x
|
||||||
| Label s -> StringMap.find s map
|
| Label s -> begin
|
||||||
|
try StringMap.find s map with
|
||||||
|
| Not_found ->
|
||||||
|
Printf.sprintf "Zmatrix error: dihedral %s undefined" s
|
||||||
|
|> failwith
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
type line =
|
type line =
|
||||||
|
@ -224,7 +224,7 @@
|
|||||||
subroutine overlap_bourrin_spread(A_center,B_center,alpha,beta,power_A,power_B,overlap_x,lower_exp_val,dx,nx)
|
subroutine overlap_bourrin_spread(A_center,B_center,alpha,beta,power_A,power_B,overlap_x,lower_exp_val,dx,nx)
|
||||||
BEGIN_DOC
|
BEGIN_DOC
|
||||||
! Computes the following integral :
|
! Computes the following integral :
|
||||||
! int [-infty ; +infty] of [(x-A_center)^(power_A) * (x-B_center)^power_B * exp(-alpha(x-A_center)^2) * exp(-beta(x-B_center)^2) * x ]
|
! int [-infty ; +infty] of [(x-A_center)^(power_A) * (x-B_center)^power_B * exp(-alpha(x-A_center)^2) * exp(-beta(x-B_center)^2) * x^2 ]
|
||||||
! needed for the dipole and those things
|
! needed for the dipole and those things
|
||||||
END_DOC
|
END_DOC
|
||||||
implicit none
|
implicit none
|
||||||
|
@ -4,13 +4,15 @@ casscf
|
|||||||
|
|
||||||
|CASSCF| program with the CIPSI algorithm.
|
|CASSCF| program with the CIPSI algorithm.
|
||||||
|
|
||||||
Example of inputs
|
|
||||||
-----------------
|
Example of inputs for GROUND STATE calculations
|
||||||
|
-----------------------------------------------
|
||||||
|
NOTICE :: FOR EXCITED STATES CALCULATIONS SEE THE FILE "example_casscf_multistate.sh"
|
||||||
|
|
||||||
a) Small active space : standard CASSCF
|
a) Small active space : standard CASSCF
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
Let's do O2 (triplet) in aug-cc-pvdz with the following geometry (xyz format, Bohr units)
|
Let's do O2 (triplet) in aug-cc-pvdz with the following geometry (xyz format, Bohr units)
|
||||||
3
|
2
|
||||||
|
|
||||||
O 0.0000000000 0.0000000000 -1.1408000000
|
O 0.0000000000 0.0000000000 -1.1408000000
|
||||||
O 0.0000000000 0.0000000000 1.1408000000
|
O 0.0000000000 0.0000000000 1.1408000000
|
||||||
@ -45,3 +47,4 @@ qp set casscf_cipsi small_active_space False
|
|||||||
qp run casscf | tee ${EZFIO_FILE}.casscf_large.out
|
qp run casscf | tee ${EZFIO_FILE}.casscf_large.out
|
||||||
# you should find around -149.9046
|
# you should find around -149.9046
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,14 +54,24 @@ subroutine run
|
|||||||
|
|
||||||
call write_time(6)
|
call write_time(6)
|
||||||
call write_int(6,iteration,'CAS-SCF iteration = ')
|
call write_int(6,iteration,'CAS-SCF iteration = ')
|
||||||
call write_double(6,energy,'CAS-SCF energy = ')
|
call write_double(6,energy,'State-average CAS-SCF energy = ')
|
||||||
! if(n_states == 1)then
|
! if(n_states == 1)then
|
||||||
! call ezfio_get_casscf_cipsi_energy_pt2(E_PT2)
|
! call ezfio_get_casscf_cipsi_energy_pt2(E_PT2)
|
||||||
! call ezfio_get_casscf_cipsi_energy(PT2)
|
! call ezfio_get_casscf_cipsi_energy(PT2)
|
||||||
|
double precision :: delta_E_istate, e_av
|
||||||
|
e_av = 0.d0
|
||||||
do istate=1,N_states
|
do istate=1,N_states
|
||||||
call write_double(6,E_PT2(istate),'E + PT2 energy = ')
|
e_av += state_average_weight(istate) * Ev(istate)
|
||||||
call write_double(6,PT2(istate),' PT2 = ')
|
if(istate.gt.1)then
|
||||||
|
delta_E_istate = E_PT2(istate) - E_PT2(1)
|
||||||
|
write(*,'(A6,I2,A18,F16.10)')'state ',istate,' Delta E+PT2 = ',delta_E_istate
|
||||||
|
endif
|
||||||
|
write(*,'(A6,I2,A18,F16.10)')'state ',istate,' E + PT2 energy = ',E_PT2(istate)
|
||||||
|
write(*,'(A6,I2,A18,F16.10)')'state ',istate,' PT2 energy = ',PT2(istate)
|
||||||
|
! call write_double(6,E_PT2(istate),'E + PT2 energy = ')
|
||||||
|
! call write_double(6,PT2(istate),' PT2 = ')
|
||||||
enddo
|
enddo
|
||||||
|
call write_double(6,e_av,'State-average CAS-SCF energy bis = ')
|
||||||
call write_double(6,pt2_max,' PT2_MAX = ')
|
call write_double(6,pt2_max,' PT2_MAX = ')
|
||||||
! endif
|
! endif
|
||||||
|
|
||||||
@ -99,8 +109,8 @@ subroutine run
|
|||||||
|
|
||||||
mo_coef = NewOrbs
|
mo_coef = NewOrbs
|
||||||
mo_occ = occnum
|
mo_occ = occnum
|
||||||
call save_mos
|
|
||||||
if(.not.converged)then
|
if(.not.converged)then
|
||||||
|
call save_mos
|
||||||
iteration += 1
|
iteration += 1
|
||||||
if(norm_grad_vec2.gt.0.01d0)then
|
if(norm_grad_vec2.gt.0.01d0)then
|
||||||
N_det = N_states
|
N_det = N_states
|
||||||
|
66
src/casscf_cipsi/example_casscf_multistate.sh
Executable file
66
src/casscf_cipsi/example_casscf_multistate.sh
Executable file
@ -0,0 +1,66 @@
|
|||||||
|
# This is an example for MULTI STATE CALCULATION STATE AVERAGE CASSCF
|
||||||
|
# We will compute 3 states on the O2 molecule
|
||||||
|
# The Ground state and 2 degenerate excited states
|
||||||
|
# Please follow carefully the tuto :)
|
||||||
|
|
||||||
|
##### PREPARING THE EZFIO
|
||||||
|
# Set the path to your QP2 directory
|
||||||
|
QP_ROOT=my_fancy_path
|
||||||
|
source ${QP_ROOT}/quantum_package.rc
|
||||||
|
# Create the EZFIO folder
|
||||||
|
qp create_ezfio -b aug-cc-pvdz O2.xyz -m 3 -a -o O2_avdz_multi_state
|
||||||
|
# Start with ROHF orbitals
|
||||||
|
qp run scf # ROHF energy : -149.619992871398
|
||||||
|
# Freeze the 1s orbitals of the two oxygen
|
||||||
|
qp set_frozen_core
|
||||||
|
|
||||||
|
##### PREPARING THE ORBITALS WITH NATURAL ORBITALS OF A CIS
|
||||||
|
# Tell that you want 3 states in your WF
|
||||||
|
qp set determinants n_states 3
|
||||||
|
# Run a CIS wave function to start your calculation
|
||||||
|
qp run cis | tee ${EZFIO_FILE}.cis_3_states.out # -149.6652601409258 -149.4714726176746 -149.4686165431939
|
||||||
|
# Save the STATE AVERAGE natural orbitals for having a balanced description
|
||||||
|
# This will also order the orbitals according to their occupation number
|
||||||
|
# Which makes the active space selection easyer !
|
||||||
|
qp run save_natorb | tee ${EZFIO_FILE}.natorb_3states.out
|
||||||
|
|
||||||
|
##### PREPARING A CIS GUESS WITHIN THE ACTIVE SPACE
|
||||||
|
# Set an active space which has the most of important excitations
|
||||||
|
# and that maintains symmetry : the ACTIVE ORBITALS are from """6 to 13"""
|
||||||
|
|
||||||
|
# YOU FIRST FREEZE THE VIRTUALS THAT ARE NOT IN THE ACTIVE SPACE
|
||||||
|
# !!!!! WE SET TO "-D" for DELETED !!!!
|
||||||
|
qp set_mo_class -c "[1-5]" -a "[6-13]" -d "[14-46]"
|
||||||
|
# You create a guess of CIS type WITHIN THE ACTIVE SPACE
|
||||||
|
qp run cis | tee ${EZFIO_FILE}.cis_3_states_active_space.out # -149.6515472533511 -149.4622878024821 -149.4622878024817
|
||||||
|
# You tell to read the WFT stored (i.e. the guess we just created)
|
||||||
|
qp set determinants read_wf True
|
||||||
|
|
||||||
|
##### DOING THE CASSCF
|
||||||
|
### SETTING PROPERLY THE ACTIVE SPACE FOR CASSCF
|
||||||
|
# You set the active space WITH THE VIRTUAL ORBITALS !!!
|
||||||
|
# !!!!! NOW WE SET TO "-v" for VIRTUALS !!!!!
|
||||||
|
qp set_mo_class -c "[1-5]" -a "[6-13]" -v "[14-46]"
|
||||||
|
|
||||||
|
# You tell that it is a small actice space so the CIPSI can take all Slater determinants
|
||||||
|
qp set casscf_cipsi small_active_space True
|
||||||
|
# You specify the output file
|
||||||
|
output=${EZFIO_FILE}.casscf_3states.out
|
||||||
|
# You run the CASSCF calculation
|
||||||
|
qp run casscf | tee ${output} # -149.7175867510 -149.5059010227 -149.5059010226
|
||||||
|
|
||||||
|
# Some grep in order to get some numbers useful to check convergence
|
||||||
|
# State average energy
|
||||||
|
grep "State-average CAS-SCF energy =" $output | cut -d "=" -f 2 > data_e_average
|
||||||
|
# Delta E anticipated for State-average energy, only usefull to check convergence
|
||||||
|
grep "Predicted energy improvement =" $output | cut -d "=" -f 2 > data_improve
|
||||||
|
# Ground state energy
|
||||||
|
grep "state 1 E + PT2 energy" $output | cut -d "=" -f 2 > data_1
|
||||||
|
# First excited state energy
|
||||||
|
grep "state 2 E + PT2 energy" $output | cut -d "=" -f 2 > data_2
|
||||||
|
# First excitation energy
|
||||||
|
grep "state 2 Delta E+PT2" $output | cut -d "=" -f 2 > data_delta_E2
|
||||||
|
# Second excited state energy
|
||||||
|
grep "state 3 E + PT2 energy" $output | cut -d "=" -f 2 > data_3
|
||||||
|
# Second excitation energy
|
||||||
|
grep "state 3 Delta E+PT2" $output | cut -d "=" -f 2 > data_delta_E3
|
@ -226,27 +226,28 @@ BEGIN_PROVIDER [real*8, Umat, (mo_num,mo_num) ]
|
|||||||
end do
|
end do
|
||||||
|
|
||||||
! Form the exponential
|
! Form the exponential
|
||||||
|
call exp_matrix_taylor(Tmat,mo_num,Umat,converged)
|
||||||
|
|
||||||
Tpotmat(:,:)=0.D0
|
! Tpotmat(:,:)=0.D0
|
||||||
Umat(:,:) =0.D0
|
! Umat(:,:) =0.D0
|
||||||
do i=1,mo_num
|
! do i=1,mo_num
|
||||||
Tpotmat(i,i)=1.D0
|
! Tpotmat(i,i)=1.D0
|
||||||
Umat(i,i) =1.d0
|
! Umat(i,i) =1.d0
|
||||||
end do
|
! end do
|
||||||
iter=0
|
! iter=0
|
||||||
converged=.false.
|
! converged=.false.
|
||||||
do while (.not.converged)
|
! do while (.not.converged)
|
||||||
iter+=1
|
! iter+=1
|
||||||
f = 1.d0 / dble(iter)
|
! f = 1.d0 / dble(iter)
|
||||||
Tpotmat2(:,:) = Tpotmat(:,:) * f
|
! Tpotmat2(:,:) = Tpotmat(:,:) * f
|
||||||
call dgemm('N','N', mo_num,mo_num,mo_num,1.d0, &
|
! call dgemm('N','N', mo_num,mo_num,mo_num,1.d0, &
|
||||||
Tpotmat2, size(Tpotmat2,1), &
|
! Tpotmat2, size(Tpotmat2,1), &
|
||||||
Tmat, size(Tmat,1), 0.d0, &
|
! Tmat, size(Tmat,1), 0.d0, &
|
||||||
Tpotmat, size(Tpotmat,1))
|
! Tpotmat, size(Tpotmat,1))
|
||||||
Umat(:,:) = Umat(:,:) + Tpotmat(:,:)
|
! Umat(:,:) = Umat(:,:) + Tpotmat(:,:)
|
||||||
|
!
|
||||||
converged = ( sum(abs(Tpotmat(:,:))) < 1.d-6).or.(iter>30)
|
! converged = ( sum(abs(Tpotmat(:,:))) < 1.d-6).or.(iter>30)
|
||||||
end do
|
! end do
|
||||||
END_PROVIDER
|
END_PROVIDER
|
||||||
|
|
||||||
|
|
||||||
|
@ -492,3 +492,25 @@ subroutine u_0_H_u_0_two_e(e_0,u_0,n,keys_tmp,Nint,N_st,sze)
|
|||||||
deallocate (s_0, v_0)
|
deallocate (s_0, v_0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
BEGIN_PROVIDER [double precision, psi_energy_two_e_trans, (N_states, N_states)]
|
||||||
|
implicit none
|
||||||
|
BEGIN_DOC
|
||||||
|
! psi_energy_two_e_trans(istate,jstate) = <Psi_istate|W_ee |Psi_jstate>
|
||||||
|
END_dOC
|
||||||
|
integer :: i,j,istate,jstate
|
||||||
|
double precision :: hij, coef_i, coef_j
|
||||||
|
psi_energy_two_e_trans = 0.d0
|
||||||
|
do i = 1, N_det
|
||||||
|
do j = 1, N_det
|
||||||
|
call i_H_j_two_e(psi_det(1,1,i),psi_det(1,1,j),N_int,hij)
|
||||||
|
do istate = 1, N_states
|
||||||
|
coef_i = psi_coef(i,istate)
|
||||||
|
do jstate = 1, N_states
|
||||||
|
coef_j = psi_coef(j,jstate)
|
||||||
|
psi_energy_two_e_trans(jstate,istate) += coef_i * coef_j * hij
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
END_PROVIDER
|
||||||
|
@ -21,3 +21,10 @@ type: logical
|
|||||||
doc: If true and N_states > 1, the oscillator strength will be computed
|
doc: If true and N_states > 1, the oscillator strength will be computed
|
||||||
interface: ezfio,provider,ocaml
|
interface: ezfio,provider,ocaml
|
||||||
default: false
|
default: false
|
||||||
|
|
||||||
|
[calc_energy_components]
|
||||||
|
type: logical
|
||||||
|
doc: If true, the components of the energy (1e, 2e, kinetic) will be computed
|
||||||
|
interface: ezfio,provider,ocaml
|
||||||
|
default: false
|
||||||
|
|
||||||
|
@ -6,6 +6,11 @@ subroutine print_mol_properties()
|
|||||||
! Run the propertie calculations
|
! Run the propertie calculations
|
||||||
END_DOC
|
END_DOC
|
||||||
|
|
||||||
|
! Energy components
|
||||||
|
if (calc_energy_components) then
|
||||||
|
call print_energy_components
|
||||||
|
endif
|
||||||
|
|
||||||
! Electric dipole moment
|
! Electric dipole moment
|
||||||
if (calc_dipole_moment) then
|
if (calc_dipole_moment) then
|
||||||
call print_dipole_moment
|
call print_dipole_moment
|
||||||
|
39
src/two_body_rdm/act_2_transition_rdm.irp.f
Normal file
39
src/two_body_rdm/act_2_transition_rdm.irp.f
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
BEGIN_PROVIDER [double precision, act_2_rdm_trans_spin_trace_mo, (n_act_orb,n_act_orb,n_act_orb,n_act_orb,N_states,N_states)]
|
||||||
|
implicit none
|
||||||
|
BEGIN_DOC
|
||||||
|
! act_2_rdm_trans_spin_trace_mo(i,j,k,l,istate,jstate) = STATE SPECIFIC physicist notation for 2rdm_trans
|
||||||
|
!
|
||||||
|
! \sum_{\sigma,\sigma'}<Psi_{istate}| a^{\dagger}_{i \sigma} a^{\dagger}_{j \sigma'} a_{l \sigma'} a_{k \sigma} |Psi_{jstate}>
|
||||||
|
!
|
||||||
|
! WHERE ALL ORBITALS (i,j,k,l) BELONGS TO AN ACTIVE SPACE DEFINED BY "list_act"
|
||||||
|
!
|
||||||
|
! THE NORMALIZATION (i.e. sum of diagonal elements) IS SET TO N_{elec}^{act} * (N_{elec}^{act} - 1)
|
||||||
|
!
|
||||||
|
! !!!!! WARNING !!!!! ALL SLATER DETERMINANTS IN PSI_DET MUST BELONG TO AN ACTIVE SPACE DEFINED BY "list_act"
|
||||||
|
END_DOC
|
||||||
|
integer :: ispin
|
||||||
|
double precision :: wall_1, wall_2
|
||||||
|
! condition for beta/beta spin
|
||||||
|
print*,''
|
||||||
|
print*,'Providing act_2_rdm_trans_spin_trace_mo '
|
||||||
|
character*(128) :: name_file
|
||||||
|
name_file = 'act_2_rdm_trans_spin_trace_mo'
|
||||||
|
ispin = 4
|
||||||
|
act_2_rdm_trans_spin_trace_mo = 0.d0
|
||||||
|
call wall_time(wall_1)
|
||||||
|
! if(read_two_body_rdm_trans_spin_trace)then
|
||||||
|
! print*,'Reading act_2_rdm_trans_spin_trace_mo from disk ...'
|
||||||
|
! call read_array_two_rdm_trans(n_act_orb,N_states,act_2_rdm_trans_spin_trace_mo,name_file)
|
||||||
|
! else
|
||||||
|
call orb_range_2_trans_rdm_openmp(act_2_rdm_trans_spin_trace_mo,n_act_orb,n_act_orb,list_act,ispin,psi_coef,size(psi_coef,2),size(psi_coef,1))
|
||||||
|
! endif
|
||||||
|
! if(write_two_body_rdm_trans_spin_trace)then
|
||||||
|
! print*,'Writing act_2_rdm_trans_spin_trace_mo on disk ...'
|
||||||
|
! call write_array_two_rdm_trans(n_act_orb,n_states,act_2_rdm_trans_spin_trace_mo,name_file)
|
||||||
|
! call ezfio_set_two_body_rdm_trans_io_two_body_rdm_trans_spin_trace("Read")
|
||||||
|
! endif
|
||||||
|
|
||||||
|
act_2_rdm_trans_spin_trace_mo *= 2.d0
|
||||||
|
call wall_time(wall_2)
|
||||||
|
print*,'Wall time to provide act_2_rdm_trans_spin_trace_mo',wall_2 - wall_1
|
||||||
|
END_PROVIDER
|
@ -365,3 +365,91 @@ subroutine routine_full_mos
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
subroutine routine_active_only_trans
|
||||||
|
implicit none
|
||||||
|
integer :: i,j,k,l,iorb,jorb,korb,lorb,istate,jstate
|
||||||
|
BEGIN_DOC
|
||||||
|
! This routine computes the two electron repulsion within the active space using various providers
|
||||||
|
!
|
||||||
|
END_DOC
|
||||||
|
|
||||||
|
double precision :: vijkl,get_two_e_integral
|
||||||
|
double precision :: wee_tot(N_states,N_states),rdm_transtot
|
||||||
|
double precision :: spin_trace
|
||||||
|
double precision :: accu_tot
|
||||||
|
|
||||||
|
wee_tot = 0.d0
|
||||||
|
|
||||||
|
|
||||||
|
iorb = 1
|
||||||
|
jorb = 1
|
||||||
|
korb = 1
|
||||||
|
lorb = 1
|
||||||
|
vijkl = get_two_e_integral(lorb,korb,jorb,iorb,mo_integrals_map)
|
||||||
|
provide act_2_rdm_trans_spin_trace_mo
|
||||||
|
i = 1
|
||||||
|
j = 2
|
||||||
|
|
||||||
|
print*,'**************************'
|
||||||
|
print*,'**************************'
|
||||||
|
do jstate = 1, N_states
|
||||||
|
do istate = 1, N_states
|
||||||
|
!! PURE ACTIVE PART
|
||||||
|
!!
|
||||||
|
accu_tot = 0.d0
|
||||||
|
do i = 1, n_act_orb
|
||||||
|
iorb = list_act(i)
|
||||||
|
do j = 1, n_act_orb
|
||||||
|
jorb = list_act(j)
|
||||||
|
do k = 1, n_act_orb
|
||||||
|
korb = list_act(k)
|
||||||
|
do l = 1, n_act_orb
|
||||||
|
lorb = list_act(l)
|
||||||
|
! 1 2 1 2 2 1 2 1
|
||||||
|
! if(dabs(act_2_rdm_trans_spin_trace_mo(i,j,k,l,istate,jstate) - act_2_rdm_trans_spin_trace_mo(j,i,l,k,istate,jstate)).gt.1.d-10)then
|
||||||
|
! print*,'Error in act_2_rdm_trans_spin_trace_mo'
|
||||||
|
! print*,"dabs(act_2_rdm_trans_spin_trace_mo(i,j,k,l) - act_2_rdm_trans_spin_trace_mo(j,i,l,k)).gt.1.d-10"
|
||||||
|
! print*,i,j,k,l
|
||||||
|
! print*,act_2_rdm_trans_spin_trace_mo(i,j,k,l,istate,jstate),act_2_rdm_trans_spin_trace_mo(j,i,l,k,istate,jstate),dabs(act_2_rdm_trans_spin_trace_mo(i,j,k,l,istate,jstate) - act_2_rdm_trans_spin_trace_mo(j,i,l,k,istate,jstate))
|
||||||
|
! endif
|
||||||
|
|
||||||
|
! 1 2 1 2 1 2 1 2
|
||||||
|
! if(dabs(act_2_rdm_trans_spin_trace_mo(i,j,k,l,istate,jstate) - act_2_rdm_trans_spin_trace_mo(k,l,i,j,istate,jstate)).gt.1.d-10)then
|
||||||
|
! print*,'Error in act_2_rdm_trans_spin_trace_mo'
|
||||||
|
! print*,"dabs(act_2_rdm_trans_spin_trace_mo(i,j,k,l,istate,jstate) - act_2_rdm_trans_spin_trace_mo(k,l,i,j,istate,jstate)).gt.1.d-10"
|
||||||
|
! print*,i,j,k,l
|
||||||
|
! print*,act_2_rdm_trans_spin_trace_mo(i,j,k,l,istate,jstate),act_2_rdm_trans_spin_trace_mo(k,l,i,j,istate,jstate),dabs(act_2_rdm_trans_spin_trace_mo(i,j,k,l,istate,jstate) - act_2_rdm_trans_spin_trace_mo(k,l,i,j,istate,jstate))
|
||||||
|
! endif
|
||||||
|
|
||||||
|
vijkl = get_two_e_integral(lorb,korb,jorb,iorb,mo_integrals_map)
|
||||||
|
|
||||||
|
|
||||||
|
rdm_transtot = act_2_rdm_trans_spin_trace_mo(l,k,j,i,istate,jstate)
|
||||||
|
|
||||||
|
wee_tot(istate,jstate) += 0.5d0 * vijkl * rdm_transtot
|
||||||
|
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
print*,''
|
||||||
|
print*,''
|
||||||
|
print*,'Active space only energy for state ',istate,jstate
|
||||||
|
print*,'wee_tot = ',wee_tot(istate,jstate)
|
||||||
|
print*,'Full energy '
|
||||||
|
print*,'psi_energy_two_e(istate,jstate)= ',psi_energy_two_e_trans(istate,jstate)
|
||||||
|
print*,'--------------------------'
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
print*,'Wee from DM '
|
||||||
|
do istate = 1,N_states
|
||||||
|
write(*,'(100(F16.10,X))')wee_tot(1:N_states,istate)
|
||||||
|
enddo
|
||||||
|
print*,'Wee from Psi det'
|
||||||
|
do istate = 1,N_states
|
||||||
|
write(*,'(100(F16.10,X))')psi_energy_two_e_trans(1:N_states,istate)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
@ -31,3 +31,37 @@ subroutine read_array_two_rdm(n_orb,nstates,array_tmp,name_file)
|
|||||||
close(unit=i_unit_output)
|
close(unit=i_unit_output)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
subroutine write_array_two_trans_rdm(n_orb,nstates,array_tmp,name_file)
|
||||||
|
implicit none
|
||||||
|
integer, intent(in) :: n_orb,nstates
|
||||||
|
character*(128), intent(in) :: name_file
|
||||||
|
double precision, intent(in) :: array_tmp(n_orb,n_orb,n_orb,n_orb,nstates,nstates)
|
||||||
|
|
||||||
|
character*(128) :: output
|
||||||
|
integer :: i_unit_output,getUnitAndOpen
|
||||||
|
PROVIDE ezfio_filename
|
||||||
|
output=trim(ezfio_filename)//'/work/'//trim(name_file)
|
||||||
|
i_unit_output = getUnitAndOpen(output,'W')
|
||||||
|
call lock_io()
|
||||||
|
write(i_unit_output)array_tmp
|
||||||
|
call unlock_io()
|
||||||
|
close(unit=i_unit_output)
|
||||||
|
end
|
||||||
|
|
||||||
|
subroutine read_array_two_trans_rdm(n_orb,nstates,array_tmp,name_file)
|
||||||
|
implicit none
|
||||||
|
character*(128) :: output
|
||||||
|
integer :: i_unit_output,getUnitAndOpen
|
||||||
|
integer, intent(in) :: n_orb,nstates
|
||||||
|
character*(128), intent(in) :: name_file
|
||||||
|
double precision, intent(out) :: array_tmp(n_orb,n_orb,n_orb,n_orb,N_states,nstates)
|
||||||
|
PROVIDE ezfio_filename
|
||||||
|
output=trim(ezfio_filename)//'/work/'//trim(name_file)
|
||||||
|
i_unit_output = getUnitAndOpen(output,'R')
|
||||||
|
call lock_io()
|
||||||
|
read(i_unit_output)array_tmp
|
||||||
|
call unlock_io()
|
||||||
|
close(unit=i_unit_output)
|
||||||
|
end
|
||||||
|
|
||||||
|
@ -4,5 +4,6 @@ program test_2_rdm
|
|||||||
touch read_wf
|
touch read_wf
|
||||||
call routine_active_only
|
call routine_active_only
|
||||||
call routine_full_mos
|
call routine_full_mos
|
||||||
|
call routine_active_only_trans
|
||||||
end
|
end
|
||||||
|
|
||||||
|
585
src/two_rdm_routines/davidson_like_trans_2rdm.irp.f
Normal file
585
src/two_rdm_routines/davidson_like_trans_2rdm.irp.f
Normal file
@ -0,0 +1,585 @@
|
|||||||
|
subroutine orb_range_2_trans_rdm_openmp(big_array,dim1,norb,list_orb,ispin,u_0,N_st,sze)
|
||||||
|
use bitmasks
|
||||||
|
implicit none
|
||||||
|
BEGIN_DOC
|
||||||
|
! if ispin == 1 :: alpha/alpha 2_rdm
|
||||||
|
! == 2 :: beta /beta 2_rdm
|
||||||
|
! == 3 :: alpha/beta + beta/alpha 2trans_rdm
|
||||||
|
! == 4 :: spin traced 2_rdm :: aa + bb + ab + ba
|
||||||
|
!
|
||||||
|
! notice that here it is the TRANSITION RDM THAT IS COMPUTED
|
||||||
|
!
|
||||||
|
! THE DIAGONAL PART IS THE USUAL ONE FOR A GIVEN STATE
|
||||||
|
! 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,N_st,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
|
||||||
|
PROVIDE mo_two_e_integrals_in_map
|
||||||
|
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_2_trans_rdm_openmp_work(big_array,dim1,norb,list_orb,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_2_trans_rdm_openmp_work(big_array,dim1,norb,list_orb,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
|
||||||
|
use bitmasks
|
||||||
|
implicit none
|
||||||
|
BEGIN_DOC
|
||||||
|
! Computes two-trans_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,N_st,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_2_trans_rdm_openmp_work_1(big_array,dim1,norb,list_orb,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
|
||||||
|
case (2)
|
||||||
|
call orb_range_2_trans_rdm_openmp_work_2(big_array,dim1,norb,list_orb,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
|
||||||
|
case (3)
|
||||||
|
call orb_range_2_trans_rdm_openmp_work_3(big_array,dim1,norb,list_orb,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
|
||||||
|
case (4)
|
||||||
|
call orb_range_2_trans_rdm_openmp_work_4(big_array,dim1,norb,list_orb,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
|
||||||
|
case default
|
||||||
|
call orb_range_2_trans_rdm_openmp_work_N_int(big_array,dim1,norb,list_orb,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
|
||||||
|
end select
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_TEMPLATE
|
||||||
|
subroutine orb_range_2_trans_rdm_openmp_work_$N_int(big_array,dim1,norb,list_orb,ispin,u_t,N_st,sze,istart,iend,ishift,istep)
|
||||||
|
use bitmasks
|
||||||
|
use omp_lib
|
||||||
|
implicit none
|
||||||
|
BEGIN_DOC
|
||||||
|
! Computes the two trans_rdm for the N_st vectors |u_t>
|
||||||
|
! if ispin == 1 :: alpha/alpha 2trans_rdm
|
||||||
|
! == 2 :: beta /beta 2trans_rdm
|
||||||
|
! == 3 :: alpha/beta 2trans_rdm
|
||||||
|
! == 4 :: spin traced 2trans_rdm :: aa + bb + 0.5 (ab + ba))
|
||||||
|
! The 2trans_rdm 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
|
||||||
|
double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,N_st,N_st)
|
||||||
|
|
||||||
|
integer(omp_lock_kind) :: lock_2trans_rdm
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
integer :: ll
|
||||||
|
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_2_trans_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 = 6 * norb + elec_alpha_num * elec_alpha_num * 60
|
||||||
|
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_2trans_rdm)
|
||||||
|
|
||||||
|
! 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_2trans_rdm,&
|
||||||
|
!$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, 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, &
|
||||||
|
!$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)
|
||||||
|
|
||||||
|
! Alpha/Beta double excitations
|
||||||
|
! =============================
|
||||||
|
nkeys = 0
|
||||||
|
allocate( keys(4,sze_buff), values(n_st,n_st,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)
|
||||||
|
! print*,'nkeys before = ',nkeys
|
||||||
|
do ll = 1, N_states
|
||||||
|
do l= 1, N_states
|
||||||
|
c_1(l,ll) = u_t(ll,l_a) * u_t(l,k_a)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
if(alpha_beta)then
|
||||||
|
! only ONE contribution
|
||||||
|
if (nkeys+1 .ge. sze_buff) then
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
endif
|
||||||
|
else if (spin_trace)then
|
||||||
|
! TWO contributions
|
||||||
|
if (nkeys+2 .ge. sze_buff) then
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
call orb_range_off_diag_double_to_all_states_ab_trans_rdm_buffer(tmp_det,tmp_det2,c_1,N_st,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
|
||||||
|
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
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 ll= 1, N_states
|
||||||
|
do l= 1, N_states
|
||||||
|
c_1(l,ll) = u_t(ll,l_a) * u_t(l,k_a)
|
||||||
|
enddo
|
||||||
|
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_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
endif
|
||||||
|
call orb_range_off_diag_single_to_all_states_ab_trans_rdm_buffer(tmp_det, tmp_det2,c_1,N_st,orb_bitmask,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_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
endif
|
||||||
|
call orb_range_off_diag_single_to_all_states_aa_trans_rdm_buffer(tmp_det,tmp_det2,c_1,N_st,orb_bitmask,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo
|
||||||
|
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
|
||||||
|
! 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)
|
||||||
|
|
||||||
|
do ll= 1, N_states
|
||||||
|
do l= 1, N_states
|
||||||
|
c_1(l,ll) = u_t(ll,l_a) * u_t(l,k_a)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
if (nkeys+4 .ge. sze_buff) then
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
endif
|
||||||
|
call orb_range_off_diag_double_to_all_states_aa_trans_rdm_buffer(tmp_det(1,1),psi_det_alpha_unique(1, lrow),c_1,N_st,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
|
||||||
|
|
||||||
|
! 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 ll= 1, N_states
|
||||||
|
do l= 1, N_states
|
||||||
|
c_1(l,ll) = u_t(ll,l_a) * u_t(l,k_a)
|
||||||
|
enddo
|
||||||
|
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_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
endif
|
||||||
|
call orb_range_off_diag_single_to_all_states_ab_trans_rdm_buffer(tmp_det, tmp_det2,c_1,N_st,orb_bitmask,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_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
endif
|
||||||
|
call orb_range_off_diag_single_to_all_states_bb_trans_rdm_buffer(tmp_det, tmp_det2,c_1,N_st,orb_bitmask,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
|
||||||
|
! 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)
|
||||||
|
do ll= 1, N_states
|
||||||
|
do l= 1, N_states
|
||||||
|
c_1(l,ll) = u_t(ll,l_a) * u_t(l,k_a)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
if (nkeys+4 .ge. sze_buff) then
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
endif
|
||||||
|
call orb_range_off_diag_double_to_all_states_trans_rdm_bb_buffer(tmp_det(1,2),psi_det_beta_unique(1, lcol),c_1,N_st,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
|
||||||
|
! print*,'to do orb_range_off_diag_double_to_2_trans_rdm_bb_dm_buffer'
|
||||||
|
ASSERT (l_a <= N_det)
|
||||||
|
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
|
||||||
|
|
||||||
|
! 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,N_states)
|
||||||
|
do ll = 1, N_states
|
||||||
|
do l = 1, N_states
|
||||||
|
c_1(l,ll) = u_t(ll,k_a) * u_t(l,k_a)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
nkeys = 0
|
||||||
|
call orb_range_diag_to_all_states_2_rdm_trans_buffer(tmp_det,c_1,N_states,orb_bitmask,list_orb_reverse,ispin,sze_buff,nkeys,keys,values)
|
||||||
|
call update_keys_values_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2trans_rdm)
|
||||||
|
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_n_states_trans(keys,values,nkeys,dim1,n_st,big_array,lock_2rdm)
|
||||||
|
use omp_lib
|
||||||
|
implicit none
|
||||||
|
integer, intent(in) :: n_st,nkeys,dim1
|
||||||
|
integer, intent(in) :: keys(4,nkeys)
|
||||||
|
double precision, intent(in) :: values(n_st,n_st,nkeys)
|
||||||
|
double precision, intent(inout) :: big_array(dim1,dim1,dim1,dim1,n_st,n_st)
|
||||||
|
|
||||||
|
integer(omp_lock_kind),intent(inout):: lock_2rdm
|
||||||
|
|
||||||
|
integer :: i,h1,h2,p1,p2,istate,jstate
|
||||||
|
call omp_set_lock(lock_2rdm)
|
||||||
|
|
||||||
|
! print*,'*************'
|
||||||
|
! print*,'updating'
|
||||||
|
! print*,'nkeys',nkeys
|
||||||
|
do i = 1, nkeys
|
||||||
|
h1 = keys(1,i)
|
||||||
|
h2 = keys(2,i)
|
||||||
|
p1 = keys(3,i)
|
||||||
|
p2 = keys(4,i)
|
||||||
|
do jstate = 1, N_st
|
||||||
|
do istate = 1, N_st
|
||||||
|
!! print*,h1,h2,p1,p2,values(istate,i)
|
||||||
|
big_array(h1,h2,p1,p2,istate,jstate) += values(istate,jstate,i)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
call omp_unset_lock(lock_2rdm)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
1002
src/two_rdm_routines/update_trans_rdm.irp.f
Normal file
1002
src/two_rdm_routines/update_trans_rdm.irp.f
Normal file
File diff suppressed because it is too large
Load Diff
@ -652,6 +652,7 @@ subroutine get_pseudo_inverse_complex(A,LDA,m,n,C,LDC,cutoff)
|
|||||||
complex*16, allocatable :: U(:,:), Vt(:,:), work(:), A_tmp(:,:)
|
complex*16, allocatable :: U(:,:), Vt(:,:), work(:), A_tmp(:,:)
|
||||||
integer :: info, lwork
|
integer :: info, lwork
|
||||||
integer :: i,j,k
|
integer :: i,j,k
|
||||||
|
double precision :: d1
|
||||||
allocate (D(n),U(m,n),Vt(n,n),work(1),A_tmp(m,n),rwork(5*n))
|
allocate (D(n),U(m,n),Vt(n,n),work(1),A_tmp(m,n),rwork(5*n))
|
||||||
do j=1,n
|
do j=1,n
|
||||||
do i=1,m
|
do i=1,m
|
||||||
@ -673,8 +674,9 @@ subroutine get_pseudo_inverse_complex(A,LDA,m,n,C,LDC,cutoff)
|
|||||||
stop 1
|
stop 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
d1 = D(1)
|
||||||
do i=1,n
|
do i=1,n
|
||||||
if (D(i) > cutoff*D(1)) then
|
if (D(i) > cutoff*d1) then
|
||||||
D(i) = 1.d0/D(i)
|
D(i) = 1.d0/D(i)
|
||||||
else
|
else
|
||||||
D(i) = 0.d0
|
D(i) = 0.d0
|
||||||
@ -1375,8 +1377,6 @@ subroutine get_pseudo_inverse(A, LDA, m, n, C, LDC, cutoff)
|
|||||||
enddo
|
enddo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
print*, ' n_svd = ', n_svd
|
|
||||||
|
|
||||||
!$OMP PARALLEL &
|
!$OMP PARALLEL &
|
||||||
!$OMP DEFAULT (NONE) &
|
!$OMP DEFAULT (NONE) &
|
||||||
!$OMP PRIVATE (i, j) &
|
!$OMP PRIVATE (i, j) &
|
||||||
@ -1390,12 +1390,12 @@ subroutine get_pseudo_inverse(A, LDA, m, n, C, LDC, cutoff)
|
|||||||
!$OMP END DO
|
!$OMP END DO
|
||||||
!$OMP END PARALLEL
|
!$OMP END PARALLEL
|
||||||
|
|
||||||
call dgemm("N", "N", m, n, n_svd, 1.d0, U, m, Vt, n, 0.d0, C, LDC)
|
call dgemm('T', 'T', n, m, n_svd, 1.d0, Vt, size(Vt,1), U, size(U,1), 0.d0, C, size(C,1))
|
||||||
|
|
||||||
! C = 0.d0
|
! C = 0.d0
|
||||||
! do i=1,m
|
! do i=1,m
|
||||||
! do j=1,n
|
! do j=1,n
|
||||||
! do k=1,n
|
! do k=1,n_svd
|
||||||
! C(j,i) = C(j,i) + U(i,k) * D(k) * Vt(k,j)
|
! C(j,i) = C(j,i) + U(i,k) * D(k) * Vt(k,j)
|
||||||
! enddo
|
! enddo
|
||||||
! enddo
|
! enddo
|
||||||
@ -1897,3 +1897,140 @@ end do
|
|||||||
|
|
||||||
end subroutine pivoted_cholesky
|
end subroutine pivoted_cholesky
|
||||||
|
|
||||||
|
subroutine exp_matrix(X,n,exp_X)
|
||||||
|
implicit none
|
||||||
|
double precision, intent(in) :: X(n,n)
|
||||||
|
integer, intent(in):: n
|
||||||
|
double precision, intent(out):: exp_X(n,n)
|
||||||
|
BEGIN_DOC
|
||||||
|
! exponential of the matrix X: X has to be ANTI HERMITIAN !!
|
||||||
|
!
|
||||||
|
! taken from Hellgaker, jorgensen, Olsen book
|
||||||
|
!
|
||||||
|
! section evaluation of matrix exponential (Eqs. 3.1.29 to 3.1.31)
|
||||||
|
END_DOC
|
||||||
|
integer :: i
|
||||||
|
double precision, allocatable :: r2_mat(:,:),eigvalues(:),eigvectors(:,:)
|
||||||
|
double precision, allocatable :: matrix_tmp1(:,:),eigvalues_mat(:,:),matrix_tmp2(:,:)
|
||||||
|
include 'constants.include.F'
|
||||||
|
allocate(r2_mat(n,n),eigvalues(n),eigvectors(n,n))
|
||||||
|
allocate(eigvalues_mat(n,n),matrix_tmp1(n,n),matrix_tmp2(n,n))
|
||||||
|
|
||||||
|
! r2_mat = X^2 in the 3.1.30
|
||||||
|
call get_A_squared(X,n,r2_mat)
|
||||||
|
call lapack_diagd(eigvalues,eigvectors,r2_mat,n,n)
|
||||||
|
eigvalues=-eigvalues
|
||||||
|
|
||||||
|
if(.False.)then
|
||||||
|
!!! For debugging and following the book intermediate
|
||||||
|
! rebuilding the matrix : X^2 = -W t^2 W^T as in 3.1.30
|
||||||
|
! matrix_tmp1 = W t^2
|
||||||
|
print*,'eigvalues = '
|
||||||
|
do i = 1, n
|
||||||
|
print*,i,eigvalues(i)
|
||||||
|
write(*,'(100(F16.10,X))')eigvectors(:,i)
|
||||||
|
enddo
|
||||||
|
eigvalues_mat=0.d0
|
||||||
|
do i = 1,n
|
||||||
|
! t = dsqrt(t^2) where t^2 are eigenvalues of X^2
|
||||||
|
eigvalues(i) = dsqrt(eigvalues(i))
|
||||||
|
eigvalues_mat(i,i) = eigvalues(i)*eigvalues(i)
|
||||||
|
enddo
|
||||||
|
call dgemm('N','N',n,n,n,1.d0,eigvectors,size(eigvectors,1), &
|
||||||
|
eigvalues_mat,size(eigvalues_mat,1),0.d0,matrix_tmp1,size(matrix_tmp1,1))
|
||||||
|
call dgemm('N','T',n,n,n,-1.d0,matrix_tmp1,size(matrix_tmp1,1), &
|
||||||
|
eigvectors,size(eigvectors,1),0.d0,matrix_tmp2,size(matrix_tmp2,1))
|
||||||
|
print*,'r2_mat new = '
|
||||||
|
do i = 1, n
|
||||||
|
write(*,'(100(F16.10,X))')matrix_tmp2(:,i)
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
|
||||||
|
! building the exponential
|
||||||
|
! exp(X) = W cos(t) W^T + W t^-1 sin(t) W^T X as in Eq. 3.1.31
|
||||||
|
! matrix_tmp1 = W cos(t)
|
||||||
|
do i = 1,n
|
||||||
|
eigvalues_mat(i,i) = dcos(eigvalues(i))
|
||||||
|
enddo
|
||||||
|
! matrix_tmp2 = W cos(t)
|
||||||
|
call dgemm('N','N',n,n,n,1.d0,eigvectors,size(eigvectors,1), &
|
||||||
|
eigvalues_mat,size(eigvalues_mat,1),0.d0,matrix_tmp1,size(matrix_tmp1,1))
|
||||||
|
! matrix_tmp2 = W cos(t) W^T
|
||||||
|
call dgemm('N','T',n,n,n,-1.d0,matrix_tmp1,size(matrix_tmp1,1), &
|
||||||
|
eigvectors,size(eigvectors,1),0.d0,matrix_tmp2,size(matrix_tmp2,1))
|
||||||
|
exp_X = matrix_tmp2
|
||||||
|
! matrix_tmp2 = W t^-1 sin(t) W^T X
|
||||||
|
do i = 1,n
|
||||||
|
if(dabs(eigvalues(i)).gt.1.d-4)then
|
||||||
|
eigvalues_mat(i,i) = dsin(eigvalues(i))/eigvalues(i)
|
||||||
|
else ! Taylor development of sin(x)/x near x=0 = 1 - x^2/6
|
||||||
|
eigvalues_mat(i,i) = 1.d0 - eigvalues(i)*eigvalues(i)*c_1_3*0.5d0
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
! matrix_tmp1 = W t^-1 sin(t)
|
||||||
|
call dgemm('N','N',n,n,n,1.d0,eigvectors,size(eigvectors,1), &
|
||||||
|
eigvalues_mat,size(eigvalues_mat,1),0.d0,matrix_tmp1,size(matrix_tmp1,1))
|
||||||
|
! matrix_tmp2 = W t^-1 sin(t) W^T
|
||||||
|
call dgemm('N','T',n,n,n,-1.d0,matrix_tmp1,size(matrix_tmp1,1), &
|
||||||
|
eigvectors,size(eigvectors,1),0.d0,matrix_tmp2,size(matrix_tmp2,1))
|
||||||
|
! exp_X += matrix_tmp2 X
|
||||||
|
call dgemm('N','N',n,n,n,1.d0,matrix_tmp2,size(matrix_tmp2,1), &
|
||||||
|
X,size(X,1),1.d0,exp_X,size(exp_X,1))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
subroutine exp_matrix_taylor(X,n,exp_X,converged)
|
||||||
|
implicit none
|
||||||
|
BEGIN_DOC
|
||||||
|
! exponential of a general real matrix X using the Taylor expansion of exp(X)
|
||||||
|
!
|
||||||
|
! returns the logical converged which checks the convergence
|
||||||
|
END_DOC
|
||||||
|
double precision, intent(in) :: X(n,n)
|
||||||
|
integer, intent(in):: n
|
||||||
|
double precision, intent(out):: exp_X(n,n)
|
||||||
|
logical :: converged
|
||||||
|
double precision :: f
|
||||||
|
integer :: i,iter
|
||||||
|
double precision, allocatable :: Tpotmat(:,:),Tpotmat2(:,:)
|
||||||
|
allocate(Tpotmat(n,n),Tpotmat2(n,n))
|
||||||
|
BEGIN_DOC
|
||||||
|
! exponential of X using Taylor expansion
|
||||||
|
END_DOC
|
||||||
|
Tpotmat(:,:)=0.D0
|
||||||
|
exp_X(:,:) =0.D0
|
||||||
|
do i=1,n
|
||||||
|
Tpotmat(i,i)=1.D0
|
||||||
|
exp_X(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', n,n,n,1.d0, &
|
||||||
|
Tpotmat2, size(Tpotmat2,1), &
|
||||||
|
X, size(X,1), 0.d0, &
|
||||||
|
Tpotmat, size(Tpotmat,1))
|
||||||
|
exp_X(:,:) = exp_X(:,:) + Tpotmat(:,:)
|
||||||
|
|
||||||
|
converged = ( sum(abs(Tpotmat(:,:))) < 1.d-6).or.(iter>30)
|
||||||
|
end do
|
||||||
|
if(.not.converged)then
|
||||||
|
print*,'Warning !! exp_matrix_taylor did not converge !'
|
||||||
|
endif
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
subroutine get_A_squared(A,n,A2)
|
||||||
|
implicit none
|
||||||
|
BEGIN_DOC
|
||||||
|
! A2 = A A where A is n x n matrix. Use the dgemm routine
|
||||||
|
END_DOC
|
||||||
|
double precision, intent(in) :: A(n,n)
|
||||||
|
integer, intent(in) :: n
|
||||||
|
double precision, intent(out):: A2(n,n)
|
||||||
|
call dgemm('N','N',n,n,n,1.d0,A,size(A,1),A,size(A,1),0.d0,A2,size(A2,1))
|
||||||
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user