(git:3add494)
se_fock_matrix_exchange.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief Construction of the Exchange part of the Fock Matrix
10 !> \author Teodoro Laino [tlaino] (05.2009) - Split and module reorganization
11 !> \par History
12 !> Teodoro Laino (04.2008) [tlaino] - University of Zurich : d-orbitals
13 !> Teodoro Laino (09.2008) [tlaino] - University of Zurich : Speed-up
14 !> Teodoro Laino (09.2008) [tlaino] - University of Zurich : Periodic SE
15 ! **************************************************************************************************
17  USE atomic_kind_types, ONLY: atomic_kind_type,&
19  USE cell_types, ONLY: cell_type
20  USE cp_control_types, ONLY: dft_control_type,&
21  semi_empirical_control_type
22  USE dbcsr_api, ONLY: dbcsr_get_block_p,&
23  dbcsr_p_type
24  USE input_constants, ONLY: do_se_is_kdso,&
26  USE kinds, ONLY: dp
27  USE message_passing, ONLY: mp_para_env_type
29  USE particle_types, ONLY: particle_type
30  USE qs_environment_types, ONLY: get_qs_env,&
31  qs_environment_type
32  USE qs_force_types, ONLY: qs_force_type
33  USE qs_kind_types, ONLY: get_qs_kind,&
34  qs_kind_type
38  neighbor_list_iterator_p_type,&
40  neighbor_list_set_p_type
42  fock1_2el,&
43  fock2e
45  USE semi_empirical_store_int_types, ONLY: semi_empirical_si_type
47  se_int_control_type,&
48  se_taper_type,&
49  semi_empirical_p_type,&
50  semi_empirical_type,&
55  USE virial_types, ONLY: virial_type
56 #include "./base/base_uses.f90"
57 
58  IMPLICIT NONE
59  PRIVATE
60 
61  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'se_fock_matrix_exchange'
62  LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .false.
63 
65 
66 CONTAINS
67 
68 ! **************************************************************************************************
69 !> \brief Construction of the Exchange part of the Fock matrix
70 !> \param qs_env ...
71 !> \param ks_matrix ...
72 !> \param matrix_p ...
73 !> \param calculate_forces ...
74 !> \param store_int_env ...
75 !> \author JGH
76 ! **************************************************************************************************
77  SUBROUTINE build_fock_matrix_exchange(qs_env, ks_matrix, matrix_p, calculate_forces, &
78  store_int_env)
79 
80  TYPE(qs_environment_type), POINTER :: qs_env
81  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_matrix, matrix_p
82  LOGICAL, INTENT(in) :: calculate_forces
83  TYPE(semi_empirical_si_type), POINTER :: store_int_env
84 
85  CHARACTER(len=*), PARAMETER :: routinen = 'build_fock_matrix_exchange'
86 
87  INTEGER :: atom_a, atom_b, handle, iatom, icol, &
88  ikind, integral_screening, irow, &
89  jatom, jkind, natorb_a, nkind, nspins
90  INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind
91  INTEGER, DIMENSION(2) :: size_p_block_a
92  LOGICAL :: anag, check, defined, found, switch, &
93  use_virial
94  LOGICAL, ALLOCATABLE, DIMENSION(:) :: se_defined
95  REAL(kind=dp) :: delta, dr
96  REAL(kind=dp), DIMENSION(3) :: force_ab, rij
97  REAL(kind=dp), DIMENSION(45, 45) :: p_block_tot
98  REAL(kind=dp), DIMENSION(:, :), POINTER :: ks_block_a, ks_block_b, p_block_a, &
99  p_block_b
100  TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
101  TYPE(cell_type), POINTER :: cell
102  TYPE(dft_control_type), POINTER :: dft_control
103  TYPE(mp_para_env_type), POINTER :: para_env
104  TYPE(neighbor_list_iterator_p_type), &
105  DIMENSION(:), POINTER :: nl_iterator
106  TYPE(neighbor_list_set_p_type), DIMENSION(:), &
107  POINTER :: sab_orb
108  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
109  TYPE(qs_force_type), DIMENSION(:), POINTER :: force
110  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
111  TYPE(se_int_control_type) :: se_int_control
112  TYPE(se_taper_type), POINTER :: se_taper
113  TYPE(semi_empirical_control_type), POINTER :: se_control
114  TYPE(semi_empirical_p_type), DIMENSION(:), POINTER :: se_kind_list
115  TYPE(semi_empirical_type), POINTER :: se_kind_a, se_kind_b
116  TYPE(virial_type), POINTER :: virial
117 
118  CALL timeset(routinen, handle)
119 
120  NULLIFY (dft_control, cell, force, particle_set, se_control, se_taper)
121  CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, cell=cell, se_taper=se_taper, &
122  para_env=para_env, virial=virial)
123 
124  CALL initialize_se_taper(se_taper, exchange=.true.)
125  se_control => dft_control%qs_control%se_control
126  anag = se_control%analytical_gradients
127  use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
128  nspins = dft_control%nspins
129 
130  cpassert(ASSOCIATED(matrix_p))
131  cpassert(SIZE(ks_matrix) > 0)
132 
133  ! Identify proper integral screening (according user requests)
134  integral_screening = se_control%integral_screening
135  IF ((integral_screening == do_se_is_kdso_d) .AND. (.NOT. se_control%force_kdsod_EX)) THEN
136  integral_screening = do_se_is_kdso
137  END IF
138  CALL setup_se_int_control_type(se_int_control, shortrange=.false., &
139  do_ewald_r3=.false., do_ewald_gks=.false., integral_screening=integral_screening, &
140  max_multipole=do_multipole_none, pc_coulomb_int=.false.)
141 
142  CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb, &
143  atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
144 
145  nkind = SIZE(atomic_kind_set)
146  IF (calculate_forces) THEN
147  CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, force=force)
148  delta = se_control%delta
149  CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
150  END IF
151 
152  ALLOCATE (se_defined(nkind), se_kind_list(nkind))
153  DO ikind = 1, nkind
154  CALL get_qs_kind(qs_kind_set(ikind), se_parameter=se_kind_a)
155  se_kind_list(ikind)%se_param => se_kind_a
156  CALL get_se_param(se_kind_a, defined=defined, natorb=natorb_a)
157  se_defined(ikind) = (defined .AND. natorb_a >= 1)
158  END DO
159 
160  CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
161  DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
162  CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, iatom=iatom, jatom=jatom, r=rij)
163  IF (.NOT. se_defined(ikind)) cycle
164  IF (.NOT. se_defined(jkind)) cycle
165  se_kind_a => se_kind_list(ikind)%se_param
166  se_kind_b => se_kind_list(jkind)%se_param
167 
168  IF (iatom <= jatom) THEN
169  irow = iatom
170  icol = jatom
171  switch = .false.
172  ELSE
173  irow = jatom
174  icol = iatom
175  switch = .true.
176  END IF
177  ! Retrieve blocks for KS and P
178  CALL dbcsr_get_block_p(matrix=ks_matrix(1)%matrix, &
179  row=irow, col=icol, block=ks_block_a, found=found)
180  cpassert(ASSOCIATED(ks_block_a))
181  CALL dbcsr_get_block_p(matrix=matrix_p(1)%matrix, &
182  row=irow, col=icol, block=p_block_a, found=found)
183  cpassert(ASSOCIATED(p_block_a))
184  size_p_block_a(1) = SIZE(p_block_a, 1)
185  size_p_block_a(2) = SIZE(p_block_a, 2)
186  p_block_tot(1:size_p_block_a(1), 1:size_p_block_a(2)) = 2.0_dp*p_block_a
187 
188  ! Handle more configurations
189  IF (nspins == 2) THEN
190  CALL dbcsr_get_block_p(matrix=ks_matrix(2)%matrix, &
191  row=irow, col=icol, block=ks_block_b, found=found)
192  cpassert(ASSOCIATED(ks_block_b))
193  CALL dbcsr_get_block_p(matrix=matrix_p(2)%matrix, &
194  row=irow, col=icol, block=p_block_b, found=found)
195  cpassert(ASSOCIATED(p_block_b))
196  check = (size_p_block_a(1) == SIZE(p_block_b, 1)) .AND. (size_p_block_a(2) == SIZE(p_block_b, 2))
197  cpassert(check)
198  p_block_tot(1:SIZE(p_block_a, 1), 1:SIZE(p_block_a, 2)) = p_block_a + p_block_b
199  END IF
200 
201  dr = dot_product(rij, rij)
202  IF (iatom == jatom .AND. dr < rij_threshold) THEN
203  ! Once center - Two electron Terms
204  IF (nspins == 1) THEN
205  CALL fock1_2el(se_kind_a, p_block_tot, p_block_a, ks_block_a, factor=0.5_dp)
206  ELSE IF (nspins == 2) THEN
207  CALL fock1_2el(se_kind_a, p_block_tot, p_block_a, ks_block_a, factor=1.0_dp)
208  CALL fock1_2el(se_kind_a, p_block_tot, p_block_b, ks_block_b, factor=1.0_dp)
209  END IF
210  ELSE
211  ! Exchange Terms
212  IF (nspins == 1) THEN
213  CALL fock2e(se_kind_a, se_kind_b, rij, switch, size_p_block_a, p_block_a, ks_block_a, &
214  factor=0.5_dp, anag=anag, se_int_control=se_int_control, se_taper=se_taper, &
215  store_int_env=store_int_env)
216  ELSE IF (nspins == 2) THEN
217  CALL fock2e(se_kind_a, se_kind_b, rij, switch, size_p_block_a, p_block_a, ks_block_a, &
218  factor=1.0_dp, anag=anag, se_int_control=se_int_control, se_taper=se_taper, &
219  store_int_env=store_int_env)
220 
221  CALL fock2e(se_kind_a, se_kind_b, rij, switch, size_p_block_a, p_block_b, ks_block_b, &
222  factor=1.0_dp, anag=anag, se_int_control=se_int_control, se_taper=se_taper, &
223  store_int_env=store_int_env)
224  END IF
225  IF (calculate_forces) THEN
226  atom_a = atom_of_kind(iatom)
227  atom_b = atom_of_kind(jatom)
228  force_ab = 0.0_dp
229  IF (nspins == 1) THEN
230  CALL dfock2e(se_kind_a, se_kind_b, rij, switch, size_p_block_a, p_block_a, &
231  factor=0.5_dp, anag=anag, se_int_control=se_int_control, se_taper=se_taper, force=force_ab, &
232  delta=delta)
233  ELSE IF (nspins == 2) THEN
234  CALL dfock2e(se_kind_a, se_kind_b, rij, switch, size_p_block_a, p_block_a, &
235  factor=1.0_dp, anag=anag, se_int_control=se_int_control, se_taper=se_taper, force=force_ab, &
236  delta=delta)
237 
238  CALL dfock2e(se_kind_a, se_kind_b, rij, switch, size_p_block_a, p_block_b, &
239  factor=1.0_dp, anag=anag, se_int_control=se_int_control, se_taper=se_taper, force=force_ab, &
240  delta=delta)
241  END IF
242  IF (switch) THEN
243  force_ab(1) = -force_ab(1)
244  force_ab(2) = -force_ab(2)
245  force_ab(3) = -force_ab(3)
246  END IF
247  IF (use_virial) THEN
248  CALL virial_pair_force(virial%pv_virial, -1.0_dp, force_ab, rij)
249  END IF
250 
251  force(ikind)%rho_elec(1, atom_a) = force(ikind)%rho_elec(1, atom_a) - force_ab(1)
252  force(jkind)%rho_elec(1, atom_b) = force(jkind)%rho_elec(1, atom_b) + force_ab(1)
253 
254  force(ikind)%rho_elec(2, atom_a) = force(ikind)%rho_elec(2, atom_a) - force_ab(2)
255  force(jkind)%rho_elec(2, atom_b) = force(jkind)%rho_elec(2, atom_b) + force_ab(2)
256 
257  force(ikind)%rho_elec(3, atom_a) = force(ikind)%rho_elec(3, atom_a) - force_ab(3)
258  force(jkind)%rho_elec(3, atom_b) = force(jkind)%rho_elec(3, atom_b) + force_ab(3)
259  END IF
260  END IF
261  END DO
262  CALL neighbor_list_iterator_release(nl_iterator)
263 
264  DEALLOCATE (se_kind_list, se_defined)
265 
266  CALL finalize_se_taper(se_taper)
267 
268  CALL timestop(handle)
269 
270  END SUBROUTINE build_fock_matrix_exchange
271 
272 END MODULE se_fock_matrix_exchange
273 
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
Handles all functions related to the CELL.
Definition: cell_types.F:15
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_se_is_kdso_d
integer, parameter, public do_se_is_kdso
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
Interface to the message passing library MPI.
Multipole structure: for multipole (fixed and induced) in FF based MD.
integer, parameter, public do_multipole_none
Define the data structure for the particle information.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_RI_aux_kp, matrix_s, matrix_s_RI_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, WannierCentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, rhs)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
Definition: qs_kind_types.F:23
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_r3d_rs_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, U_of_dft_plus_u, J_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, J0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Define the neighbor list data types and the corresponding functionality.
subroutine, public neighbor_list_iterator_create(iterator_set, nl, search, nthread)
Neighbor list iterator functions.
subroutine, public neighbor_list_iterator_release(iterator_set)
...
integer function, public neighbor_list_iterate(iterator_set, mepos)
...
subroutine, public get_iterator_info(iterator_set, mepos, ikind, jkind, nkind, ilist, nlist, inode, nnode, iatom, jatom, r, cell)
...
Construction of the Exchange part of the Fock Matrix.
subroutine, public build_fock_matrix_exchange(qs_env, ks_matrix, matrix_p, calculate_forces, store_int_env)
Construction of the Exchange part of the Fock matrix.
Provides the low level routines to build both the exchange and the Coulomb Fock matrices....
subroutine, public dfock2e(sepi, sepj, rij, switch, isize, pi_mat, factor, anag, se_int_control, se_taper, force, delta)
Derivatives of 2-center Fock Matrix - General Driver.
subroutine, public fock1_2el(sep, p_tot, p_mat, f_mat, factor)
Construction of 1-center 2-electron Fock Matrix.
subroutine, public fock2e(sepi, sepj, rij, switch, isize, pi_mat, fi_mat, factor, anag, se_int_control, se_taper, store_int_env)
Construction of 2-center Fock Matrix - General Driver.
Arrays of parameters used in the semi-empirical calculations \References Everywhere in this module TC...
real(kind=dp), parameter, public rij_threshold
Type to store integrals for semi-empirical calculations.
Definition of the semi empirical parameter types.
subroutine, public setup_se_int_control_type(se_int_control, shortrange, do_ewald_r3, do_ewald_gks, integral_screening, max_multipole, pc_coulomb_int)
Setup the Semiempirical integral control type.
subroutine, public get_se_param(sep, name, typ, defined, z, zeff, natorb, eheat, beta, sto_exponents, uss, upp, udd, uff, alp, eisol, gss, gsp, gpp, gp2, acoul, nr, de, ass, asp, app, hsp, gsd, gpd, gdd, ppddg, dpddg, ngauss)
Get info from the semi-empirical type.
Working with the semi empirical parameter types.
subroutine, public finalize_se_taper(se_taper)
Finalizes the semi-empirical taper for a chunk calculation.
subroutine, public initialize_se_taper(se_taper, coulomb, exchange, lr_corr)
Initializes the semi-empirical taper for a chunk calculation.
pure subroutine, public virial_pair_force(pv_virial, f0, force, rab)
Computes the contribution to the stress tensor from two-body pair-wise forces.