mirror of
https://github.com/LCPQ/quantum_package
synced 2024-10-19 22:41:48 +02:00
Merge branch 'eginer-toto'
This commit is contained in:
commit
81a30fcf1a
5
TODO
5
TODO
@ -7,12 +7,7 @@
|
||||
|
||||
* Creer une page web pas trop degueu et la mettre ici : http://lcpq.github.io/quantum_package
|
||||
* Manu : README
|
||||
* data_energy_and_density
|
||||
* dft_keywords
|
||||
* dft_quantities_on_grid
|
||||
* dft_utils_one_body
|
||||
* dm_for_dft
|
||||
* integrals_erf
|
||||
* prendre des bouts du src/README.rst et en mettre partout
|
||||
|
||||
|
||||
|
@ -9,6 +9,7 @@ ao_basis
|
||||
ao_one_e_integrals
|
||||
ao_two_e_integrals
|
||||
becke_numerical_grid
|
||||
aux_quantities
|
||||
bitmask
|
||||
cis
|
||||
cisd
|
||||
|
@ -67,13 +67,13 @@ just run
|
||||
|
||||
.. code:: bash
|
||||
|
||||
qp_run SCF hcn
|
||||
qp_run scf hcn
|
||||
|
||||
The expected energy is ``-92.827856698`` au.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The documentation of the :ref:`Hartree_Fock` module.
|
||||
The documentation of the :ref:`hartree_fock` module.
|
||||
|
||||
|
||||
Choose the target |MO| space
|
||||
@ -95,7 +95,7 @@ We will now use the |CIPSI| algorithm to estimate the |FCI| energy.
|
||||
|
||||
.. code::
|
||||
|
||||
qp_run FCI hcn
|
||||
qp_run fci hcn
|
||||
|
||||
|
||||
The program will start with a single determinant and will iteratively:
|
||||
@ -116,7 +116,7 @@ The estimated |FCI| energy of HCN is ``-93.0501`` au.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The documentation of the :ref:`FCI` module.
|
||||
The documentation of the :ref:`fci` module.
|
||||
|
||||
|
||||
.. important:: TODO
|
||||
|
@ -6,7 +6,7 @@ This module contains all quantities needed to build the Becke's grid used in gen
|
||||
|
||||
This grid is built as the reunion of a spherical grid around each atom. Each spherical grid contains a certain number of radial and angular points.
|
||||
|
||||
For a simple example of how to use the grid, see example.irp.f.
|
||||
For a simple example of how to use the grid, see :file:`example.irp.f`.
|
||||
|
||||
The spherical integration uses Lebedev-Laikov grids, which was used from the code distributed through CCL (http://www.ccl.net/).
|
||||
See next section for explanations and citation policies.
|
||||
|
@ -25,4 +25,4 @@ transforming a bit string to a list of integers for example.
|
||||
bit_kind = bit_kind_size / 8
|
||||
|
||||
|
||||
|
||||
For an example of how to use the bitmaks, see the file :file:`example.irp.f`.
|
||||
|
11
src/density_for_dft/EZFIO.cfg
Normal file
11
src/density_for_dft/EZFIO.cfg
Normal file
@ -0,0 +1,11 @@
|
||||
[density_for_dft]
|
||||
type: character*(32)
|
||||
doc: Type of density used for DFT calculation. If set to WFT , it uses the density of the wave function stored in (psi_det,psi_coef). If set to input_density it uses the one-body dm stored in aux_quantities/ . If set to damping_rs_dft it uses the damped density between WFT and input_density. In the ks_scf and rs_ks_scf programs, it is set to WFT.
|
||||
interface: ezfio, provider, ocaml
|
||||
default: WFT
|
||||
|
||||
[damping_for_rs_dft]
|
||||
type: double precision
|
||||
doc: damping factor for the density used in RSFT.
|
||||
interface: ezfio,provider,ocaml
|
||||
default: 0.5
|
@ -1,4 +1,12 @@
|
||||
==========
|
||||
DM_for_dft
|
||||
==========
|
||||
===============
|
||||
density_for_dft
|
||||
===============
|
||||
|
||||
|
||||
This module defines the *provider* of the density used for the DFT related calculations.
|
||||
This definition is done through the keyword :option:`density_for_dft density_for_dft`.
|
||||
The density can be:
|
||||
|
||||
# WFT : the density is computed with a potentially multi determinant wave function (see variables `psi_det` and `psi_det`)# input_density : the density is set to a density previously stored in the |EZFIO| folder (see ``aux_quantities``)
|
||||
# damping_rs_dft : the density is damped between the input_density and the WFT density, with a damping factor of :option:`density_for_dft damping_for_rs_dft`
|
||||
|
||||
|
@ -2,4 +2,4 @@
|
||||
Determinants
|
||||
============
|
||||
|
||||
Contains everything for the computation of the Hamiltonian in the basis of Slater determinants.
|
||||
Contains everything for the computation of the Hamiltonian matrix elements in the basis of orthogonal Slater determinants built on a restricted spin-orbitals basis.
|
||||
|
@ -16,14 +16,3 @@ doc: Percentage of HF exchange in the DFT model
|
||||
interface: ezfio,provider,ocaml
|
||||
default: 0.
|
||||
|
||||
[density_for_dft]
|
||||
type: character*(32)
|
||||
doc: Type of density used for DFT calculation. If WFT it uses the density of the WFT stored in terms of determinants. If input_density it uses the one-body dm stored in data_.../ . If damping_rs_dft it uses the damping density between WFT and input_density
|
||||
interface: ezfio, provider, ocaml
|
||||
default: WFT
|
||||
|
||||
[damping_for_rs_dft]
|
||||
type: double precision
|
||||
doc: damping factor for the density used in RSFT.
|
||||
interface: ezfio,provider,ocaml
|
||||
default: 0.5
|
||||
|
@ -2,6 +2,11 @@
|
||||
DFT Keywords
|
||||
============
|
||||
|
||||
This module contains all keywords which are related to a DFT calculation
|
||||
This module contains the main keywords related to a DFT calculation or RS-DFT calculation, such as:
|
||||
|
||||
# :option:exchange_functional
|
||||
# :option:correlation_functional
|
||||
# :option:HF_exchange : only relevent for the :ref:`ks_scf` program
|
||||
# :option:density_for_dft : mainly relevent for multi-determinant range separated DFT, see the plugins of eginer.
|
||||
|
||||
The keyword for the range separation parameter :math:`\mu` is the :option:`ao_two_e_erf_integrals mu_erf` keyword.
|
||||
|
@ -1,5 +1,4 @@
|
||||
dft_keywords
|
||||
determinants
|
||||
ao_basis
|
||||
mo_basis
|
||||
becke_numerical_grid
|
||||
|
@ -1,4 +1,21 @@
|
||||
===========
|
||||
RSDFT_Utils
|
||||
===========
|
||||
===============
|
||||
dft_utils_one_e
|
||||
===============
|
||||
|
||||
This module contains all the one-body related quantities needed to perform DFT or RS-DFT calculations.
|
||||
Therefore, it contains most of the properties which depends on the one-body density and density matrix.
|
||||
|
||||
The most important files and variables are:
|
||||
# The general *providers* for the x/c energies in :file:`e_xc_general.irp.f`
|
||||
# The general *providers* for the x/c potentials in :file:`pot_general.irp.f`
|
||||
# The short-range hartree operator and all related quantities in :file:`sr_coulomb.irp.f`
|
||||
These *providers* will be used in many DFT-related programs, such as :file:`ks_scf.irp.f` or :file:`rs_ks_scf.irp.f`.
|
||||
It is also needed to compute the effective one-body operator needed in multi-determinant RS-DFT (see plugins by eginer).
|
||||
|
||||
Some other interesting quantities:
|
||||
# The LDA and PBE *providers* for the x/c energies in :file:`e_xc.irp.f` and :file:`sr_exc.irp.f`
|
||||
# The LDA and PBE *providers* for the x/c potentials on the AO basis in :file:`pot_ao.irp.f` and :file:`sr_pot_ao.irp.f`
|
||||
# The :math:`h_{core}` energy computed directly with the one-body density matrix in :file:`one_e_energy_dft.irp.f`
|
||||
# LDA and PBE short-range functionals *subroutines* in :file:`exc_sr_lda.irp.f` and :file:`exc_sr_pbe.irp.f`
|
||||
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
BEGIN_PROVIDER [double precision, mu_erf_dft]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! range separation parameter used in RS-DFT. It is set to mu_erf in order to be consistent with the two electrons integrals erf
|
||||
END_DOC
|
||||
mu_erf_dft = mu_erf
|
||||
|
||||
END_PROVIDER
|
||||
|
190
src/dft_utils_one_e/pot_ao.irp.f
Normal file
190
src/dft_utils_one_e/pot_ao.irp.f
Normal file
@ -0,0 +1,190 @@
|
||||
BEGIN_PROVIDER[double precision, aos_vc_alpha_LDA_w, (n_points_final_grid,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, aos_vc_beta_LDA_w, (n_points_final_grid,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, aos_vx_alpha_LDA_w, (n_points_final_grid,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, aos_vx_beta_LDA_w, (n_points_final_grid,ao_num,N_states)]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! aos_vxc_alpha_LDA_w(j,i) = ao_i(r_j) * (v^x_alpha(r_j) + v^c_alpha(r_j)) * W(r_j)
|
||||
END_DOC
|
||||
integer :: istate,i,j
|
||||
double precision :: r(3)
|
||||
double precision :: mu,weight
|
||||
double precision :: e_c,vc_a,vc_b,e_x,vx_a,vx_b
|
||||
double precision, allocatable :: rhoa(:),rhob(:)
|
||||
double precision :: mu_local
|
||||
mu_local = 1.d-9
|
||||
allocate(rhoa(N_states), rhob(N_states))
|
||||
do istate = 1, N_states
|
||||
do i = 1, n_points_final_grid
|
||||
r(1) = final_grid_points(1,i)
|
||||
r(2) = final_grid_points(2,i)
|
||||
r(3) = final_grid_points(3,i)
|
||||
weight=final_weight_functions_at_final_grid_points(i)
|
||||
rhoa(istate) = one_body_dm_alpha_at_r(i,istate)
|
||||
rhob(istate) = one_body_dm_beta_at_r(i,istate)
|
||||
call ec_LDA_sr(mu_local,rhoa(istate),rhob(istate),e_c,vc_a,vc_b)
|
||||
call ex_LDA_sr(mu_local,rhoa(istate),rhob(istate),e_x,vx_a,vx_b)
|
||||
do j =1, ao_num
|
||||
aos_vc_alpha_LDA_w(i,j,istate) = vc_a * aos_in_r_array(j,i)*weight
|
||||
aos_vc_beta_LDA_w(i,j,istate) = vc_b * aos_in_r_array(j,i)*weight
|
||||
aos_vx_alpha_LDA_w(i,j,istate) = vx_a * aos_in_r_array(j,i)*weight
|
||||
aos_vx_beta_LDA_w(i,j,istate) = vx_b * aos_in_r_array(j,i)*weight
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
|
||||
END_PROVIDER
|
||||
|
||||
|
||||
BEGIN_PROVIDER [double precision, potential_x_alpha_ao_LDA,(ao_num,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER [double precision, potential_x_beta_ao_LDA,(ao_num,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER [double precision, potential_c_alpha_ao_LDA,(ao_num,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER [double precision, potential_c_beta_ao_LDA,(ao_num,ao_num,N_states)]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! short range exchange/correlation alpha/beta potentials with LDA functional on the AO basis
|
||||
END_DOC
|
||||
integer :: istate
|
||||
double precision :: wall_1,wall_2
|
||||
call wall_time(wall_1)
|
||||
do istate = 1, N_states
|
||||
call dgemm('N','N',ao_num,ao_num,n_points_final_grid,1.d0,aos_in_r_array,ao_num,aos_vc_alpha_LDA_w(1,1,istate),n_points_final_grid,0.d0,potential_c_alpha_ao_LDA(1,1,istate),ao_num)
|
||||
call dgemm('N','N',ao_num,ao_num,n_points_final_grid,1.d0,aos_in_r_array,ao_num,aos_vc_beta_LDA_w(1,1,istate) ,n_points_final_grid,0.d0,potential_c_beta_ao_LDA(1,1,istate),ao_num)
|
||||
call dgemm('N','N',ao_num,ao_num,n_points_final_grid,1.d0,aos_in_r_array,ao_num,aos_vx_alpha_LDA_w(1,1,istate),n_points_final_grid,0.d0,potential_x_alpha_ao_LDA(1,1,istate),ao_num)
|
||||
call dgemm('N','N',ao_num,ao_num,n_points_final_grid,1.d0,aos_in_r_array,ao_num,aos_vx_beta_LDA_w(1,1,istate) ,n_points_final_grid,0.d0,potential_x_beta_ao_LDA(1,1,istate),ao_num)
|
||||
enddo
|
||||
call wall_time(wall_2)
|
||||
print*,'time to provide potential_x/c_alpha/beta_ao_LDA = ',wall_2 - wall_1
|
||||
|
||||
END_PROVIDER
|
||||
|
||||
BEGIN_PROVIDER[double precision, aos_vc_alpha_PBE_w , (ao_num,n_points_final_grid,N_states)] !(n_points_final_grid,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, aos_vc_beta_PBE_w , (ao_num,n_points_final_grid,N_states)]!(n_points_final_grid,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, aos_vx_alpha_PBE_w , (ao_num,n_points_final_grid,N_states)] !(n_points_final_grid,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, aos_vx_beta_PBE_w , (ao_num,n_points_final_grid,N_states)]!(n_points_final_grid,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, aos_dvc_alpha_PBE_w , (ao_num,n_points_final_grid,3,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, aos_dvc_beta_PBE_w , (ao_num,n_points_final_grid,3,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, aos_dvx_alpha_PBE_w , (ao_num,n_points_final_grid,3,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, aos_dvx_beta_PBE_w , (ao_num,n_points_final_grid,3,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, grad_aos_dvc_alpha_PBE_w , (ao_num,n_points_final_grid,3,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, grad_aos_dvc_beta_PBE_w , (ao_num,n_points_final_grid,3,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, grad_aos_dvx_alpha_PBE_w , (ao_num,n_points_final_grid,3,N_states)]
|
||||
&BEGIN_PROVIDER[double precision, grad_aos_dvx_beta_PBE_w , (ao_num,n_points_final_grid,3,N_states)]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! aos_vxc_alpha_PBE_w(j,i) = ao_i(r_j) * (v^x_alpha(r_j) + v^c_alpha(r_j)) * W(r_j)
|
||||
END_DOC
|
||||
integer :: istate,i,j,m
|
||||
double precision :: r(3)
|
||||
double precision :: mu,weight
|
||||
double precision, allocatable :: ex(:), ec(:)
|
||||
double precision, allocatable :: rho_a(:),rho_b(:),grad_rho_a(:,:),grad_rho_b(:,:),grad_rho_a_2(:),grad_rho_b_2(:),grad_rho_a_b(:)
|
||||
double precision, allocatable :: contrib_grad_xa(:,:),contrib_grad_xb(:,:),contrib_grad_ca(:,:),contrib_grad_cb(:,:)
|
||||
double precision, allocatable :: vc_rho_a(:), vc_rho_b(:), vx_rho_a(:), vx_rho_b(:)
|
||||
double precision, allocatable :: vx_grad_rho_a_2(:), vx_grad_rho_b_2(:), vx_grad_rho_a_b(:), vc_grad_rho_a_2(:), vc_grad_rho_b_2(:), vc_grad_rho_a_b(:)
|
||||
allocate(vc_rho_a(N_states), vc_rho_b(N_states), vx_rho_a(N_states), vx_rho_b(N_states))
|
||||
allocate(vx_grad_rho_a_2(N_states), vx_grad_rho_b_2(N_states), vx_grad_rho_a_b(N_states), vc_grad_rho_a_2(N_states), vc_grad_rho_b_2(N_states), vc_grad_rho_a_b(N_states))
|
||||
|
||||
|
||||
allocate(rho_a(N_states), rho_b(N_states),grad_rho_a(3,N_states),grad_rho_b(3,N_states))
|
||||
allocate(grad_rho_a_2(N_states),grad_rho_b_2(N_states),grad_rho_a_b(N_states), ex(N_states), ec(N_states))
|
||||
allocate(contrib_grad_xa(3,N_states),contrib_grad_xb(3,N_states),contrib_grad_ca(3,N_states),contrib_grad_cb(3,N_states))
|
||||
do istate = 1, N_states
|
||||
do i = 1, n_points_final_grid
|
||||
r(1) = final_grid_points(1,i)
|
||||
r(2) = final_grid_points(2,i)
|
||||
r(3) = final_grid_points(3,i)
|
||||
weight=final_weight_functions_at_final_grid_points(i)
|
||||
rho_a(istate) = one_body_dm_alpha_and_grad_at_r(4,i,istate)
|
||||
rho_b(istate) = one_body_dm_beta_and_grad_at_r(4,i,istate)
|
||||
grad_rho_a(1:3,istate) = one_body_dm_alpha_and_grad_at_r(1:3,i,istate)
|
||||
grad_rho_b(1:3,istate) = one_body_dm_beta_and_grad_at_r(1:3,i,istate)
|
||||
grad_rho_a_2 = 0.d0
|
||||
grad_rho_b_2 = 0.d0
|
||||
grad_rho_a_b = 0.d0
|
||||
do m = 1, 3
|
||||
grad_rho_a_2(istate) += grad_rho_a(m,istate) * grad_rho_a(m,istate)
|
||||
grad_rho_b_2(istate) += grad_rho_b(m,istate) * grad_rho_b(m,istate)
|
||||
grad_rho_a_b(istate) += grad_rho_a(m,istate) * grad_rho_b(m,istate)
|
||||
enddo
|
||||
|
||||
! inputs
|
||||
call GGA_type_functionals(r,rho_a,rho_b,grad_rho_a_2,grad_rho_b_2,grad_rho_a_b, & ! outputs exchange
|
||||
ex,vx_rho_a,vx_rho_b,vx_grad_rho_a_2,vx_grad_rho_b_2,vx_grad_rho_a_b, & ! outputs correlation
|
||||
ec,vc_rho_a,vc_rho_b,vc_grad_rho_a_2,vc_grad_rho_b_2,vc_grad_rho_a_b )
|
||||
vx_rho_a(istate) *= weight
|
||||
vc_rho_a(istate) *= weight
|
||||
vx_rho_b(istate) *= weight
|
||||
vc_rho_b(istate) *= weight
|
||||
do m= 1,3
|
||||
contrib_grad_ca(m,istate) = weight * (2.d0 * vc_grad_rho_a_2(istate) * grad_rho_a(m,istate) + vc_grad_rho_a_b(istate) * grad_rho_b(m,istate))
|
||||
contrib_grad_xa(m,istate) = weight * (2.d0 * vx_grad_rho_a_2(istate) * grad_rho_a(m,istate) + vx_grad_rho_a_b(istate) * grad_rho_b(m,istate))
|
||||
contrib_grad_cb(m,istate) = weight * (2.d0 * vc_grad_rho_b_2(istate) * grad_rho_b(m,istate) + vc_grad_rho_a_b(istate) * grad_rho_a(m,istate))
|
||||
contrib_grad_xb(m,istate) = weight * (2.d0 * vx_grad_rho_b_2(istate) * grad_rho_b(m,istate) + vx_grad_rho_a_b(istate) * grad_rho_a(m,istate))
|
||||
enddo
|
||||
do j = 1, ao_num
|
||||
aos_vc_alpha_PBE_w(j,i,istate) = vc_rho_a(istate) * aos_in_r_array(j,i)
|
||||
aos_vc_beta_PBE_w (j,i,istate) = vc_rho_b(istate) * aos_in_r_array(j,i)
|
||||
aos_vx_alpha_PBE_w(j,i,istate) = vx_rho_a(istate) * aos_in_r_array(j,i)
|
||||
aos_vx_beta_PBE_w (j,i,istate) = vx_rho_b(istate) * aos_in_r_array(j,i)
|
||||
do m = 1,3
|
||||
aos_dvc_alpha_PBE_w(j,i,m,istate) = contrib_grad_ca(m,istate) * aos_in_r_array(j,i)
|
||||
aos_dvc_beta_PBE_w (j,i,m,istate) = contrib_grad_cb(m,istate) * aos_in_r_array(j,i)
|
||||
aos_dvx_alpha_PBE_w(j,i,m,istate) = contrib_grad_xa(m,istate) * aos_in_r_array(j,i)
|
||||
aos_dvx_beta_PBE_w (j,i,m,istate) = contrib_grad_xb(m,istate) * aos_in_r_array(j,i)
|
||||
|
||||
grad_aos_dvc_alpha_PBE_w (j,i,m,istate) = contrib_grad_ca(m,istate) * aos_grad_in_r_array(j,i,m)
|
||||
grad_aos_dvc_beta_PBE_w (j,i,m,istate) = contrib_grad_cb(m,istate) * aos_grad_in_r_array(j,i,m)
|
||||
grad_aos_dvx_alpha_PBE_w (j,i,m,istate) = contrib_grad_xa(m,istate) * aos_grad_in_r_array(j,i,m)
|
||||
grad_aos_dvx_beta_PBE_w (j,i,m,istate) = contrib_grad_xb(m,istate) * aos_grad_in_r_array(j,i,m)
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
|
||||
END_PROVIDER
|
||||
|
||||
|
||||
BEGIN_PROVIDER [double precision, potential_x_alpha_ao_PBE,(ao_num,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER [double precision, potential_x_beta_ao_PBE,(ao_num,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER [double precision, potential_c_alpha_ao_PBE,(ao_num,ao_num,N_states)]
|
||||
&BEGIN_PROVIDER [double precision, potential_c_beta_ao_PBE,(ao_num,ao_num,N_states)]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! exchange/correlation alpha/beta potentials with the short range PBE functional on the AO basis
|
||||
END_DOC
|
||||
integer :: istate, m
|
||||
double precision :: wall_1,wall_2
|
||||
call wall_time(wall_1)
|
||||
potential_c_alpha_ao_PBE = 0.d0
|
||||
potential_x_alpha_ao_PBE = 0.d0
|
||||
potential_c_beta_ao_PBE = 0.d0
|
||||
potential_x_beta_ao_PBE = 0.d0
|
||||
do istate = 1, N_states
|
||||
! correlation alpha
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,aos_vc_alpha_PBE_w(1,1,istate),size(aos_vc_alpha_PBE_w,1),aos_in_r_array,size(aos_in_r_array,1),1.d0,potential_c_alpha_ao_PBE(1,1,istate),size(potential_c_alpha_ao_PBE,1))
|
||||
! correlation beta
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,aos_vc_beta_PBE_w(1,1,istate),size(aos_vc_beta_PBE_w,1),aos_in_r_array,size(aos_in_r_array,1),1.d0,potential_c_beta_ao_PBE(1,1,istate),size(potential_c_beta_ao_PBE,1))
|
||||
! exchange alpha
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,aos_vx_alpha_PBE_w(1,1,istate),size(aos_vx_alpha_PBE_w,1),aos_in_r_array,size(aos_in_r_array,1),1.d0,potential_x_alpha_ao_PBE(1,1,istate),size(potential_x_alpha_ao_PBE,1))
|
||||
! exchange beta
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,aos_vx_beta_PBE_w(1,1,istate),size(aos_vx_beta_PBE_w,1), aos_in_r_array,size(aos_in_r_array,1),1.d0,potential_x_beta_ao_PBE(1,1,istate), size(potential_x_beta_ao_PBE,1))
|
||||
do m= 1,3
|
||||
! correlation alpha
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,aos_dvc_alpha_PBE_w(1,1,m,istate),size(aos_dvc_alpha_PBE_w,1),aos_grad_in_r_array(1,1,m),size(aos_grad_in_r_array,1),1.d0,potential_c_alpha_ao_PBE(1,1,istate),size(potential_c_alpha_ao_PBE,1))
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,grad_aos_dvc_alpha_PBE_w(1,1,m,istate),size(grad_aos_dvc_alpha_PBE_w,1),aos_in_r_array,size(aos_in_r_array,1),1.d0,potential_c_alpha_ao_PBE(1,1,istate),size(potential_c_alpha_ao_PBE,1))
|
||||
! correlation beta
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,aos_dvc_beta_PBE_w(1,1,m,istate),size(aos_dvc_beta_PBE_w,1),aos_grad_in_r_array(1,1,m),size(aos_grad_in_r_array,1),1.d0,potential_c_beta_ao_PBE(1,1,istate),size(potential_c_beta_ao_PBE,1))
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,grad_aos_dvc_beta_PBE_w(1,1,m,istate),size(grad_aos_dvc_beta_PBE_w,1),aos_in_r_array,size(aos_in_r_array,1),1.d0,potential_c_beta_ao_PBE(1,1,istate),size(potential_c_beta_ao_PBE,1))
|
||||
! exchange alpha
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,aos_dvx_alpha_PBE_w(1,1,m,istate),size(aos_dvx_alpha_PBE_w,1),aos_grad_in_r_array(1,1,m),size(aos_grad_in_r_array,1),1.d0,potential_x_alpha_ao_PBE(1,1,istate),size(potential_x_alpha_ao_PBE,1))
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,grad_aos_dvx_alpha_PBE_w(1,1,m,istate),size(grad_aos_dvx_alpha_PBE_w,1),aos_in_r_array,size(aos_in_r_array,1),1.d0,potential_x_alpha_ao_PBE(1,1,istate),size(potential_x_alpha_ao_PBE,1))
|
||||
! exchange beta
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,aos_dvx_beta_PBE_w(1,1,m,istate),size(aos_dvx_beta_PBE_w,1),aos_grad_in_r_array(1,1,m),size(aos_grad_in_r_array,1),1.d0,potential_x_beta_ao_PBE(1,1,istate),size(potential_x_beta_ao_PBE,1))
|
||||
call dgemm('N','T',ao_num,ao_num,n_points_final_grid,1.d0,grad_aos_dvx_beta_PBE_w(1,1,m,istate),size(grad_aos_dvx_beta_PBE_w,1),aos_in_r_array,size(aos_in_r_array,1),1.d0,potential_x_beta_ao_PBE(1,1,istate),size(potential_x_beta_ao_PBE,1))
|
||||
enddo
|
||||
enddo
|
||||
|
||||
call wall_time(wall_2)
|
||||
|
||||
END_PROVIDER
|
@ -14,6 +14,12 @@
|
||||
else if(exchange_functional.EQ."short_range_PBE")then
|
||||
potential_x_alpha_ao = potential_sr_x_alpha_ao_PBE
|
||||
potential_x_beta_ao = potential_sr_x_beta_ao_PBE
|
||||
else if(trim(exchange_functional)=="LDA")then
|
||||
potential_x_alpha_ao = potential_x_alpha_ao_LDA
|
||||
potential_x_beta_ao = potential_x_beta_ao_LDA
|
||||
else if(exchange_functional.EQ."PBE")then
|
||||
potential_x_alpha_ao = potential_x_alpha_ao_PBE
|
||||
potential_x_beta_ao = potential_x_beta_ao_PBE
|
||||
else if(exchange_functional.EQ."None")then
|
||||
potential_x_alpha_ao = 0.d0
|
||||
potential_x_beta_ao = 0.d0
|
||||
@ -26,9 +32,15 @@
|
||||
if(trim(correlation_functional)=="short_range_LDA")then
|
||||
potential_c_alpha_ao = potential_sr_c_alpha_ao_LDA
|
||||
potential_c_beta_ao = potential_sr_c_beta_ao_LDA
|
||||
else if(trim(correlation_functional)=="LDA")then
|
||||
potential_c_alpha_ao = potential_c_alpha_ao_LDA
|
||||
potential_c_beta_ao = potential_c_beta_ao_LDA
|
||||
else if(correlation_functional.EQ."short_range_PBE")then
|
||||
potential_c_alpha_ao = potential_sr_c_alpha_ao_PBE
|
||||
potential_c_beta_ao = potential_sr_c_beta_ao_PBE
|
||||
else if(correlation_functional.EQ."PBE")then
|
||||
potential_c_alpha_ao = potential_c_alpha_ao_PBE
|
||||
potential_c_beta_ao = potential_c_beta_ao_PBE
|
||||
else if(correlation_functional.EQ."None")then
|
||||
potential_c_alpha_ao = 0.d0
|
||||
potential_c_beta_ao = 0.d0
|
||||
|
@ -3,6 +3,9 @@ subroutine GGA_sr_type_functionals(r,rho_a,rho_b,grad_rho_a_2,grad_rho_b_2,grad_
|
||||
ex,vx_rho_a,vx_rho_b,vx_grad_rho_a_2,vx_grad_rho_b_2,vx_grad_rho_a_b, &
|
||||
ec,vc_rho_a,vc_rho_b,vc_grad_rho_a_2,vc_grad_rho_b_2,vc_grad_rho_a_b )
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! routine that helps in building the x/c potentials on the AO basis for a GGA functional with a short-range interaction
|
||||
END_DOC
|
||||
double precision, intent(in) :: r(3),rho_a(N_states),rho_b(N_states),grad_rho_a_2(N_states),grad_rho_b_2(N_states),grad_rho_a_b(N_states)
|
||||
double precision, intent(out) :: ex(N_states),vx_rho_a(N_states),vx_rho_b(N_states),vx_grad_rho_a_2(N_states),vx_grad_rho_b_2(N_states),vx_grad_rho_a_b(N_states)
|
||||
double precision, intent(out) :: ec(N_states),vc_rho_a(N_states),vc_rho_b(N_states),vc_grad_rho_a_2(N_states),vc_grad_rho_b_2(N_states),vc_grad_rho_a_b(N_states)
|
||||
@ -54,13 +57,16 @@ subroutine GGA_type_functionals(r,rho_a,rho_b,grad_rho_a_2,grad_rho_b_2,grad_rho
|
||||
ex,vx_rho_a,vx_rho_b,vx_grad_rho_a_2,vx_grad_rho_b_2,vx_grad_rho_a_b, &
|
||||
ec,vc_rho_a,vc_rho_b,vc_grad_rho_a_2,vc_grad_rho_b_2,vc_grad_rho_a_b )
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! routine that helps in building the x/c potentials on the AO basis for a GGA functional
|
||||
END_DOC
|
||||
double precision, intent(in) :: r(3),rho_a(N_states),rho_b(N_states),grad_rho_a_2(N_states),grad_rho_b_2(N_states),grad_rho_a_b(N_states)
|
||||
double precision, intent(out) :: ex(N_states),vx_rho_a(N_states),vx_rho_b(N_states),vx_grad_rho_a_2(N_states),vx_grad_rho_b_2(N_states),vx_grad_rho_a_b(N_states)
|
||||
double precision, intent(out) :: ec(N_states),vc_rho_a(N_states),vc_rho_b(N_states),vc_grad_rho_a_2(N_states),vc_grad_rho_b_2(N_states),vc_grad_rho_a_b(N_states)
|
||||
integer :: istate
|
||||
double precision :: r2(3),dr2(3), local_potential,r12,dx2,mu
|
||||
double precision :: r2(3),dr2(3), local_potential,r12,dx2
|
||||
double precision :: mu_local
|
||||
mu_local = 1.d+9
|
||||
mu_local = 1.d-9
|
||||
do istate = 1, N_states
|
||||
if(exchange_functional.EQ."short_range_PBE")then
|
||||
call ex_pbe_sr(mu_local,rho_a(istate),rho_b(istate),grad_rho_a_2(istate),grad_rho_b_2(istate),grad_rho_a_b(istate),ex(istate),vx_rho_a(istate),vx_rho_b(istate),vx_grad_rho_a_2(istate),vx_grad_rho_b_2(istate),vx_grad_rho_a_b(istate))
|
||||
|
@ -6,13 +6,20 @@ Hartree-Fock
|
||||
The Hartree-Fock module performs *Restricted* Hartree-Fock calculations (the
|
||||
spatial part of the |MOs| is common for alpha and beta spinorbitals).
|
||||
|
||||
The Hartree-Fock program does the following:
|
||||
The Hartree-Fock in an SCF and therefore is based on the ``scf_utils`` structure.
|
||||
It performs the following actions:
|
||||
|
||||
#. Compute/Read all the one- and two-electron integrals, and store them in memory
|
||||
#. Check in the |EZFIO| database if there is a set of |MOs|. If there is, it
|
||||
will read them as initial guess. Otherwise, it will create a guess.
|
||||
#. Perform the |SCF| iterations
|
||||
|
||||
The definition of the Fock matrix is in :file:`hartree_fock fock_matrix_hf.irp.f`
|
||||
For the keywords related to the |SCF| procedure, see the ``scf_utils`` directory where you will find all options.
|
||||
The main are:
|
||||
# :option:`scf_utils thresh_scf`
|
||||
# :option:`scf_utils level_shift`
|
||||
|
||||
At each iteration, the |MOs| are saved in the |EZFIO| database. Hence, if the calculation
|
||||
crashes for any unexpected reason, the calculation can be restarted by running again
|
||||
the |SCF| with the same |EZFIO| database.
|
||||
|
@ -1,6 +1,13 @@
|
||||
BEGIN_PROVIDER [double precision, extra_energy_contrib_from_density]
|
||||
BEGIN_PROVIDER [double precision, extra_e_contrib_density]
|
||||
implicit none
|
||||
extra_energy_contrib_from_density = 0.D0
|
||||
BEGIN_DOC
|
||||
! Extra contribution to the SCF energy coming from the density.
|
||||
!
|
||||
! For a Hartree-Fock calculation: extra_e_contrib_density = 0
|
||||
!
|
||||
! For a Kohn-Sham or Range-separated Kohn-Sham: the exchange/correlation - trace of the V_xc potential
|
||||
END_DOC
|
||||
extra_e_contrib_density = 0.D0
|
||||
|
||||
END_PROVIDER
|
||||
|
||||
@ -8,6 +15,9 @@ END_PROVIDER
|
||||
&BEGIN_PROVIDER [ double precision, HF_two_electron_energy]
|
||||
&BEGIN_PROVIDER [ double precision, HF_one_electron_energy]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! Hartree-Fock energy containing the nuclear repulsion, and its one- and two-body components.
|
||||
END_DOC
|
||||
integer :: i,j
|
||||
HF_energy = nuclear_repulsion
|
||||
do j=1,ao_num
|
||||
|
@ -1,18 +1,25 @@
|
||||
============
|
||||
Hartree-Fock
|
||||
Kohn-Sham
|
||||
============
|
||||
|
||||
|
||||
The Hartree-Fock module performs *Restricted* Hartree-Fock calculations (the
|
||||
The Kohn-Sham module performs *Restricted* Kohn-Sham calculations (the
|
||||
spatial part of the |MOs| is common for alpha and beta spinorbitals).
|
||||
|
||||
The Hartree-Fock program does the following:
|
||||
The Kohn-Sham in an SCF and therefore is based on the ``scf_utils`` structure.
|
||||
It performs the following actions:
|
||||
|
||||
#. Compute/Read all the one- and two-electron integrals, and store them in memory
|
||||
#. Check in the |EZFIO| database if there is a set of |MOs|. If there is, it
|
||||
will read them as initial guess. Otherwise, it will create a guess.
|
||||
#. Perform the |SCF| iterations
|
||||
|
||||
The definition of the Fock matrix is in :file:`kohn_sham fock_matrix_ks.irp.f`
|
||||
For the keywords related to the |SCF| procedure, see the ``scf_utils`` directory where you will find all options.
|
||||
The main are:
|
||||
# :option:`scf_utils thresh_scf`
|
||||
# :option:`scf_utils level_shift`
|
||||
|
||||
At each iteration, the |MOs| are saved in the |EZFIO| database. Hence, if the calculation
|
||||
crashes for any unexpected reason, the calculation can be restarted by running again
|
||||
the |SCF| with the same |EZFIO| database.
|
||||
|
@ -199,46 +199,3 @@ END_PROVIDER
|
||||
|
||||
END_PROVIDER
|
||||
|
||||
|
||||
|
||||
|
||||
BEGIN_PROVIDER [ double precision, KS_energy]
|
||||
&BEGIN_PROVIDER [ double precision, two_electron_energy]
|
||||
&BEGIN_PROVIDER [ double precision, one_electron_energy]
|
||||
&BEGIN_PROVIDER [ double precision, Fock_matrix_energy]
|
||||
&BEGIN_PROVIDER [ double precision, trace_potential_xc ]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! Hartree-Fock energy
|
||||
END_DOC
|
||||
|
||||
integer :: i,j
|
||||
double precision :: accu_mono,accu_fock
|
||||
KS_energy = nuclear_repulsion
|
||||
one_electron_energy = 0.d0
|
||||
two_electron_energy = 0.d0
|
||||
Fock_matrix_energy = 0.d0
|
||||
trace_potential_xc = 0.d0
|
||||
do j=1,ao_num
|
||||
do i=1,ao_num
|
||||
Fock_matrix_energy += Fock_matrix_ao_alpha(i,j) * SCF_density_matrix_ao_alpha(i,j) + &
|
||||
Fock_matrix_ao_beta(i,j) * SCF_density_matrix_ao_beta(i,j)
|
||||
two_electron_energy += 0.5d0 * ( ao_bi_elec_integral_alpha(i,j) * SCF_density_matrix_ao_alpha(i,j) &
|
||||
+ao_bi_elec_integral_beta(i,j) * SCF_density_matrix_ao_beta(i,j) )
|
||||
one_electron_energy += ao_mono_elec_integral(i,j) * (SCF_density_matrix_ao_alpha(i,j) + SCF_density_matrix_ao_beta (i,j) )
|
||||
! possible bug fix for open-shell
|
||||
! trace_potential_xc += (ao_potential_alpha_xc(i,j) + ao_potential_beta_xc(i,j) ) * (SCF_density_matrix_ao_alpha(i,j) + SCF_density_matrix_ao_beta (i,j) )
|
||||
trace_potential_xc += ao_potential_alpha_xc(i,j) * SCF_density_matrix_ao_alpha(i,j) + ao_potential_beta_xc(i,j) * SCF_density_matrix_ao_beta (i,j)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
KS_energy += e_exchange_dft + e_correlation_dft + one_electron_energy + two_electron_energy
|
||||
END_PROVIDER
|
||||
|
||||
BEGIN_PROVIDER [double precision, extra_energy_contrib_from_density]
|
||||
implicit none
|
||||
! possible bug fix for open-shell:
|
||||
! extra_energy_contrib_from_density = e_exchange_dft + e_correlation_dft - 0.25d0 * trace_potential_xc
|
||||
extra_energy_contrib_from_density = e_exchange_dft + e_correlation_dft - 0.5d0 * trace_potential_xc
|
||||
END_PROVIDER
|
||||
|
||||
|
43
src/kohn_sham/ks_enery.irp.f
Normal file
43
src/kohn_sham/ks_enery.irp.f
Normal file
@ -0,0 +1,43 @@
|
||||
BEGIN_PROVIDER [ double precision, KS_energy]
|
||||
&BEGIN_PROVIDER [ double precision, two_electron_energy]
|
||||
&BEGIN_PROVIDER [ double precision, one_electron_energy]
|
||||
&BEGIN_PROVIDER [ double precision, Fock_matrix_energy]
|
||||
&BEGIN_PROVIDER [ double precision, trace_potential_xc ]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! Kohn-Sham energy containing the nuclear repulsion energy, and the various components of this quantity.
|
||||
END_DOC
|
||||
|
||||
integer :: i,j
|
||||
double precision :: accu_mono,accu_fock
|
||||
KS_energy = nuclear_repulsion
|
||||
one_electron_energy = 0.d0
|
||||
two_electron_energy = 0.d0
|
||||
Fock_matrix_energy = 0.d0
|
||||
trace_potential_xc = 0.d0
|
||||
do j=1,ao_num
|
||||
do i=1,ao_num
|
||||
Fock_matrix_energy += Fock_matrix_ao_alpha(i,j) * SCF_density_matrix_ao_alpha(i,j) + &
|
||||
Fock_matrix_ao_beta(i,j) * SCF_density_matrix_ao_beta(i,j)
|
||||
two_electron_energy += 0.5d0 * ( ao_bi_elec_integral_alpha(i,j) * SCF_density_matrix_ao_alpha(i,j) &
|
||||
+ao_bi_elec_integral_beta(i,j) * SCF_density_matrix_ao_beta(i,j) )
|
||||
one_electron_energy += ao_mono_elec_integral(i,j) * (SCF_density_matrix_ao_alpha(i,j) + SCF_density_matrix_ao_beta (i,j) )
|
||||
trace_potential_xc += ao_potential_alpha_xc(i,j) * SCF_density_matrix_ao_alpha(i,j) + ao_potential_beta_xc(i,j) * SCF_density_matrix_ao_beta (i,j)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
KS_energy += e_exchange_dft + e_correlation_dft + one_electron_energy + two_electron_energy
|
||||
END_PROVIDER
|
||||
|
||||
BEGIN_PROVIDER [double precision, extra_e_contrib_density]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! Extra contribution to the SCF energy coming from the density.
|
||||
!
|
||||
! For a Hartree-Fock calculation: extra_e_contrib_density = 0
|
||||
!
|
||||
! For a Kohn-Sham or Range-separated Kohn-Sham: the exchange/correlation - 1/2 trace of the V_xc potential
|
||||
END_DOC
|
||||
extra_e_contrib_density = e_exchange_dft + e_correlation_dft - 0.5d0 * trace_potential_xc
|
||||
END_PROVIDER
|
||||
|
@ -1,18 +1,27 @@
|
||||
============
|
||||
Hartree-Fock
|
||||
============
|
||||
=========================
|
||||
Range-separated Kohn-Sham
|
||||
=========================
|
||||
|
||||
|
||||
The Hartree-Fock module performs *Restricted* Hartree-Fock calculations (the
|
||||
spatial part of the |MOs| is common for alpha and beta spinorbitals).
|
||||
The Range-separated Kohn-Sham module performs *Restricted* Kohn-Sham calculations (the
|
||||
spatial part of the |MOs| is common for alpha and beta spinorbitals) where the coulomb interaction is partially treated using exact exchange.
|
||||
The splitting of the interaction between long- and short-range is determined by the range-separation parameter :option:`ao_two_e_erf_integrals mu_erf`. The long-range part of the interaction is explicitly treated with exact exchange, and the short-range part of the interaction is treated with appropriate DFT functionals.
|
||||
|
||||
The Hartree-Fock program does the following:
|
||||
The Range-separated Kohn-Sham in an SCF and therefore is based on the ``scf_utils`` structure.
|
||||
It performs the following actions:
|
||||
|
||||
#. Compute/Read all the one- and two-electron integrals, and store them in memory
|
||||
#. Check in the |EZFIO| database if there is a set of |MOs|. If there is, it
|
||||
will read them as initial guess. Otherwise, it will create a guess.
|
||||
#. Perform the |SCF| iterations
|
||||
|
||||
The definition of the Fock matrix is in :file:`kohn_sham_rs fock_matrix_rs_ks.irp.f`
|
||||
For the keywords related to the |SCF| procedure, see the ``scf_utils`` directory where you will find all options.
|
||||
The main are:
|
||||
# :option:`scf_utils thresh_scf`
|
||||
# :option:`scf_utils level_shift`
|
||||
|
||||
|
||||
At each iteration, the |MOs| are saved in the |EZFIO| database. Hence, if the calculation
|
||||
crashes for any unexpected reason, the calculation can be restarted by running again
|
||||
the |SCF| with the same |EZFIO| database.
|
||||
@ -24,8 +33,6 @@ To start a calculation from scratch, the simplest way is to remove the
|
||||
``mo_basis`` directory from the |EZFIO| database, and run the |SCF| again.
|
||||
|
||||
|
||||
|
||||
|
||||
.. _DIIS: https://en.wikipedia.org/w/index.php?title=DIIS
|
||||
.. _level-shifting: https://doi.org/10.1002/qua.560070407
|
||||
|
||||
|
@ -245,50 +245,3 @@ END_PROVIDER
|
||||
|
||||
END_PROVIDER
|
||||
|
||||
|
||||
|
||||
BEGIN_PROVIDER [ double precision, RS_KS_energy ]
|
||||
!BEGIN_PROVIDER [ double precision, SCF_energy ]
|
||||
&BEGIN_PROVIDER [ double precision, two_electron_energy]
|
||||
&BEGIN_PROVIDER [ double precision, one_electron_energy]
|
||||
&BEGIN_PROVIDER [ double precision, Fock_matrix_energy]
|
||||
&BEGIN_PROVIDER [ double precision, trace_potential_xc ]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! Range-separated Kohn-Sham energy
|
||||
END_DOC
|
||||
RS_KS_energy = nuclear_repulsion
|
||||
|
||||
integer :: i,j
|
||||
double precision :: accu_mono,accu_fock
|
||||
one_electron_energy = 0.d0
|
||||
two_electron_energy = 0.d0
|
||||
Fock_matrix_energy = 0.d0
|
||||
trace_potential_xc = 0.d0
|
||||
do j=1,ao_num
|
||||
do i=1,ao_num
|
||||
Fock_matrix_energy += Fock_matrix_ao_alpha(i,j) * SCF_density_matrix_ao_alpha(i,j) + &
|
||||
Fock_matrix_ao_beta(i,j) * SCF_density_matrix_ao_beta(i,j)
|
||||
two_electron_energy += 0.5d0 * ( ao_bi_elec_integral_alpha(i,j) * SCF_density_matrix_ao_alpha(i,j) &
|
||||
+ao_bi_elec_integral_beta(i,j) * SCF_density_matrix_ao_beta(i,j) )
|
||||
one_electron_energy += ao_mono_elec_integral(i,j) * (SCF_density_matrix_ao_alpha(i,j) + SCF_density_matrix_ao_beta (i,j) )
|
||||
! possible bug fix for open-shell
|
||||
! trace_potential_xc += (ao_potential_alpha_xc(i,j) + ao_potential_beta_xc(i,j) ) * (SCF_density_matrix_ao_alpha(i,j) + SCF_density_matrix_ao_beta (i,j) )
|
||||
trace_potential_xc += ao_potential_alpha_xc(i,j) * SCF_density_matrix_ao_alpha(i,j) + ao_potential_beta_xc(i,j) * SCF_density_matrix_ao_beta (i,j)
|
||||
enddo
|
||||
enddo
|
||||
RS_KS_energy += e_exchange_dft + e_correlation_dft + one_electron_energy + two_electron_energy
|
||||
!SCF_energy = RS_KS_energy
|
||||
END_PROVIDER
|
||||
|
||||
BEGIN_PROVIDER [double precision, extra_energy_contrib_from_density]
|
||||
implicit none
|
||||
! possible bug fix for open-shell:
|
||||
! extra_energy_contrib_from_density = e_exchange_dft + e_correlation_dft - 0.25d0 * trace_potential_xc
|
||||
extra_energy_contrib_from_density = e_exchange_dft + e_correlation_dft - 0.5d0 * trace_potential_xc
|
||||
END_PROVIDER
|
||||
|
||||
!BEGIN_PROVIDER [ double precision, SCF_energy ]
|
||||
! implicit none
|
||||
! SCF_energy = RS_KS_energy
|
||||
!END_PROVIDER
|
||||
|
42
src/kohn_sham_rs/rs_ks_energy.irp.f
Normal file
42
src/kohn_sham_rs/rs_ks_energy.irp.f
Normal file
@ -0,0 +1,42 @@
|
||||
BEGIN_PROVIDER [ double precision, RS_KS_energy ]
|
||||
&BEGIN_PROVIDER [ double precision, two_electron_energy]
|
||||
&BEGIN_PROVIDER [ double precision, one_electron_energy]
|
||||
&BEGIN_PROVIDER [ double precision, Fock_matrix_energy]
|
||||
&BEGIN_PROVIDER [ double precision, trace_potential_xc ]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! Range-separated Kohn-Sham energy containing the nuclear repulsion energy, and the various components of this quantity.
|
||||
END_DOC
|
||||
RS_KS_energy = nuclear_repulsion
|
||||
|
||||
integer :: i,j
|
||||
double precision :: accu_mono,accu_fock
|
||||
one_electron_energy = 0.d0
|
||||
two_electron_energy = 0.d0
|
||||
Fock_matrix_energy = 0.d0
|
||||
trace_potential_xc = 0.d0
|
||||
do j=1,ao_num
|
||||
do i=1,ao_num
|
||||
Fock_matrix_energy += Fock_matrix_ao_alpha(i,j) * SCF_density_matrix_ao_alpha(i,j) + &
|
||||
Fock_matrix_ao_beta(i,j) * SCF_density_matrix_ao_beta(i,j)
|
||||
two_electron_energy += 0.5d0 * ( ao_bi_elec_integral_alpha(i,j) * SCF_density_matrix_ao_alpha(i,j) &
|
||||
+ao_bi_elec_integral_beta(i,j) * SCF_density_matrix_ao_beta(i,j) )
|
||||
one_electron_energy += ao_mono_elec_integral(i,j) * (SCF_density_matrix_ao_alpha(i,j) + SCF_density_matrix_ao_beta (i,j) )
|
||||
trace_potential_xc += ao_potential_alpha_xc(i,j) * SCF_density_matrix_ao_alpha(i,j) + ao_potential_beta_xc(i,j) * SCF_density_matrix_ao_beta (i,j)
|
||||
enddo
|
||||
enddo
|
||||
RS_KS_energy += e_exchange_dft + e_correlation_dft + one_electron_energy + two_electron_energy
|
||||
END_PROVIDER
|
||||
|
||||
BEGIN_PROVIDER [double precision, extra_e_contrib_density]
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! Extra contribution to the SCF energy coming from the density.
|
||||
!
|
||||
! For a Hartree-Fock calculation: extra_e_contrib_density = 0
|
||||
!
|
||||
! For a Kohn-Sham or Range-separated Kohn-Sham: the exchange/correlation - 1/2 trace of the V_xc potential
|
||||
END_DOC
|
||||
extra_e_contrib_density = e_exchange_dft + e_correlation_dft - 0.5d0 * trace_potential_xc
|
||||
END_PROVIDER
|
||||
|
@ -3,4 +3,35 @@ scf_utils
|
||||
=========
|
||||
|
||||
|
||||
TODO
|
||||
|
||||
The scf_utils module performs *Restricted* SCF calculations (the
|
||||
spatial part of the |MOs| is common for alpha and beta spinorbitals) based on a single-determinant wave function.
|
||||
|
||||
This module does not produce any executable *and must not do*, but instead it contains everything one needs to perform an orbital optimization based on an Fock matrix.
|
||||
The ``scf_utils`` module is included in the :file:`NEED` of the various single determinant SCF procedures, such as ``hartree_fock`` or ``kohn_sham``, where a specific definition of the Fock matrix is given (see :file:`hartree_fock fock_matrix_hf.irp.f` for an example).
|
||||
|
||||
All SCF programs perform the following actions:
|
||||
|
||||
#. Compute/Read all the one- and two-electron integrals, and store them in memory
|
||||
#. Check in the |EZFIO| database if there is a set of |MOs|. If there is, it
|
||||
will read them as initial guess. Otherwise, it will create a guess.
|
||||
#. Perform the |SCF| iterations based on the definition of the Fock matrix
|
||||
|
||||
|
||||
The main keywords/options are:
|
||||
# :option:`scf_utils thresh_scf`
|
||||
# :option:`scf_utils level_shift`
|
||||
|
||||
At each iteration, the |MOs| are saved in the |EZFIO| database. Hence, if the calculation
|
||||
crashes for any unexpected reason, the calculation can be restarted by running again
|
||||
the |SCF| with the same |EZFIO| database.
|
||||
|
||||
The `DIIS`_ algorithm is implemented, as well as the `level-shifting`_ method.
|
||||
If the |SCF| does not converge, try again with a higher value of :option:`level_shift`.
|
||||
|
||||
To start a calculation from scratch, the simplest way is to remove the
|
||||
``mo_basis`` directory from the |EZFIO| database, and run the |SCF| again.
|
||||
|
||||
.. _DIIS: https://en.wikipedia.org/w/index.php?title=DIIS
|
||||
.. _level-shifting: https://doi.org/10.1002/qua.560070407
|
||||
|
||||
|
@ -138,7 +138,7 @@ BEGIN_PROVIDER [ double precision, SCF_energy ]
|
||||
(ao_mono_elec_integral(i,j) + Fock_matrix_ao_beta (i,j) ) * SCF_density_matrix_ao_beta (i,j) )
|
||||
enddo
|
||||
enddo
|
||||
SCF_energy += extra_energy_contrib_from_density
|
||||
SCF_energy += extra_e_contrib_density
|
||||
|
||||
END_PROVIDER
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
fci
|
||||
mo_two_e_erf_integrals
|
||||
aux_quantities
|
||||
|
117
src/tools/print_wf.irp.f
Normal file
117
src/tools/print_wf.irp.f
Normal file
@ -0,0 +1,117 @@
|
||||
program print_wf
|
||||
implicit none
|
||||
BEGIN_DOC
|
||||
! print the wave function stored in the EZFIO folder in the intermediate normalization
|
||||
!
|
||||
! it also prints a lot of information regarding the excitation operators from the reference determinant
|
||||
!
|
||||
! and a first-order perturbative analysis of the wave function.
|
||||
!
|
||||
! If the wave function strongly deviates from the first-order analysis, something funny is going on :)
|
||||
END_DOC
|
||||
|
||||
|
||||
! this has to be done in order to be sure that N_det, psi_det and psi_coef are the wave function stored in the EZFIO folder
|
||||
read_wf = .True.
|
||||
touch read_wf
|
||||
call routine
|
||||
end
|
||||
|
||||
subroutine routine
|
||||
implicit none
|
||||
integer :: i
|
||||
integer :: degree
|
||||
double precision :: hij,hii,coef_1,h00
|
||||
integer :: exc(0:2,2,2)
|
||||
double precision :: phase
|
||||
integer :: h1,p1,h2,p2,s1,s2
|
||||
double precision :: get_mo_bielec_integral
|
||||
double precision :: norm_mono_a,norm_mono_b
|
||||
double precision :: norm_mono_a_2,norm_mono_b_2
|
||||
double precision :: norm_mono_a_pert_2,norm_mono_b_pert_2
|
||||
double precision :: norm_mono_a_pert,norm_mono_b_pert
|
||||
double precision :: delta_e,coef_2_2
|
||||
norm_mono_a = 0.d0
|
||||
norm_mono_b = 0.d0
|
||||
norm_mono_a_2 = 0.d0
|
||||
norm_mono_b_2 = 0.d0
|
||||
norm_mono_a_pert = 0.d0
|
||||
norm_mono_b_pert = 0.d0
|
||||
norm_mono_a_pert_2 = 0.d0
|
||||
norm_mono_b_pert_2 = 0.d0
|
||||
do i = 1, min(10000,N_det)
|
||||
print*,''
|
||||
print*,'i = ',i
|
||||
call debug_det(psi_det(1,1,i),N_int)
|
||||
call get_excitation_degree(psi_det(1,1,i),psi_det(1,1,1),degree,N_int)
|
||||
print*,'degree = ',degree
|
||||
if(degree == 0)then
|
||||
print*,'Reference determinant '
|
||||
call i_H_j(psi_det(1,1,i),psi_det(1,1,i),N_int,h00)
|
||||
else
|
||||
call i_H_j(psi_det(1,1,i),psi_det(1,1,i),N_int,hii)
|
||||
call i_H_j(psi_det(1,1,1),psi_det(1,1,i),N_int,hij)
|
||||
delta_e = hii - h00
|
||||
coef_1 = hij/(h00-hii)
|
||||
if(hij.ne.0.d0)then
|
||||
if (delta_e > 0.d0) then
|
||||
coef_2_2 = 0.5d0 * (delta_e - dsqrt(delta_e * delta_e + 4.d0 * hij * hij ))/ hij
|
||||
else
|
||||
coef_2_2 = 0.5d0 * (delta_e + dsqrt(delta_e * delta_e + 4.d0 * hij * hij )) /hij
|
||||
endif
|
||||
endif
|
||||
call get_excitation(psi_det(1,1,1),psi_det(1,1,i),exc,degree,phase,N_int)
|
||||
call decode_exc(exc,degree,h1,p1,h2,p2,s1,s2)
|
||||
print*,'phase = ',phase
|
||||
if(degree == 1)then
|
||||
print*,'s1',s1
|
||||
print*,'h1,p1 = ',h1,p1
|
||||
if(s1 == 1)then
|
||||
norm_mono_a += dabs(psi_coef(i,1)/psi_coef(1,1))
|
||||
norm_mono_a_2 += dabs(psi_coef(i,1)/psi_coef(1,1))**2
|
||||
norm_mono_a_pert += dabs(coef_1)
|
||||
norm_mono_a_pert_2 += dabs(coef_1)**2
|
||||
else
|
||||
norm_mono_b += dabs(psi_coef(i,1)/psi_coef(1,1))
|
||||
norm_mono_b_2 += dabs(psi_coef(i,1)/psi_coef(1,1))**2
|
||||
norm_mono_b_pert += dabs(coef_1)
|
||||
norm_mono_b_pert_2 += dabs(coef_1)**2
|
||||
endif
|
||||
double precision :: hmono,hdouble
|
||||
call i_H_j_verbose(psi_det(1,1,1),psi_det(1,1,i),N_int,hij,hmono,hdouble,phase)
|
||||
print*,'hmono = ',hmono
|
||||
print*,'hdouble = ',hdouble
|
||||
print*,'hmono+hdouble = ',hmono+hdouble
|
||||
print*,'hij = ',hij
|
||||
else
|
||||
print*,'s1',s1
|
||||
print*,'h1,p1 = ',h1,p1
|
||||
print*,'s2',s2
|
||||
print*,'h2,p2 = ',h2,p2
|
||||
endif
|
||||
|
||||
print*,'<Ref| H |D_I> = ',hij
|
||||
print*,'Delta E = ',h00-hii
|
||||
print*,'coef pert (1) = ',coef_1
|
||||
print*,'coef 2x2 = ',coef_2_2
|
||||
print*,'Delta E_corr = ',psi_coef(i,1)/psi_coef(1,1) * hij
|
||||
endif
|
||||
print*,'amplitude = ',psi_coef(i,1)/psi_coef(1,1)
|
||||
|
||||
enddo
|
||||
|
||||
|
||||
print*,''
|
||||
print*,'L1 norm of mono alpha = ',norm_mono_a
|
||||
print*,'L1 norm of mono beta = ',norm_mono_b
|
||||
print*, '---'
|
||||
print*,'L2 norm of mono alpha = ',norm_mono_a_2
|
||||
print*,'L2 norm of mono beta = ',norm_mono_b_2
|
||||
print*, '-- perturbative mono'
|
||||
print*,''
|
||||
print*,'L1 norm of pert alpha = ',norm_mono_a_pert
|
||||
print*,'L1 norm of pert beta = ',norm_mono_b_pert
|
||||
print*,'L2 norm of pert alpha = ',norm_mono_a_pert_2
|
||||
print*,'L2 norm of pert beta = ',norm_mono_b_pert_2
|
||||
|
||||
end
|
Loading…
Reference in New Issue
Block a user