24#include "./base/base_uses.f90"
32 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'gw_ri_rs_utils'
47 CHARACTER(LEN=*),
PARAMETER :: routinen =
'precompute_ri_rs_radii'
48 REAL(kind=
dp),
PARAMETER :: min_exponent_for_radius = 1.0e-3_dp
50 INTEGER :: handle, i, iatom, ikind, j, natom, nkind
51 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kind_of
53 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha_min_ao_kind, alpha_min_ri_kind
54 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: zet_ao, zet_ri
56 CALL timeset(routinen, handle)
58 cpassert(
ASSOCIATED(bs_env%ri_rs%atomic_kind_set))
59 nkind =
SIZE(bs_env%ri_rs%atomic_kind_set)
61 eps = bs_env%eps_filter
63 ALLOCATE (alpha_min_ao_kind(nkind), alpha_min_ri_kind(nkind))
64 alpha_min_ao_kind = huge(1.0_dp)
65 alpha_min_ri_kind = huge(1.0_dp)
68 zet_ao => bs_env%basis_set_AO(ikind)%gto_basis_set%zet
69 zet_ri => bs_env%basis_set_RI(ikind)%gto_basis_set%zet
70 DO i = 1,
SIZE(zet_ao, 1)
71 DO j = 1,
SIZE(zet_ao, 2)
72 IF (zet_ao(i, j) > min_exponent_for_radius)
THEN
73 alpha_min_ao_kind(ikind) = min(alpha_min_ao_kind(ikind), zet_ao(i, j))
77 DO i = 1,
SIZE(zet_ri, 1)
78 DO j = 1,
SIZE(zet_ri, 2)
79 IF (zet_ri(i, j) > min_exponent_for_radius)
THEN
80 alpha_min_ri_kind(ikind) = min(alpha_min_ri_kind(ikind), zet_ri(i, j))
88 ALLOCATE (bs_env%ri_rs%radius_ao_per_atom(natom))
89 ALLOCATE (bs_env%ri_rs%radius_ri_per_atom(natom))
91 ikind = kind_of(iatom)
92 bs_env%ri_rs%radius_ao_per_atom(iatom) = sqrt(-log(eps)/alpha_min_ao_kind(ikind))
93 bs_env%ri_rs%radius_ri_per_atom(iatom) = sqrt(-log(eps)/alpha_min_ri_kind(ikind))
96 IF (bs_env%unit_nr > 0)
THEN
97 WRITE (bs_env%unit_nr,
'(T2,A)')
'RI-RS basis radii (Å):'
98 WRITE (bs_env%unit_nr,
'(T4,A6,2X,A4,2A14)')
'Kind',
'Elem',
'r_AO (Å)',
'r_RI (Å)'
100 WRITE (bs_env%unit_nr,
'(T4,I6,2X,A4,2F14.4)') &
102 bs_env%ri_rs%atomic_kind_set(ikind)%element_symbol, &
103 sqrt(-log(eps)/alpha_min_ao_kind(ikind))*
angstrom, &
104 sqrt(-log(eps)/alpha_min_ri_kind(ikind))*
angstrom
106 WRITE (bs_env%unit_nr,
'(A)')
' '
109 DEALLOCATE (alpha_min_ao_kind, alpha_min_ri_kind, kind_of)
111 CALL timestop(handle)
123 REAL(kind=
dp),
ALLOCATABLE,
INTENT(INOUT) :: points(:, :)
124 INTEGER,
INTENT(IN) :: icenter_atom
126 LOGICAL,
INTENT(OUT),
OPTIONAL :: mask(:)
127 INTEGER,
INTENT(IN),
OPTIONAL :: atom_indices(:)
129 INTEGER :: iatom, iatom_index, ipoint, n_atoms, &
131 LOGICAL,
ALLOCATABLE :: keep(:)
132 REAL(kind=
dp) :: displacement(3), distance2, max_radius2, &
134 REAL(kind=
dp),
ALLOCATABLE :: filtered_points(:, :)
136 ALLOCATE (keep(
SIZE(points, 2)), source=.true.)
137 max_radius2 = maxval(sum(points**2, dim=1))
138 n_atoms =
SIZE(particle_set)
139 IF (
PRESENT(atom_indices)) n_atoms =
SIZE(atom_indices)
140 DO iatom_index = 1, n_atoms
141 IF (
PRESENT(atom_indices))
THEN
142 iatom = atom_indices(iatom_index)
143 cpassert(iatom >= 1 .AND. iatom <=
SIZE(particle_set))
147 IF (iatom == icenter_atom) cycle
148 displacement(:) = particle_set(iatom)%r - particle_set(icenter_atom)%r
149 distance2 = sum(displacement**2)
151 IF (distance2 > 4.0_dp*max_radius2) cycle
152 tolerance = 32.0_dp*epsilon(1.0_dp)*max(1.0_dp, distance2)
153 DO ipoint = 1,
SIZE(points, 2)
154 IF (.NOT. keep(ipoint)) cycle
156 IF (2.0_dp*dot_product(points(:, ipoint), displacement) > distance2 + tolerance)
THEN
157 keep(ipoint) = .false.
158 ELSE IF (iatom < icenter_atom)
THEN
159 IF (abs(2.0_dp*dot_product(points(:, ipoint), displacement) - distance2) <= tolerance)
THEN
160 keep(ipoint) = .false.
165 IF (
PRESENT(mask))
THEN
166 cpassert(
SIZE(mask) ==
SIZE(keep))
171 ALLOCATE (filtered_points(3, n_keep))
172 IF (n_keep > 0) filtered_points(:, :) = reshape(pack(points, spread(keep, 1, 3)), [3, n_keep])
173 CALL move_alloc(filtered_points, points)
187 INTEGER,
INTENT(IN) :: icenter_atom
188 REAL(kind=
dp),
INTENT(IN) :: radius
189 INTEGER,
ALLOCATABLE,
INTENT(OUT) :: atom_indices(:)
191 INTEGER :: iatom, ncluster
192 INTEGER,
ALLOCATABLE :: work(:)
194 ALLOCATE (work(
SIZE(particle_set)))
196 DO iatom = 1,
SIZE(particle_set)
197 IF (sum(
pbc(particle_set(iatom)%r - particle_set(icenter_atom)%r, cell)**2) <= radius**2)
THEN
198 ncluster = ncluster + 1
199 work(ncluster) = iatom
202 ALLOCATE (atom_indices(ncluster), source=work(:ncluster))
228 dphi, cutoff_squared)
229 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: phi
230 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: grid_points
231 INTEGER,
INTENT(IN) :: iatom
233 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
235 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(INOUT), &
237 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: cutoff_squared
239 CHARACTER(len=*),
PARAMETER :: routinen =
'evaluate_ao_on_points'
241 INTEGER :: handle, ikind
244 CALL timeset(routinen, handle)
245 cpassert(
SIZE(grid_points, 1) == 3)
246 cpassert(
SIZE(phi, 1) ==
SIZE(grid_points, 2))
247 IF (
PRESENT(dphi))
THEN
248 cpassert(
SIZE(dphi, 1) == 3)
249 cpassert(
SIZE(dphi, 2) ==
SIZE(phi, 1))
250 cpassert(
SIZE(dphi, 3) ==
SIZE(phi, 2))
253 ikind = particle_set(iatom)%atomic_kind%kind_number
254 CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis, basis_type=
'ORB')
255 IF (.NOT.
ASSOCIATED(basis))
THEN
256 CALL timestop(handle)
260 particle_set(iatom)%r, cell, dphi, cutoff_squared)
261 CALL timestop(handle)
275 dphi, cutoff_squared)
276 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: phi
277 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: grid_points
279 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: source_position
281 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(INOUT), &
283 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: cutoff_squared
285 INTEGER :: first_sgf, ialpha, ico, iend_co, ipgf, &
286 ipoint, irow, iset, isgf, ishell, &
287 istart_co, l, last_sgf, lx, ly, lz, &
289 REAL(kind=
dp) :: exponent, exponential, polynomial, &
290 polynomial_derivative(3), radius2, &
293 cpassert(
ASSOCIATED(basis))
294 cpassert(
SIZE(grid_points, 1) == 3)
295 cpassert(
SIZE(phi, 1) ==
SIZE(grid_points, 2))
296 IF (
PRESENT(dphi))
THEN
297 cpassert(
SIZE(dphi, 1) == 3)
298 cpassert(
SIZE(dphi, 2) ==
SIZE(phi, 1))
299 cpassert(
SIZE(dphi, 3) ==
SIZE(phi, 2))
307 DO ipoint = 1,
SIZE(grid_points, 2)
308 relative =
pbc(grid_points(:, ipoint) - source_position, cell)
309 radius2 = dot_product(relative, relative)
310 IF (
PRESENT(cutoff_squared))
THEN
311 IF (radius2 > cutoff_squared) cycle
314 DO iset = 1, basis%nset
315 n_cart_total =
ncoset(basis%lmax(iset))
316 DO ishell = 1, basis%nshell(iset)
317 l = basis%l(ishell, iset)
318 istart_co =
ncoset(l - 1) + 1
320 first_sgf = basis%first_sgf(ishell, iset)
321 last_sgf = basis%last_sgf(ishell, iset)
322 DO ipgf = 1, basis%npgf(iset)
323 exponent = basis%zet(ipgf, iset)
324 exponential = exp(-exponent*radius2)
325 DO isgf = first_sgf, last_sgf
326 DO ico = istart_co, iend_co
327 irow = (ipgf - 1)*n_cart_total + ico
328 weight = basis%sphi(irow, isgf)
332 polynomial = relative(1)**lx*relative(2)**ly*relative(3)**lz
333 phi(ipoint, isgf) = phi(ipoint, isgf) + weight*polynomial*exponential
335 IF (
PRESENT(dphi))
THEN
336 polynomial_derivative = 0.0_dp
337 IF (lx > 0) polynomial_derivative(1) = real(lx,
dp)*relative(1)**(lx - 1)* &
338 relative(2)**ly*relative(3)**lz
339 IF (ly > 0) polynomial_derivative(2) = real(ly,
dp)*relative(1)**lx* &
340 relative(2)**(ly - 1)*relative(3)**lz
341 IF (lz > 0) polynomial_derivative(3) = real(lz,
dp)*relative(1)**lx* &
342 relative(2)**ly*relative(3)**(lz - 1)
344 dphi(ialpha, ipoint, isgf) = dphi(ialpha, ipoint, isgf) + weight*exponential* &
345 (polynomial_derivative(ialpha) - &
346 2.0_dp*exponent*relative(ialpha)*polynomial)
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.
Common setup operations used by the periodic and non-periodic GW RI-RS implementations.
subroutine, public get_rirs_cluster_atoms(particle_set, cell, icenter_atom, radius, atom_indices)
Form C_A from nuclei within the specified radius, in global atom order.
subroutine, public precompute_ri_rs_radii(bs_env)
Compute per-atom AO and RI basis radii from the most diffuse Gaussian primitive in the AO ("ORB") and...
subroutine, public filter_grid_to_voronoi(points, icenter_atom, particle_set, mask, atom_indices)
Retain source-grid points inside the Voronoi volume of one atom.
subroutine, public evaluate_ao_on_points(phi, grid_points, iatom, particle_set, qs_kind_set, cell, dphi, cutoff_squared)
Evaluate contracted spherical AOs, and optionally their grid-coordinate derivatives.
subroutine, public evaluate_ao_basis_on_points(phi, grid_points, basis, source_position, cell, dphi, cutoff_squared)
Evaluate one explicitly supplied contracted Gaussian basis on Cartesian points.
Defines the basic variable types.
integer, parameter, public dp
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public ncoset
integer, dimension(:, :), allocatable, public indco
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public angstrom
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, 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_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, hund_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, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Type defining parameters related to the simulation cell.
Provides all information about a quickstep kind.