9
1
mirror of https://github.com/QuantumPackage/qp2.git synced 2024-11-07 05:53:37 +01:00

Global Replacement of 'occupation pattern' with 'configuration'

This commit is contained in:
Anthony Scemama 2020-12-08 18:44:53 +01:00
parent 05cdfa4f44
commit 3713ca46ad
17 changed files with 196 additions and 197 deletions

View File

@ -1,36 +1,29 @@
det : dans la fonction d'onde vec * popcnt pour avoir les determinants par NSOMO
csf : dans la fonctions d'onde vec * Trier par Nsomo
conf_det : Nconf x Ndet'(conf) * Tableau (i) -> indice du 1er CFG qui a i SOMO
conf_csf : Nconf x Ncsf'(conf) * Boucler sur toutes les CFG mono-excitees par rapport a toutes les autres
csf'(conf) : dans une conf (N_somo(conf) + N_domo(conf)) * p,q,cfg -> 0|1|2|3 (Type d'excitation)
det'(conf) : dans une conf (N_somo(conf) + N_domo(conf))
det''(conf) : probleme modele avec N_somo(conf)
csf''(conf) : probleme modele avec N_somo(conf)
* [0/2]
- [ ] Precalculer dans la base des configurations
W_pq = \sum_{K} <Psi | E_pq | K>
K> configuration \in SOMO-SOMO SOMO-DOMO DOMO-VMO SOMO-VMO
W : matrice mono x mono
- [ ] Fonction conf ->
- [ ] Compute <i|H|j> in conf basis
- [ ] Function hij_conf(i,j) -> matrix Ndet_ixM
222200000000
000010100101
p->q
222200200000
000000000101
(1,Ndet) (Ndet,Ndet) (Ndet,1) -> E SOMO->SOMO
for i=1,Nconf DOMO -> SOMO
for j=1,Nconf
(i,Ndet') [(Ndet',Ndet'') (Ndet'',Ndet'') (Ndet'',Ndet')] (Ndet',j) -> E
(i,Ncsf') (Ncsf',Ncsf'') [(Ncsf'',Ndet'') (Ndet'',Ndet'') (Ndet'',Ncsf'')] (Ncsf'',Ncsf') (Ncsf',j) -> E
<psi | [\sum_K E_pq | K>< K | E_rs] | Psi> do p in DO
do q in not(DO or SO)
p->q + 2 DOMO->VMO
C.D^t
K : toutes les mono do p in DO
do q in not(DO or SO)
<ij|kl> = \sum_m <ij|mj><ml|kl> p->q + 2 DOMO->VMO
DOMO -> VMO
test si bit=1 dans DO
test si bit=1 dans VO

View File

