26#include "./base/base_uses.f90"
34 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'ri_rs_utils'
52 REAL(kind=
dp),
INTENT(IN) :: eps
53 INTEGER,
INTENT(IN) :: unit_nr
55 CHARACTER(LEN=*),
PARAMETER :: routinen =
'precompute_ri_rs_radii'
56 REAL(kind=
dp),
PARAMETER :: min_exponent_for_radius = 1.0e-3_dp
58 INTEGER :: handle, i, iatom, ikind, j, natom, nkind
59 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kind_of
60 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha_min_ao_kind, alpha_min_ri_kind
61 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: zet_ao, zet_ri
63 CALL timeset(routinen, handle)
65 cpassert(
ASSOCIATED(ri_rs%atomic_kind_set))
66 cpassert(
ASSOCIATED(ri_rs%particle_set))
67 cpassert(0.0_dp < eps .AND. eps < 1.0_dp)
68 nkind =
SIZE(ri_rs%atomic_kind_set)
69 natom =
SIZE(ri_rs%particle_set)
71 ALLOCATE (alpha_min_ao_kind(nkind), alpha_min_ri_kind(nkind))
72 alpha_min_ao_kind = huge(1.0_dp)
73 alpha_min_ri_kind = huge(1.0_dp)
76 zet_ao => basis_set_ao(ikind)%gto_basis_set%zet
77 zet_ri => basis_set_ri(ikind)%gto_basis_set%zet
78 DO i = 1,
SIZE(zet_ao, 1)
79 DO j = 1,
SIZE(zet_ao, 2)
80 IF (zet_ao(i, j) > min_exponent_for_radius)
THEN
81 alpha_min_ao_kind(ikind) = min(alpha_min_ao_kind(ikind), zet_ao(i, j))
85 DO i = 1,
SIZE(zet_ri, 1)
86 DO j = 1,
SIZE(zet_ri, 2)
87 IF (zet_ri(i, j) > min_exponent_for_radius)
THEN
88 alpha_min_ri_kind(ikind) = min(alpha_min_ri_kind(ikind), zet_ri(i, j))
96 ALLOCATE (ri_rs%radius_ao_per_atom(natom))
97 ALLOCATE (ri_rs%radius_ri_per_atom(natom))
99 ikind = kind_of(iatom)
100 ri_rs%radius_ao_per_atom(iatom) = sqrt(-log(eps)/alpha_min_ao_kind(ikind))
101 ri_rs%radius_ri_per_atom(iatom) = sqrt(-log(eps)/alpha_min_ri_kind(ikind))
104 IF (unit_nr > 0)
THEN
105 WRITE (unit_nr,
'(T2,A)')
'RI-RS basis radii (Å):'
106 WRITE (unit_nr,
'(T4,A6,2X,A4,2A14)')
'Kind',
'Elem',
'r_AO (Å)',
'r_RI (Å)'
108 WRITE (unit_nr,
'(T4,I6,2X,A4,2F14.4)') &
110 ri_rs%atomic_kind_set(ikind)%element_symbol, &
111 sqrt(-log(eps)/alpha_min_ao_kind(ikind))*
angstrom, &
112 sqrt(-log(eps)/alpha_min_ri_kind(ikind))*
angstrom
114 WRITE (unit_nr,
'(A)')
' '
117 DEALLOCATE (alpha_min_ao_kind, alpha_min_ri_kind, kind_of)
119 CALL timestop(handle)
131 REAL(kind=
dp),
ALLOCATABLE,
INTENT(INOUT) :: points(:, :)
132 INTEGER,
INTENT(IN) :: icenter_atom
134 LOGICAL,
INTENT(OUT),
OPTIONAL :: mask(:)
135 INTEGER,
INTENT(IN),
OPTIONAL :: atom_indices(:)
137 INTEGER :: iatom, iatom_index, ipoint, n_atoms, &
139 LOGICAL,
ALLOCATABLE :: keep(:)
140 REAL(kind=
dp) :: displacement(3), distance2, max_radius2, &
142 REAL(kind=
dp),
ALLOCATABLE :: filtered_points(:, :)
144 ALLOCATE (keep(
SIZE(points, 2)), source=.true.)
145 max_radius2 = maxval(sum(points**2, dim=1))
146 n_atoms =
SIZE(particle_set)
147 IF (
PRESENT(atom_indices)) n_atoms =
SIZE(atom_indices)
148 DO iatom_index = 1, n_atoms
149 IF (
PRESENT(atom_indices))
THEN
150 iatom = atom_indices(iatom_index)
151 cpassert(iatom >= 1 .AND. iatom <=
SIZE(particle_set))
155 IF (iatom == icenter_atom) cycle
156 displacement(:) = particle_set(iatom)%r - particle_set(icenter_atom)%r
157 distance2 = sum(displacement**2)
159 IF (distance2 > 4.0_dp*max_radius2) cycle
160 tolerance = 32.0_dp*epsilon(1.0_dp)*max(1.0_dp, distance2)
161 DO ipoint = 1,
SIZE(points, 2)
162 IF (.NOT. keep(ipoint)) cycle
164 IF (2.0_dp*dot_product(points(:, ipoint), displacement) > distance2 + tolerance)
THEN
165 keep(ipoint) = .false.
166 ELSE IF (iatom < icenter_atom)
THEN
167 IF (abs(2.0_dp*dot_product(points(:, ipoint), displacement) - distance2) <= tolerance)
THEN
168 keep(ipoint) = .false.
173 IF (
PRESENT(mask))
THEN
174 cpassert(
SIZE(mask) ==
SIZE(keep))
179 ALLOCATE (filtered_points(3, n_keep))
180 IF (n_keep > 0) filtered_points(:, :) = reshape(pack(points, spread(keep, 1, 3)), [3, n_keep])
181 CALL move_alloc(filtered_points, points)
195 INTEGER,
INTENT(IN) :: icenter_atom
196 REAL(kind=
dp),
INTENT(IN) :: radius
197 INTEGER,
ALLOCATABLE,
INTENT(OUT) :: atom_indices(:)
199 INTEGER :: iatom, ncluster
200 INTEGER,
ALLOCATABLE :: work(:)
202 ALLOCATE (work(
SIZE(particle_set)))
204 DO iatom = 1,
SIZE(particle_set)
205 IF (sum(
pbc(particle_set(iatom)%r - particle_set(icenter_atom)%r, cell)**2) <= radius**2)
THEN
206 ncluster = ncluster + 1
207 work(ncluster) = iatom
210 ALLOCATE (atom_indices(ncluster), source=work(:ncluster))
236 dphi, cutoff_squared)
237 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: phi
238 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: grid_points
239 INTEGER,
INTENT(IN) :: iatom
241 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
243 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(INOUT), &
245 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: cutoff_squared
247 CHARACTER(len=*),
PARAMETER :: routinen =
'evaluate_ao_on_points'
249 INTEGER :: handle, ikind
252 CALL timeset(routinen, handle)
253 cpassert(
SIZE(grid_points, 1) == 3)
254 cpassert(
SIZE(phi, 1) ==
SIZE(grid_points, 2))
255 IF (
PRESENT(dphi))
THEN
256 cpassert(
SIZE(dphi, 1) == 3)
257 cpassert(
SIZE(dphi, 2) ==
SIZE(phi, 1))
258 cpassert(
SIZE(dphi, 3) ==
SIZE(phi, 2))
261 ikind = particle_set(iatom)%atomic_kind%kind_number
262 CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis, basis_type=
'ORB')
263 IF (.NOT.
ASSOCIATED(basis))
THEN
264 CALL timestop(handle)
268 particle_set(iatom)%r, cell, dphi, cutoff_squared)
269 CALL timestop(handle)
284 dphi, cutoff_squared, periodic_images)
285 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: phi
286 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: grid_points
288 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: source_position
290 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(INOUT), &
292 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: cutoff_squared
293 LOGICAL,
INTENT(IN),
OPTIONAL :: periodic_images
295 INTEGER :: first_sgf, ialpha, ico, iend_co, image_extent(3), ipgf, ipoint, irow, iset, isgf, &
296 ishell, istart_co, ix, iy, iz, l, last_sgf, lx, ly, lz, n_cart_total
297 LOGICAL :: sum_images
298 REAL(kind=
dp) :: exponent, exponential, hmat(3, 3), polynomial, polynomial_derivative(3), &
299 radius2, relative(3), relative_raw(3), weight
301 cpassert(
ASSOCIATED(basis))
302 cpassert(
SIZE(grid_points, 1) == 3)
303 cpassert(
SIZE(phi, 1) ==
SIZE(grid_points, 2))
304 IF (
PRESENT(dphi))
THEN
305 cpassert(
SIZE(dphi, 1) == 3)
306 cpassert(
SIZE(dphi, 2) ==
SIZE(phi, 1))
307 cpassert(
SIZE(dphi, 3) ==
SIZE(phi, 2))
311 IF (
PRESENT(periodic_images)) sum_images = periodic_images
315 image_extent = cell%perd
326 DO ipoint = 1,
SIZE(grid_points, 2)
327 relative_raw = grid_points(:, ipoint) - source_position
328 IF (.NOT. sum_images) relative_raw =
pbc(relative_raw, cell)
329 DO ix = -image_extent(1), image_extent(1)
330 DO iy = -image_extent(2), image_extent(2)
331 DO iz = -image_extent(3), image_extent(3)
332 relative = relative_raw
333 IF (sum_images) relative = relative_raw - matmul(hmat, real([ix, iy, iz],
dp))
334 radius2 = dot_product(relative, relative)
335 IF (
PRESENT(cutoff_squared))
THEN
336 IF (radius2 > cutoff_squared) cycle
339 DO iset = 1, basis%nset
340 n_cart_total =
ncoset(basis%lmax(iset))
341 DO ishell = 1, basis%nshell(iset)
342 l = basis%l(ishell, iset)
343 istart_co =
ncoset(l - 1) + 1
345 first_sgf = basis%first_sgf(ishell, iset)
346 last_sgf = basis%last_sgf(ishell, iset)
347 DO ipgf = 1, basis%npgf(iset)
348 exponent = basis%zet(ipgf, iset)
349 exponential = exp(-exponent*radius2)
350 DO isgf = first_sgf, last_sgf
351 DO ico = istart_co, iend_co
352 irow = (ipgf - 1)*n_cart_total + ico
353 weight = basis%sphi(irow, isgf)
357 polynomial = relative(1)**lx*relative(2)**ly*relative(3)**lz
358 phi(ipoint, isgf) = phi(ipoint, isgf) + weight*polynomial*exponential
360 IF (
PRESENT(dphi))
THEN
361 polynomial_derivative = 0.0_dp
362 IF (lx > 0) polynomial_derivative(1) = real(lx,
dp)*relative(1)**(lx - 1)* &
363 relative(2)**ly*relative(3)**lz
364 IF (ly > 0) polynomial_derivative(2) = real(ly,
dp)*relative(1)**lx* &
365 relative(2)**(ly - 1)*relative(3)**lz
366 IF (lz > 0) polynomial_derivative(3) = real(lz,
dp)*relative(1)**lx* &
367 relative(2)**ly*relative(3)**(lz - 1)
369 dphi(ialpha, ipoint, isgf) = dphi(ialpha, ipoint, isgf) + weight*exponential* &
370 (polynomial_derivative(ialpha) - &
371 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.
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
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.
Shared real-space resolution-of-identity grid and matrix data.
Geometry and AO evaluation for real-space resolution of the identity.
subroutine, public evaluate_ao_basis_on_points(phi, grid_points, basis, source_position, cell, dphi, cutoff_squared, periodic_images)
Evaluate one explicitly supplied contracted Gaussian basis on Cartesian points.
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 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 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(ri_rs, basis_set_ao, basis_set_ri, eps, unit_nr)
Compute per-atom AO and RI basis radii from the most diffuse Gaussian primitive in the AO ("ORB") and...
Type defining parameters related to the simulation cell.
Provides all information about a quickstep kind.