@ -1,107 +1,116 @@
#+TITLE: CFG CIPSI #+TITLE: CFG CIPSI
#+AUTHOR: Vijay Gopal Chilkuri (vijay.gopal.c@gmail.com) #+AUTHOR: Vijay Gopal Chilkuri (vijay.gopal.c@gmail.com)
#+DATE: <2020-12-08 Tue 08:27> #+DATE: 2020-12-08 Tue 08:27
#+startup: latexpreview
#+LATEX_HEADER: \usepackage{braket} #+LATEX_HEADER: \usepackage{braket}
* Biblio
* Theoretical background * Theoretical background
Here we describe the main theoretical background and definitions of the Here we describe the main theoretical background and definitions of the
Configuration (CFG) based CIPSI algorithm. The outline of the document is as follows. Configuration (CFG) based CIPSI algorithm. The outline of the document is as follows.
First, we give some definitions of the CFG many-particle basis follwed by the First, we give some definitions of the CFG many-particle basis follwed by the
definitions of the overlap, one-particle, and two-particle matrix-elements. Finally, definitions of the overlap, one-particle, and two-particle matrix-elements. Finally,
an algorithm is presented for the sigma-vector (\[ \sigma \]-vector defined later) calculation using an algorithm is presented for the sigma-vector (\( \sigma \)-vector defined later) calculation using
the CFG basis. the CFG basis.
* Definitino of CI basis ** Definitinon of CI basis
In CFG based CIPSI, the wavefunction is represented in CFG basis as shown in Eq:\[~\ref{Eq:definebasis1}\]. In CFG based CIPSI, the wavefunction is represented in CFG basis
as shown in Eq: [[Eq:definebasis1]].
#+LATEX: \newcommand{\Ncfg}{N_{\text{CFG}}}
#+LATEX: \newcommand{\Ncsf}{N_{\text{CSF}}}
#+LATEX: \newcommand{\Nsomo}{N_{\text{SOMO}}}
#+NAME: Eq:definebasis1
\begin{equation} \begin{equation}
\label{Eq:definebasis1} \ket{\Psi} = \sum_{i=1}^{\Ncfg} \sum_{j=1}^{\Ncsf(i)} c_{ij} {^S\ket{\Phi^j_i}}
\ket{\psi} &= \sum_{ij} c_{ij} ^s\ket{\phi^j_i}
\end{equation} \end{equation}
where the \[\ket{\Phi^j_i}\] represent Configuration State Functions (CSFs) where the \(\ket{\Phi^j_i}\) represent Configuration State Functions (CSFs)
which are expanded in terms of Bonded functions (BFs) as shown in which are expanded in terms of Bonded functions (BFs) as shown in
Eq:\[~\ref{Eq:definebasis2}\]. [[Eq:definebasis2]].
#+NAME: Eq:definebasis2
\begin{equation} \begin{equation}
\label{Eq:definebasis2} \ket{\Phi^j_i} = \sum_k O^{\Nsomo(i)}_{kj} \ket{^S\phi_k(i,j)}
\ket{\Phi^j_i} &= \sum^j_{i,k} O^j_{i,k} \ket{^S\phi_k(i,j)}
\end{equation} \end{equation}
where the functions \(\ket{^S\phi_k(i,j)}\) represent the BFs for the CFG
\(\ket{^S\Phi_i}\).
The coefficients \(O^b_{a,k}\) depend only on the number of SOMOs
in \(\Phi_i\).
Each CFG contains a list of CSFs related to it which describes the
spin part of the wavefunction (see Eq: [[Eq:definebasis3]]) which is
encoded in the BFs as shown below in Eq: [[Eq:definebasis5]].
Where the functions \[\ket{^S\phi_k(i,j)}\] represent the BFs for the CFG #+NAME: Eq:definebasis3
\[i\]. Each CFG contains a list of CSFs related to it which describes the
spin part of the wavefunction (see Eq:~\ref{Eq:definebasis3}) which is
encoded in the BFs as shown below in Eq:~\ref{Eq:definebasis5}.
\begin{equation}\begin{equation}
\label{Eq:definebasis3}
\ket{^S\Phi_i} = \left\{ \ket{^S\Phi^1_i}, \ket{^S\Phi^2_i}, \dots, \ket{^s\phi^{n_{csf}}_i} \right}
\end{equation}
\begin{equation}\begin{equation}
\label{eq:definebasis4}
\ket{^s\phi_i} = \left\{ c^1_i, c^1_i, \dots, c^{N_{CSF}}_i \right\}
\end{equation}
Each of the CSFs belonging to the CFG \[\ket{^S\Phi_i}\] have coefficients
associated to them as shown in Eq:~\ref{Eq:definebasis4}. Crucially, the bonded functions
defined in Eq:~\ref{Eq:definebasis5} are not northogonal to each other.
\begin{equation} \begin{equation}
\label{Eq:definebasis4} \ket{^S\Phi_i} = \left\{ \ket{^S\Phi^1_i}, \ket{^S\Phi^2_i}, \dots, \ket{^s\Phi^{\Ncsf}_i} \right\}
\ket{^S\phi_k(i,j)} = (i\bar{i})\dots (j,k) l m
\end{equation} \end{equation}
#+NAME: Eq:definebasis4
\begin{equation}
\mathbf{c}_i = \left\{ c^1_i, c^2_i, \dots, c^{\Ncsf}_i \right\}
\end{equation}
Each of the CSFs belonging to the CFG \(\ket{^S\Phi_i}\) have coefficients
associated to them as shown in Eq: [[Eq:definebasis4]]. Crucially, the bonded functions
defined in Eq: [[Eq:definebasis5]] are not northogonal to each other.
#+NAME: Eq:definebasis5
\begin{equation}
\ket{^S\phi_k(i,j)} = (a\bar{a})\dots (b\ c) (d (e
\end{equation}
$i$ is the index of the CFG and $j$ determines the coupling.
The bonded functions are made up of products of slater determinants. There are The bonded functions are made up of products of slater determinants. There are
three types of determinants, first, the closed shell pairs \[(i\bar{i})\]. Second, three types of determinants, first, the closed shell pairs \((a\bar{a})\). Second,
the open-shell singlet pairs \[(i,j)\] which are expanded as \[(i,j) = \frac{\ket{i\bar{j}}-\ket{\bar{i}j}}{\sqrt{2}}\]. Third, the the open-shell singlet pairs \((b\ c)\) which are expanded as
\((b\ c) = \frac{\ket{b\bar{c}}-\ket{\bar{b}c}}{\sqrt{2}}\). Third, the
open-shell SOMOs which are coupled parallel and account for the total spin of the open-shell SOMOs which are coupled parallel and account for the total spin of the
wavefunction \[(l (m \dots\]. They are shown as open brackets. wavefunction \((l (m \dots\). They are shown as open brackets.
* Overlap of the wavefunction ** Overlap of the wavefunction
Once the wavefunction has been expanded in terms of the CSFs, the most fundamental Once the wavefunction has been expanded in terms of the CSFs, the most fundamental
operation is to calculate the overlap between two states. The overlap in the operation is to calculate the overlap between two states. The overlap in the
basis of CSFs is defined as shown in Eq:~\ref{Eq:defineovlp1}. basis of CSFs is defined as shown in Eq: [[Eq:defineovlp1]].
#+NAME: Eq:defineovlp1
\begin{equation} \begin{equation}
\label{Eq:defineovlp1}
\braket{^S\Phi_i|^S\Phi_j} = \sum_{kl} C_i C_j \braket{^S\Psi^k_i|^S\Psi^l_j} \braket{^S\Phi_i|^S\Phi_j} = \sum_{kl} C_i C_j \braket{^S\Psi^k_i|^S\Psi^l_j}
\end{equation} \end{equation}
Where the sum is over the CSFs \[k\] and \[l\] corresponding to the \[i\] Where the sum is over the CSFs \(k\) and \(l\) corresponding to the \(i\)
and \[j\] CFGs respectively. The overlap between the CSFs can be expanded in terms and \(j\) CFGs respectively. The overlap between the CSFs can be expanded in terms
of the BFs using the definition given in Eq:~\ref{Eq:definebasis2} and Eq:~\ref{Eq:definebasis3} of the BFs using the definition given in Eq: [[Eq:definebasis2]] and
as given in Eq:~\ref{Eq:defineovlp2}. Eq: [[Eq:definebasis3]] as given in Eq: [[Eq:defineovlp2]].
#+NAME: Eq:defineovlp2
\begin{equation} \begin{equation}
\label{Eq:defineovlp2}
\braket{^S\Phi^k_i|^S\Phi^l_j} = \sum_m \sum_n \left( O^k_{i,m}\right)^{\dagger} \braket{^S\phi_m(i,k)|^S\phi_n(j,l)} O^l_{j,n} \braket{^S\Phi^k_i|^S\Phi^l_j} = \sum_m \sum_n \left( O^k_{i,m}\right)^{\dagger} \braket{^S\phi_m(i,k)|^S\phi_n(j,l)} O^l_{j,n}
\end{equation} \end{equation}
Therefore, the overlap between two CSFs can be expanded in terms of the overlap Therefore, the overlap between two CSFs can be expanded in terms of the overlap
between the constituent BFs. The overlap matrix \[S_{mn}\] is of dimension \[\left( N^k_{N_{BF}} , N^l_{N_{BF}} \rigth)\]. between the constituent BFs. The overlap matrix \(S_{mn}\) is of dimension \(\left( N^k_{N_{BF}} , N^l_{N_{BF}} \right)\).
The equation shown above (Eq:~\ref{Eq:defineovlp2}) can be written in marix-form as The equation shown above (Eq: [[Eq:defineovlp2]]) can be written in marix-form as
shown below in Eq:~\ref{Eq:defineovlp3}. shown below in Eq: [[Eq:defineovlp3]].
#+NAME: Eq:defineovlp3
\begin{equation} \begin{equation}
\label{Eq:defineovlp3}
\braket{^S\Phi_i|^S\Phi_j} = \left( C_{i,1} \right)^{\dagger} \mathbf{O}_i\cdot\mathbf{S}_{ij}\cdot\mathbf{O}_j C_{j,1} \braket{^S\Phi_i|^S\Phi_j} = \left( C_{i,1} \right)^{\dagger} \mathbf{O}_i\cdot\mathbf{S}_{ij}\cdot\mathbf{O}_j C_{j,1}
\end{equation} \end{equation}
@ -110,16 +119,13 @@
labels. It only depends on the number of Singly Occupied Molecular Orbitals labels. It only depends on the number of Singly Occupied Molecular Orbitals
(SOMOs) therefore it can be pretabulated. Actually, it is possible to (SOMOs) therefore it can be pretabulated. Actually, it is possible to
redefine the CSFs in terms of a linear combination of BFs such that redefine the CSFs in terms of a linear combination of BFs such that
\[S_{ij}\] becomes the identity matrix. In this case, one needs to store the \(S_{ij}\) becomes the identity matrix. In this case, one needs to store the
orthogonalization matrix \[\mathbf{\tilde{O}}_i\] which is given by orthogonalization matrix \(\mathbf{\tilde{O}}_i\) which is given by
\[\mathbf{O}_i\cdot S^{1/2}_i\] for a given CFG \[i\]. Note that the a CFG \(\mathbf{O}_i\cdot S^{1/2}_i\) for a given CFG \(i\). Note that the a CFG
\[i\] is by definition of an orthonormal set of MOs automatically orthogonal \(i\) is by definition of an orthonormal set of MOs automatically orthogonal
to a CFG \[j\] with a different occupation. to a CFG \(j\) with a different occupation.
* Definition of matrix-elements ** Definition of matrix-elements
The matrix-element (ME) evaluation follows a similar logic. The matrix-element (ME) evaluation follows a similar logic.
# Local variables:
# after-save-hook: org-preview-latex-fragment
# end:

Binary file not shown.

View File

@ -102,7 +102,7 @@ subroutine run_cipsi
call write_double(6,correlation_energy_ratio, 'Correlation ratio') call write_double(6,correlation_energy_ratio, 'Correlation ratio')
call print_summary(psi_energy_with_nucl_rep, & call print_summary(psi_energy_with_nucl_rep, &
pt2_data, pt2_data_err, N_det,N_occ_pattern,N_states,psi_s2) pt2_data, pt2_data_err, N_det,N_configuration,N_states,psi_s2)
call save_energy(psi_energy_with_nucl_rep, pt2_data % pt2) call save_energy(psi_energy_with_nucl_rep, pt2_data % pt2)
@ -144,13 +144,13 @@ subroutine run_cipsi
SOFT_TOUCH threshold_generators SOFT_TOUCH threshold_generators
endif endif
print *, 'N_det = ', N_det print *, 'N_det = ', N_det
print *, 'N_sop = ', N_occ_pattern print *, 'N_cfg = ', N_configuration
print *, 'N_states = ', N_states print *, 'N_states = ', N_states
print*, 'correlation_ratio = ', correlation_energy_ratio print*, 'correlation_ratio = ', correlation_energy_ratio
call save_energy(psi_energy_with_nucl_rep, pt2_data % pt2) call save_energy(psi_energy_with_nucl_rep, pt2_data % pt2)
call print_summary(psi_energy_with_nucl_rep(1:N_states), & call print_summary(psi_energy_with_nucl_rep(1:N_states), &
pt2_data, pt2_data_err, N_det,N_occ_pattern,N_states,psi_s2) pt2_data, pt2_data_err, N_det,N_configuration,N_states,psi_s2)
call save_iterations(psi_energy_with_nucl_rep(1:N_states),pt2_data % rpt2,N_det) call save_iterations(psi_energy_with_nucl_rep(1:N_states),pt2_data % rpt2,N_det)
call print_extrapolated_energy() call print_extrapolated_energy()
endif endif

View File

@ -22,7 +22,7 @@ BEGIN_PROVIDER [ double precision, pt2_E0_denominator, (N_states) ]
enddo enddo
else if (h0_type == "Barycentric") then else if (h0_type == "Barycentric") then
pt2_E0_denominator(1:N_states) = barycentric_electronic_energy(1:N_states) pt2_E0_denominator(1:N_states) = barycentric_electronic_energy(1:N_states)
else if (h0_type == "SOP") then else if (h0_type == "CFG") then
pt2_E0_denominator(1:N_states) = psi_energy(1:N_states) pt2_E0_denominator(1:N_states) = psi_energy(1:N_states)
else else
print *, h0_type, ' not implemented' print *, h0_type, ' not implemented'

View File

@ -71,9 +71,9 @@ subroutine fill_buffer_double_rdm(i_generator, sp, h1, h2, bannedOrb, banned, fo
call apply_holes(psi_det_generators(1,1,i_generator), s1, h1, s2, h2, mask, ok, N_int) call apply_holes(psi_det_generators(1,1,i_generator), s1, h1, s2, h2, mask, ok, N_int)
E_shift = 0.d0 E_shift = 0.d0
if (h0_type == 'SOP') then if (h0_type == 'CFG') then
j = det_to_occ_pattern(i_generator) j = det_to_configuration(i_generator)
E_shift = psi_det_Hii(i_generator) - psi_occ_pattern_Hii(j) E_shift = psi_det_Hii(i_generator) - psi_configuration_Hii(j)
endif endif
do p1=1,mo_num do p1=1,mo_num

View File

@ -134,8 +134,8 @@ subroutine ZMQ_pt2(E, pt2_data, pt2_data_err, relative_error, N_in)
PROVIDE psi_bilinear_matrix_transp_order psi_selectors_coef_transp psi_det_sorted PROVIDE psi_bilinear_matrix_transp_order psi_selectors_coef_transp psi_det_sorted
PROVIDE psi_det_hii selection_weight pseudo_sym PROVIDE psi_det_hii selection_weight pseudo_sym
if (h0_type == 'SOP') then if (h0_type == 'CFG') then
PROVIDE psi_occ_pattern_hii det_to_occ_pattern PROVIDE psi_configuration_hii det_to_configuration
endif endif
if (N_det <= max(4,N_states) .or. pt2_N_teeth < 2) then if (N_det <= max(4,N_states) .or. pt2_N_teeth < 2) then

View File

@ -700,9 +700,9 @@ subroutine fill_buffer_double(i_generator, sp, h1, h2, bannedOrb, banned, fock_d
call apply_holes(psi_det_generators(1,1,i_generator), s1, h1, s2, h2, mask, ok, N_int) call apply_holes(psi_det_generators(1,1,i_generator), s1, h1, s2, h2, mask, ok, N_int)
E_shift = 0.d0 E_shift = 0.d0
if (h0_type == 'SOP') then if (h0_type == 'CFG') then
j = det_to_occ_pattern(i_generator) j = det_to_configuration(i_generator)
E_shift = psi_det_Hii(i_generator) - psi_occ_pattern_Hii(j) E_shift = psi_det_Hii(i_generator) - psi_configuration_Hii(j)
endif endif
do p1=1,mo_num do p1=1,mo_num
@ -766,8 +766,8 @@ subroutine fill_buffer_double(i_generator, sp, h1, h2, bannedOrb, banned, fock_d
w = 0d0 w = 0d0
! integer(bit_kind) :: occ(N_int,2), n ! integer(bit_kind) :: occ(N_int,2), n
! call occ_pattern_of_det(det,occ,N_int) ! call configuration_of_det(det,occ,N_int)
! call occ_pattern_to_dets_size(occ,n,elec_alpha_num,N_int) ! call configuration_to_dets_size(occ,n,elec_alpha_num,N_int)
e_pert = 0.d0 e_pert = 0.d0
coef = 0.d0 coef = 0.d0

View File

@ -175,7 +175,7 @@ subroutine make_selection_buffer_s2(b)
! Sort ! Sort
integer, allocatable :: iorder(:) integer, allocatable :: iorder(:)
integer*8, allocatable :: bit_tmp(:) integer*8, allocatable :: bit_tmp(:)
integer*8, external :: occ_pattern_search_key integer*8, external :: configuration_search_key
integer(bit_kind), allocatable :: tmp_array(:,:,:) integer(bit_kind), allocatable :: tmp_array(:,:,:)
logical, allocatable :: duplicate(:) logical, allocatable :: duplicate(:)
@ -193,7 +193,7 @@ subroutine make_selection_buffer_s2(b)
o(k,2,i) = iand(b%det(k,1,i), b%det(k,2,i)) o(k,2,i) = iand(b%det(k,1,i), b%det(k,2,i))
enddo enddo
iorder(i) = i iorder(i) = i
bit_tmp(i) = occ_pattern_search_key(o(1,1,i),N_int) bit_tmp(i) = configuration_search_key(o(1,1,i),N_int)
enddo enddo
deallocate(b%det) deallocate(b%det)
@ -279,7 +279,7 @@ subroutine make_selection_buffer_s2(b)
! Create determinants ! Create determinants
n_d = 0 n_d = 0
do i=1,n_p do i=1,n_p
call occ_pattern_to_dets_size(o(1,1,i),sze,elec_alpha_num,N_int) call configuration_to_dets_size(o(1,1,i),sze,elec_alpha_num,N_int)
n_d = n_d + sze n_d = n_d + sze
if (n_d > b%cur) then if (n_d > b%cur) then
! if (n_d - b%cur > b%cur - n_d + sze) then ! if (n_d - b%cur > b%cur - n_d + sze) then
@ -295,8 +295,8 @@ subroutine make_selection_buffer_s2(b)
k=1 k=1
do i=1,n_p do i=1,n_p
n=n_d n=n_d
call occ_pattern_to_dets_size(o(1,1,i),n,elec_alpha_num,N_int) call configuration_to_dets_size(o(1,1,i),n,elec_alpha_num,N_int)
call occ_pattern_to_dets(o(1,1,i),b%det(1,1,k),n,elec_alpha_num,N_int) call configuration_to_dets(o(1,1,i),b%det(1,1,k),n,elec_alpha_num,N_int)
do j=k,k+n-1 do j=k,k+n-1
b%val(j) = val(i) b%val(j) = val(i)
enddo enddo

View File

@ -296,8 +296,8 @@ subroutine run_slave_main
print *, 'Number of threads', nproc_target print *, 'Number of threads', nproc_target
endif endif
if (h0_type == 'SOP') then if (h0_type == 'CFG') then
PROVIDE det_to_occ_pattern PROVIDE det_to_configuration
endif endif
PROVIDE global_selection_buffer PROVIDE global_selection_buffer

View File

@ -92,7 +92,7 @@ subroutine run_stochastic_cipsi
call write_double(6,correlation_energy_ratio, 'Correlation ratio') call write_double(6,correlation_energy_ratio, 'Correlation ratio')
call print_summary(psi_energy_with_nucl_rep, & call print_summary(psi_energy_with_nucl_rep, &
pt2_data, pt2_data_err, N_det,N_occ_pattern,N_states,psi_s2) pt2_data, pt2_data_err, N_det,N_configuration,N_states,psi_s2)
call save_energy(psi_energy_with_nucl_rep, pt2_data % pt2) call save_energy(psi_energy_with_nucl_rep, pt2_data % pt2)
@ -131,7 +131,7 @@ subroutine run_stochastic_cipsi
call save_energy(psi_energy_with_nucl_rep, pt2_data % pt2) call save_energy(psi_energy_with_nucl_rep, pt2_data % pt2)
call print_summary(psi_energy_with_nucl_rep, & call print_summary(psi_energy_with_nucl_rep, &
pt2_data , pt2_data_err, N_det, N_occ_pattern, N_states, psi_s2) pt2_data , pt2_data_err, N_det, N_configuration, N_states, psi_s2)
call save_iterations(psi_energy_with_nucl_rep(1:N_states),pt2_data % rpt2,N_det) call save_iterations(psi_energy_with_nucl_rep(1:N_states),pt2_data % rpt2,N_det)
call print_extrapolated_energy() call print_extrapolated_energy()
endif endif

View File

@ -1,9 +1,9 @@
use bitmasks use bitmasks
subroutine occ_pattern_of_det(d,o,Nint) subroutine configuration_of_det(d,o,Nint)
use bitmasks use bitmasks
implicit none implicit none
BEGIN_DOC BEGIN_DOC
! Transforms a determinant to an occupation pattern ! Transforms a determinant to a configuration
! !
! occ(:,1) : Single occupations ! occ(:,1) : Single occupations
! !
@ -23,11 +23,11 @@ subroutine occ_pattern_of_det(d,o,Nint)
end end
subroutine occ_pattern_to_dets_size(o,sze,n_alpha,Nint) subroutine configuration_to_dets_size(o,sze,n_alpha,Nint)
use bitmasks use bitmasks
implicit none implicit none
BEGIN_DOC BEGIN_DOC
! Number of possible determinants for a given occ_pattern ! Number of possible determinants for a given configuration
END_DOC END_DOC
integer ,intent(in) :: Nint, n_alpha integer ,intent(in) :: Nint, n_alpha
integer(bit_kind),intent(in) :: o(Nint,2) integer(bit_kind),intent(in) :: o(Nint,2)
@ -49,15 +49,15 @@ subroutine occ_pattern_to_dets_size(o,sze,n_alpha,Nint)
end end
subroutine occ_pattern_to_dets(o,d,sze,n_alpha,Nint) subroutine configuration_to_dets(o,d,sze,n_alpha,Nint)
use bitmasks use bitmasks
implicit none implicit none
BEGIN_DOC BEGIN_DOC
! Generate all possible determinants for a given occ_pattern ! Generate all possible determinants for a given configuration
! !
! Input : ! Input :
! o : occupation pattern : (doubly occupied, singly occupied) ! o : configuration : (doubly occupied, singly occupied)
! sze : Number of produced determinants, computed by `occ_pattern_to_dets_size` ! sze : Number of produced determinants, computed by `configuration_to_dets_size`
! n_alpha : Number of $\alpha$ electrons ! n_alpha : Number of $\alpha$ electrons
! Nint : N_int ! Nint : N_int
! !
@ -184,32 +184,32 @@ subroutine occ_pattern_to_dets(o,d,sze,n_alpha,Nint)
end end
BEGIN_PROVIDER [ integer(bit_kind), psi_occ_pattern, (N_int,2,psi_det_size) ] BEGIN_PROVIDER [ integer(bit_kind), psi_configuration, (N_int,2,psi_det_size) ]
&BEGIN_PROVIDER [ integer, N_occ_pattern ] &BEGIN_PROVIDER [ integer, N_configuration ]
implicit none implicit none
BEGIN_DOC BEGIN_DOC
! Array of the occ_patterns present in the wave function. ! Array of the configurations present in the wave function.
! !
! psi_occ_pattern(:,1,j) = j-th occ_pattern of the wave function : represents all the single occupations ! psi_configuration(:,1,j) = j-th configuration of the wave function : represents all the single occupations
! !
! psi_occ_pattern(:,2,j) = j-th occ_pattern of the wave function : represents all the double occupations ! psi_configuration(:,2,j) = j-th configuration of the wave function : represents all the double occupations
! !
! The occ patterns are sorted by :c:func:`occ_pattern_search_key` ! The occ patterns are sorted by :c:func:`configuration_search_key`
END_DOC END_DOC
integer :: i,j,k integer :: i,j,k
! create ! create
do i = 1, N_det do i = 1, N_det
do k = 1, N_int do k = 1, N_int
psi_occ_pattern(k,1,i) = ieor(psi_det(k,1,i),psi_det(k,2,i)) psi_configuration(k,1,i) = ieor(psi_det(k,1,i),psi_det(k,2,i))
psi_occ_pattern(k,2,i) = iand(psi_det(k,1,i),psi_det(k,2,i)) psi_configuration(k,2,i) = iand(psi_det(k,1,i),psi_det(k,2,i))
enddo enddo
enddo enddo
! Sort ! Sort
integer, allocatable :: iorder(:) integer, allocatable :: iorder(:)
integer*8, allocatable :: bit_tmp(:) integer*8, allocatable :: bit_tmp(:)
integer*8, external :: occ_pattern_search_key integer*8, external :: configuration_search_key
integer(bit_kind), allocatable :: tmp_array(:,:,:) integer(bit_kind), allocatable :: tmp_array(:,:,:)
logical,allocatable :: duplicate(:) logical,allocatable :: duplicate(:)
logical :: dup logical :: dup
@ -219,7 +219,7 @@ end
do i=1,N_det do i=1,N_det
iorder(i) = i iorder(i) = i
bit_tmp(i) = occ_pattern_search_key(psi_occ_pattern(1,1,i),N_int) bit_tmp(i) = configuration_search_key(psi_configuration(1,1,i),N_int)
enddo enddo
call i8sort(bit_tmp,iorder,N_det) call i8sort(bit_tmp,iorder,N_det)
@ -230,8 +230,8 @@ end
!$OMP DO !$OMP DO
do i=1,N_det do i=1,N_det
do k=1,N_int do k=1,N_int
tmp_array(k,1,i) = psi_occ_pattern(k,1,iorder(i)) tmp_array(k,1,i) = psi_configuration(k,1,iorder(i))
tmp_array(k,2,i) = psi_occ_pattern(k,2,iorder(i)) tmp_array(k,2,i) = psi_configuration(k,2,iorder(i))
enddo enddo
duplicate(i) = .False. duplicate(i) = .False.
enddo enddo
@ -273,36 +273,36 @@ end
!$OMP END PARALLEL !$OMP END PARALLEL
! Copy filtered result ! Copy filtered result
N_occ_pattern=0 N_configuration=0
do i=1,N_det do i=1,N_det
if (duplicate(i)) then if (duplicate(i)) then
cycle cycle
endif endif
N_occ_pattern += 1 N_configuration += 1
do k=1,N_int do k=1,N_int
psi_occ_pattern(k,1,N_occ_pattern) = tmp_array(k,1,i) psi_configuration(k,1,N_configuration) = tmp_array(k,1,i)
psi_occ_pattern(k,2,N_occ_pattern) = tmp_array(k,2,i) psi_configuration(k,2,N_configuration) = tmp_array(k,2,i)
enddo enddo
enddo enddo
!- Check !- Check
! print *, 'Checking for duplicates in occ pattern' ! print *, 'Checking for duplicates in occ pattern'
! do i=1,N_occ_pattern ! do i=1,N_configuration
! do j=i+1,N_occ_pattern ! do j=i+1,N_configuration
! duplicate(1) = .True. ! duplicate(1) = .True.
! do k=1,N_int ! do k=1,N_int
! if (psi_occ_pattern(k,1,i) /= psi_occ_pattern(k,1,j)) then ! if (psi_configuration(k,1,i) /= psi_configuration(k,1,j)) then
! duplicate(1) = .False. ! duplicate(1) = .False.
! exit ! exit
! endif ! endif
! if (psi_occ_pattern(k,2,i) /= psi_occ_pattern(k,2,j)) then ! if (psi_configuration(k,2,i) /= psi_configuration(k,2,j)) then
! duplicate(1) = .False. ! duplicate(1) = .False.
! exit ! exit
! endif ! endif
! enddo ! enddo
! if (duplicate(1)) then ! if (duplicate(1)) then
! call debug_det(psi_occ_pattern(1,1,i),N_int) ! call debug_det(psi_configuration(1,1,i),N_int)
! call debug_det(psi_occ_pattern(1,1,j),N_int) ! call debug_det(psi_configuration(1,1,j),N_int)
! stop 'DUPLICATE' ! stop 'DUPLICATE'
! endif ! endif
! enddo ! enddo
@ -313,21 +313,21 @@ end
END_PROVIDER END_PROVIDER
BEGIN_PROVIDER [ integer, det_to_occ_pattern, (N_det) ] BEGIN_PROVIDER [ integer, det_to_configuration, (N_det) ]
implicit none implicit none
BEGIN_DOC BEGIN_DOC
! Returns the index of the occupation pattern for each determinant ! Returns the index of the configuration for each determinant
END_DOC END_DOC
integer :: i,j,k,r,l integer :: i,j,k,r,l
integer*8 :: key integer*8 :: key
integer(bit_kind) :: occ(N_int,2) integer(bit_kind) :: occ(N_int,2)
logical :: found logical :: found
integer*8, allocatable :: bit_tmp(:) integer*8, allocatable :: bit_tmp(:)
integer*8, external :: occ_pattern_search_key integer*8, external :: configuration_search_key
allocate(bit_tmp(N_occ_pattern)) allocate(bit_tmp(N_configuration))
do i=1,N_occ_pattern do i=1,N_configuration
bit_tmp(i) = occ_pattern_search_key(psi_occ_pattern(1,1,i),N_int) bit_tmp(i) = configuration_search_key(psi_configuration(1,1,i),N_int)
enddo enddo
!$OMP PARALLEL DO DEFAULT(SHARED) & !$OMP PARALLEL DO DEFAULT(SHARED) &
@ -338,11 +338,11 @@ BEGIN_PROVIDER [ integer, det_to_occ_pattern, (N_det) ]
occ(k,2) = iand(psi_det(k,1,i),psi_det(k,2,i)) occ(k,2) = iand(psi_det(k,1,i),psi_det(k,2,i))
enddo enddo
key = occ_pattern_search_key(occ,N_int) key = configuration_search_key(occ,N_int)
! TODO: Binary search ! TODO: Binary search
l = 1 l = 1
r = N_occ_pattern r = N_configuration
! do while(r-l > 32) ! do while(r-l > 32)
! j = shiftr(r+l,1) ! j = shiftr(r+l,1)
! if (bit_tmp(j) < key) then ! if (bit_tmp(j) < key) then
@ -354,14 +354,14 @@ BEGIN_PROVIDER [ integer, det_to_occ_pattern, (N_det) ]
do j=l,r do j=l,r
found = .True. found = .True.
do k=1,N_int do k=1,N_int
if ( (occ(k,1) /= psi_occ_pattern(k,1,j)) & if ( (occ(k,1) /= psi_configuration(k,1,j)) &
.or. (occ(k,2) /= psi_occ_pattern(k,2,j)) ) then .or. (occ(k,2) /= psi_configuration(k,2,j)) ) then
found = .False. found = .False.
exit exit
endif endif
enddo enddo
if (found) then if (found) then
det_to_occ_pattern(i) = j det_to_configuration(i) = j
exit exit
endif endif
enddo enddo
@ -376,78 +376,78 @@ BEGIN_PROVIDER [ integer, det_to_occ_pattern, (N_det) ]
END_PROVIDER END_PROVIDER
BEGIN_PROVIDER [ double precision, psi_occ_pattern_Hii, (N_occ_pattern) ] BEGIN_PROVIDER [ double precision, psi_configuration_Hii, (N_configuration) ]
implicit none implicit none
BEGIN_DOC BEGIN_DOC
! $\langle I|H|I \rangle$ where $|I\rangle$ is an occupation pattern. ! $\langle I|H|I \rangle$ where $|I\rangle$ is a configuration.
! This is the minimum $H_{ii}$, where the $|i\rangle$ are the ! This is the minimum $H_{ii}$, where the $|i\rangle$ are the
! determinants of $|I\rangle$. ! determinants of $|I\rangle$.
END_DOC END_DOC
integer :: j, i integer :: j, i
psi_occ_pattern_Hii(:) = huge(1.d0) psi_configuration_Hii(:) = huge(1.d0)
do i=1,N_det do i=1,N_det
j = det_to_occ_pattern(i) j = det_to_configuration(i)
psi_occ_pattern_Hii(j) = min(psi_occ_pattern_Hii(j), psi_det_Hii(i)) psi_configuration_Hii(j) = min(psi_configuration_Hii(j), psi_det_Hii(i))
enddo enddo
END_PROVIDER END_PROVIDER
BEGIN_PROVIDER [ double precision, weight_occ_pattern, (N_occ_pattern,N_states) ] BEGIN_PROVIDER [ double precision, weight_configuration, (N_configuration,N_states) ]
implicit none implicit none
BEGIN_DOC BEGIN_DOC
! Weight of the occupation patterns in the wave function ! Weight of the configurations in the wave function
END_DOC END_DOC
integer :: i,j,k integer :: i,j,k
weight_occ_pattern = 0.d0 weight_configuration = 0.d0
do i=1,N_det do i=1,N_det
j = det_to_occ_pattern(i) j = det_to_configuration(i)
do k=1,N_states do k=1,N_states
weight_occ_pattern(j,k) += psi_coef(i,k) * psi_coef(i,k) weight_configuration(j,k) += psi_coef(i,k) * psi_coef(i,k)
enddo enddo
enddo enddo
END_PROVIDER END_PROVIDER
BEGIN_PROVIDER [ double precision, weight_occ_pattern_average, (N_occ_pattern) ] BEGIN_PROVIDER [ double precision, weight_configuration_average, (N_configuration) ]
implicit none implicit none
BEGIN_DOC BEGIN_DOC
! State-average weight of the occupation patterns in the wave function ! State-average weight of the configurations in the wave function
END_DOC END_DOC
integer :: i,j,k integer :: i,j,k
weight_occ_pattern_average(:) = 0.d0 weight_configuration_average(:) = 0.d0
do i=1,N_det do i=1,N_det
j = det_to_occ_pattern(i) j = det_to_configuration(i)
do k=1,N_states do k=1,N_states
weight_occ_pattern_average(j) += psi_coef(i,k) * psi_coef(i,k) * state_average_weight(k) weight_configuration_average(j) += psi_coef(i,k) * psi_coef(i,k) * state_average_weight(k)
enddo enddo
enddo enddo
END_PROVIDER END_PROVIDER
BEGIN_PROVIDER [ integer(bit_kind), psi_occ_pattern_sorted, (N_int,2,N_occ_pattern) ] BEGIN_PROVIDER [ integer(bit_kind), psi_configuration_sorted, (N_int,2,N_configuration) ]
&BEGIN_PROVIDER [ double precision, weight_occ_pattern_average_sorted, (N_occ_pattern) ] &BEGIN_PROVIDER [ double precision, weight_configuration_average_sorted, (N_configuration) ]
&BEGIN_PROVIDER [ integer, psi_occ_pattern_sorted_order, (N_occ_pattern) ] &BEGIN_PROVIDER [ integer, psi_configuration_sorted_order, (N_configuration) ]
&BEGIN_PROVIDER [ integer, psi_occ_pattern_sorted_order_reverse, (N_occ_pattern) ] &BEGIN_PROVIDER [ integer, psi_configuration_sorted_order_reverse, (N_configuration) ]
implicit none implicit none
BEGIN_DOC BEGIN_DOC
! Occupation patterns sorted by weight ! Configurations sorted by weight
END_DOC END_DOC
integer :: i,j,k integer :: i,j,k
integer, allocatable :: iorder(:) integer, allocatable :: iorder(:)
allocate ( iorder(N_occ_pattern) ) allocate ( iorder(N_configuration) )
do i=1,N_occ_pattern do i=1,N_configuration
weight_occ_pattern_average_sorted(i) = -weight_occ_pattern_average(i) weight_configuration_average_sorted(i) = -weight_configuration_average(i)
iorder(i) = i iorder(i) = i
enddo enddo
call dsort(weight_occ_pattern_average_sorted,iorder,N_occ_pattern) call dsort(weight_configuration_average_sorted,iorder,N_configuration)
do i=1,N_occ_pattern do i=1,N_configuration
do j=1,N_int do j=1,N_int
psi_occ_pattern_sorted(j,1,i) = psi_occ_pattern(j,1,iorder(i)) psi_configuration_sorted(j,1,i) = psi_configuration(j,1,iorder(i))
psi_occ_pattern_sorted(j,2,i) = psi_occ_pattern(j,2,iorder(i)) psi_configuration_sorted(j,2,i) = psi_configuration(j,2,iorder(i))
enddo enddo
psi_occ_pattern_sorted_order(iorder(i)) = i psi_configuration_sorted_order(iorder(i)) = i
psi_occ_pattern_sorted_order_reverse(i) = iorder(i) psi_configuration_sorted_order_reverse(i) = iorder(i)
weight_occ_pattern_average_sorted(i) = -weight_occ_pattern_average_sorted(i) weight_configuration_average_sorted(i) = -weight_configuration_average_sorted(i)
enddo enddo
deallocate(iorder) deallocate(iorder)
@ -466,27 +466,27 @@ subroutine make_s2_eigenfunction
logical :: update logical :: update
update=.False. update=.False.
call write_int(6,N_occ_pattern,'Number of occupation patterns') call write_int(6,N_configuration,'Number of configurations')
!$OMP PARALLEL DEFAULT(NONE) & !$OMP PARALLEL DEFAULT(NONE) &
!$OMP SHARED(N_occ_pattern, psi_occ_pattern, elec_alpha_num,N_int,update) & !$OMP SHARED(N_configuration, psi_configuration, elec_alpha_num,N_int,update) &
!$OMP PRIVATE(s,ithread, d, det_buffer, smax, N_det_new,i,j,k) !$OMP PRIVATE(s,ithread, d, det_buffer, smax, N_det_new,i,j,k)
N_det_new = 0 N_det_new = 0
call occ_pattern_to_dets_size(psi_occ_pattern(1,1,1),s,elec_alpha_num,N_int) call configuration_to_dets_size(psi_configuration(1,1,1),s,elec_alpha_num,N_int)
allocate (d(N_int,2,s+64), det_buffer(N_int,2,bufsze) ) allocate (d(N_int,2,s+64), det_buffer(N_int,2,bufsze) )
smax = s smax = s
ithread=0 ithread=0
!$ ithread = omp_get_thread_num() !$ ithread = omp_get_thread_num()
!$OMP DO SCHEDULE (dynamic,1000) !$OMP DO SCHEDULE (dynamic,1000)
do i=1,N_occ_pattern do i=1,N_configuration
call occ_pattern_to_dets_size(psi_occ_pattern(1,1,i),s,elec_alpha_num,N_int) call configuration_to_dets_size(psi_configuration(1,1,i),s,elec_alpha_num,N_int)
s += 1 s += 1
if (s > smax) then if (s > smax) then
deallocate(d) deallocate(d)
allocate ( d(N_int,2,s+64) ) allocate ( d(N_int,2,s+64) )
smax = s smax = s
endif endif
call occ_pattern_to_dets(psi_occ_pattern(1,1,i),d,s,elec_alpha_num,N_int) call configuration_to_dets(psi_configuration(1,1,i),d,s,elec_alpha_num,N_int)
do j=1,s do j=1,s
if ( is_in_wavefunction(d(1,1,j), N_int) ) then if ( is_in_wavefunction(d(1,1,j), N_int) ) then
cycle cycle
@ -511,7 +511,7 @@ subroutine make_s2_eigenfunction
if (update) then if (update) then
call copy_H_apply_buffer_to_wf call copy_H_apply_buffer_to_wf
TOUCH N_det psi_coef psi_det psi_occ_pattern N_occ_pattern TOUCH N_det psi_coef psi_det psi_configuration N_configuration
endif endif
call write_time(6) call write_time(6)

View File

@ -12,7 +12,7 @@ integer*8 function det_search_key(det,Nint)
end end
integer*8 function occ_pattern_search_key(det,Nint) integer*8 function configuration_search_key(det,Nint)
use bitmasks use bitmasks
implicit none implicit none
BEGIN_DOC BEGIN_DOC
@ -22,7 +22,7 @@ integer*8 function occ_pattern_search_key(det,Nint)
integer(bit_kind), intent(in) :: det(Nint,2) integer(bit_kind), intent(in) :: det(Nint,2)
integer :: i integer :: i
i = shiftr(elec_alpha_num, bit_kind_shift)+1 i = shiftr(elec_alpha_num, bit_kind_shift)+1
occ_pattern_search_key = int(shiftr(ior(det(i,1),det(i,2)),1)+sum(det),8) configuration_search_key = int(shiftr(ior(det(i,1),det(i,2)),1)+sum(det),8)
end end

View File

@ -10,16 +10,16 @@ BEGIN_PROVIDER [ logical, pruned, (N_det) ]
return return
endif endif
integer :: i,j,k,ndet_new,nsop_max integer :: i,j,k,ndet_new,ncfg_max
double precision :: thr double precision :: thr
if (s2_eig) then if (s2_eig) then
nsop_max = max(1,int ( dble(N_occ_pattern) * (1.d0 - pruning) + 0.5d0 )) ncfg_max = max(1,int ( dble(N_configuration) * (1.d0 - pruning) + 0.5d0 ))
do i=1,N_det do i=1,N_det
k = det_to_occ_pattern(i) k = det_to_configuration(i)
pruned(i) = psi_occ_pattern_sorted_order_reverse(k) > nsop_max pruned(i) = psi_configuration_sorted_order_reverse(k) > ncfg_max
enddo enddo
else else

View File

@ -54,7 +54,7 @@ subroutine run
endif endif
call print_summary(psi_energy_with_nucl_rep(1:N_states), & call print_summary(psi_energy_with_nucl_rep(1:N_states), &
pt2_data, pt2_data_err, N_det,N_occ_pattern,N_states,psi_s2) pt2_data, pt2_data_err, N_det,N_configuration,N_states,psi_s2)
call save_energy(E_CI_before, pt2_data % pt2) call save_energy(E_CI_before, pt2_data % pt2)
call pt2_dealloc(pt2_data) call pt2_dealloc(pt2_data)

View File

@ -1,11 +1,11 @@
subroutine print_summary(e_,pt2_data,pt2_data_err,n_det_,n_occ_pattern_,n_st,s2_) subroutine print_summary(e_,pt2_data,pt2_data_err,n_det_,n_configuration_,n_st,s2_)
use selection_types use selection_types
implicit none implicit none
BEGIN_DOC BEGIN_DOC
! Print the extrapolated energy in the output ! Print the extrapolated energy in the output
END_DOC END_DOC
integer, intent(in) :: n_det_, n_occ_pattern_, n_st integer, intent(in) :: n_det_, n_configuration_, n_st
double precision, intent(in) :: e_(n_st), s2_(n_st) double precision, intent(in) :: e_(n_st), s2_(n_st)
type(pt2_type) , intent(in) :: pt2_data, pt2_data_err type(pt2_type) , intent(in) :: pt2_data, pt2_data_err
integer :: i, k integer :: i, k
@ -57,7 +57,7 @@ subroutine print_summary(e_,pt2_data,pt2_data_err,n_det_,n_occ_pattern_,n_st,s2_
print *, 'N_det = ', N_det_ print *, 'N_det = ', N_det_
print *, 'N_states = ', n_st print *, 'N_states = ', n_st
if (s2_eig) then if (s2_eig) then
print *, 'N_sop = ', N_occ_pattern_ print *, 'N_cfg = ', N_configuration_
endif endif
print *, '' print *, ''

View File

@ -36,6 +36,6 @@ default: 1.00
[h0_type] [h0_type]
type: character*(32) type: character*(32)
doc: Type of denominator in PT2. [EN | SOP | HF] doc: Type of denominator in PT2. [EN | CFG | HF]
interface: ezfio,provider,ocaml interface: ezfio,provider,ocaml
default: EN default: EN