31#include "./base/base_uses.f90"
37 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'pao_ml_descriptor'
59 INTEGER,
INTENT(IN) :: iatom
60 REAL(
dp),
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: descriptor
61 REAL(
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: descr_grad
62 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT),
OPTIONAL :: forces
64 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_ml_calc_descriptor'
68 CALL timeset(routinen, handle)
70 cpassert(
PRESENT(forces) .EQV.
PRESENT(descr_grad))
72 SELECT CASE (pao%ml_descriptor)
74 CALL calc_descriptor_pot(particle_set, qs_kind_set, cell, iatom, descriptor, descr_grad, forces)
76 CALL calc_descriptor_overlap(particle_set, qs_kind_set, cell, iatom, descriptor, descr_grad, forces)
78 CALL calc_descriptor_r12(particle_set, qs_kind_set, cell, iatom, descriptor, descr_grad, forces)
80 cpabort(
"PAO: unknown descriptor")
96 SUBROUTINE calc_descriptor_pot(particle_set, qs_kind_set, cell, iatom, descriptor, descr_grad, forces)
100 INTEGER,
INTENT(IN) :: iatom
101 REAL(
dp),
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: descriptor
102 REAL(
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: descr_grad
103 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT),
OPTIONAL :: forces
105 CHARACTER(len=*),
PARAMETER :: routinen =
'calc_descriptor_pot'
107 INTEGER :: handle, i, idesc, ikind, jatom, jkind, &
109 REAL(
dp) :: beta, w, weight
110 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: v_evals
111 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: block_m, block_v, v_evecs
112 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: block_d
113 REAL(
dp),
DIMENSION(3) :: ra, rab, rb
117 CALL timeset(routinen, handle)
119 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
120 CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set, pao_descriptors=pao_descriptors)
122 natoms =
SIZE(particle_set)
123 ndesc =
SIZE(pao_descriptors)
124 IF (ndesc == 0) cpabort(
"No PAO_DESCRIPTOR section found")
126 ALLOCATE (block_v(n, n), v_evecs(n, n), v_evals(n))
127 IF (
PRESENT(descriptor))
ALLOCATE (descriptor(n*ndesc))
128 IF (
PRESENT(forces))
ALLOCATE (block_d(n, n, 3), block_m(n, n))
135 IF (jatom == iatom) cycle
136 ra = particle_set(iatom)%r
137 rb = particle_set(jatom)%r
138 rab =
pbc(ra, rb, cell)
139 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
140 CALL get_qs_kind(qs_kind_set(jkind), pao_descriptors=pao_descriptors)
141 IF (
SIZE(pao_descriptors) /= ndesc) &
142 cpabort(
"Not all KINDs have the same number of PAO_DESCRIPTOR sections")
143 weight = pao_descriptors(idesc)%weight
144 beta = pao_descriptors(idesc)%beta
145 CALL pao_calc_gaussian(basis_set, block_v=block_v, rab=rab, lpot=0, beta=beta, weight=weight)
149 v_evecs(:, :) = block_v(:, :)
153 IF (
PRESENT(descriptor)) &
154 descriptor((idesc - 1)*n + 1:idesc*n) = v_evals(:)
157 IF (
PRESENT(forces))
THEN
158 cpassert(
PRESENT(descr_grad))
161 w = descr_grad((idesc - 1)*n + k)
162 block_m(:, :) = block_m(:, :) + w*matmul(v_evecs(:, k:k), transpose(v_evecs(:, k:k)))
165 IF (jatom == iatom) cycle
166 ra = particle_set(iatom)%r
167 rb = particle_set(jatom)%r
168 rab =
pbc(ra, rb, cell)
169 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
170 CALL get_qs_kind(qs_kind_set(jkind), pao_descriptors=pao_descriptors)
171 weight = pao_descriptors(idesc)%weight
172 beta = pao_descriptors(idesc)%beta
174 CALL pao_calc_gaussian(basis_set, block_d=block_d, rab=rab, lpot=0, beta=beta, weight=weight)
176 forces(iatom, i) = forces(iatom, i) - sum(block_m*block_d(:, :, i))
177 forces(jatom, i) = forces(jatom, i) + sum(block_m*block_d(:, :, i))
184 CALL timestop(handle)
185 END SUBROUTINE calc_descriptor_pot
197 SUBROUTINE calc_descriptor_overlap(particle_set, qs_kind_set, cell, iatom, descriptor, descr_grad, forces)
199 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
201 INTEGER,
INTENT(IN) :: iatom
202 REAL(
dp),
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: descriptor
203 REAL(
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: descr_grad
204 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT),
OPTIONAL :: forces
206 CHARACTER(len=*),
PARAMETER :: routinen =
'calc_descriptor_overlap'
208 INTEGER :: handle, idesc, ikind, j, jatom, jkind, &
209 k, katom, kkind, n, natoms, ndesc
210 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: neighbor_order
211 REAL(
dp) :: beta_sum, deriv, exponent, integral, jbeta, jweight, kbeta, kweight, &
212 normalization, rij2, rik2, rjk2, sbeta, screening_radius, screening_volume, w
213 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: s_evals
214 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: block_m, block_s, s_evecs
215 REAL(
dp),
DIMENSION(3) :: ri, rij, rik, rj, rjk, rk
216 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: neighbor_dist
220 CALL timeset(routinen, handle)
222 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
223 CALL get_qs_kind(qs_kind_set(ikind), pao_descriptors=ipao_descriptors)
225 natoms =
SIZE(particle_set)
226 ndesc =
SIZE(ipao_descriptors)
227 IF (ndesc == 0) cpabort(
"No PAO_DESCRIPTOR section found")
230 screening_radius = 0.0_dp
232 screening_radius = max(screening_radius, ipao_descriptors(idesc)%screening_radius)
236 screening_volume =
fourpi/3.0_dp*screening_radius**3
237 n = int(screening_volume/35.0_dp)
239 ALLOCATE (block_s(n, n), s_evals(n), s_evecs(n, n))
240 IF (
PRESENT(descriptor))
ALLOCATE (descriptor(n*ndesc))
241 IF (
PRESENT(forces))
ALLOCATE (block_m(n, n))
245 ALLOCATE (neighbor_dist(natoms), neighbor_order(natoms))
246 ri = particle_set(iatom)%r
248 rj = particle_set(jatom)%r
249 rij =
pbc(ri, rj, cell)
250 neighbor_dist(jatom) = sqrt(sum(rij**2))
252 CALL sort(neighbor_dist, natoms, neighbor_order)
253 cpassert(neighbor_order(1) == iatom)
257 IF (neighbor_dist(n + 1) < screening_radius) &
258 cpabort(
"PAO heuristic for descriptor size broke down")
262 sbeta = ipao_descriptors(idesc)%screening
266 DO j = 1, min(natoms, n)
267 DO k = 1, min(natoms, n)
268 jatom = neighbor_order(j)
269 katom = neighbor_order(k)
272 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
273 CALL get_qs_kind(qs_kind_set(jkind), pao_descriptors=jpao_descriptors)
274 CALL get_atomic_kind(particle_set(katom)%atomic_kind, kind_number=kkind)
275 CALL get_qs_kind(qs_kind_set(kkind), pao_descriptors=kpao_descriptors)
276 IF (
SIZE(jpao_descriptors) /= ndesc .OR.
SIZE(kpao_descriptors) /= ndesc) &
277 cpabort(
"Not all KINDs have the same number of PAO_DESCRIPTOR sections")
278 jweight = jpao_descriptors(idesc)%weight
279 jbeta = jpao_descriptors(idesc)%beta
280 kweight = kpao_descriptors(idesc)%weight
281 kbeta = kpao_descriptors(idesc)%beta
282 beta_sum = sbeta + jbeta + kbeta
285 rj = particle_set(jatom)%r
286 rk = particle_set(katom)%r
287 rij =
pbc(ri, rj, cell)
288 rik =
pbc(ri, rk, cell)
289 rjk =
pbc(rj, rk, cell)
295 exponent = -(sbeta*jbeta*rij2 + sbeta*kbeta*rik2 + jbeta*kbeta*rjk2)/beta_sum
296 integral = exp(exponent)*
rootpi/sqrt(beta_sum)
297 normalization = sqrt(jbeta*kbeta)/
rootpi**2
298 block_s(j, k) = jweight*kweight*normalization*integral
303 s_evecs(:, :) = block_s(:, :)
307 IF (
PRESENT(descriptor)) &
308 descriptor((idesc - 1)*n + 1:idesc*n) = s_evals(:)
311 IF (
PRESENT(forces))
THEN
312 cpassert(
PRESENT(descr_grad))
315 w = descr_grad((idesc - 1)*n + k)
316 block_m(:, :) = block_m(:, :) + w*matmul(s_evecs(:, k:k), transpose(s_evecs(:, k:k)))
319 DO j = 1, min(natoms, n)
320 DO k = 1, min(natoms, n)
321 jatom = neighbor_order(j)
322 katom = neighbor_order(k)
325 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
326 CALL get_qs_kind(qs_kind_set(jkind), pao_descriptors=jpao_descriptors)
327 CALL get_atomic_kind(particle_set(katom)%atomic_kind, kind_number=kkind)
328 CALL get_qs_kind(qs_kind_set(kkind), pao_descriptors=kpao_descriptors)
329 jweight = jpao_descriptors(idesc)%weight
330 jbeta = jpao_descriptors(idesc)%beta
331 kweight = kpao_descriptors(idesc)%weight
332 kbeta = kpao_descriptors(idesc)%beta
333 beta_sum = sbeta + jbeta + kbeta
336 rj = particle_set(jatom)%r
337 rk = particle_set(katom)%r
338 rij =
pbc(ri, rj, cell)
339 rik =
pbc(ri, rk, cell)
340 rjk =
pbc(rj, rk, cell)
346 exponent = -(sbeta*jbeta*rij2 + sbeta*kbeta*rik2 + jbeta*kbeta*rjk2)/beta_sum
347 integral = exp(exponent)*
rootpi/sqrt(beta_sum)
348 normalization = sqrt(jbeta*kbeta)/
rootpi**2
349 deriv = 2.0_dp/beta_sum*block_m(j, k)
350 w = jweight*kweight*normalization*integral*deriv
351 forces(iatom, :) = forces(iatom, :) - sbeta*jbeta*rij*w
352 forces(jatom, :) = forces(jatom, :) + sbeta*jbeta*rij*w
353 forces(iatom, :) = forces(iatom, :) - sbeta*kbeta*rik*w
354 forces(katom, :) = forces(katom, :) + sbeta*kbeta*rik*w
355 forces(jatom, :) = forces(jatom, :) - jbeta*kbeta*rjk*w
356 forces(katom, :) = forces(katom, :) + jbeta*kbeta*rjk*w
362 CALL timestop(handle)
363 END SUBROUTINE calc_descriptor_overlap
375 SUBROUTINE calc_descriptor_r12(particle_set, qs_kind_set, cell, iatom, descriptor, descr_grad, forces)
377 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
379 INTEGER,
INTENT(IN) :: iatom
380 REAL(
dp),
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: descriptor
381 REAL(
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: descr_grad
382 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT),
OPTIONAL :: forces
384 REAL(
dp),
DIMENSION(3) :: g, r1, r12, r2
386 cpassert(
SIZE(particle_set) == 2)
388 mark_used(qs_kind_set)
392 r1 = particle_set(1)%r
393 r2 = particle_set(2)%r
394 r12 =
pbc(r1, r2, cell)
396 IF (
PRESENT(descriptor))
THEN
397 ALLOCATE (descriptor(1))
398 descriptor(1) = sqrt(sum(r12**2))
401 IF (
PRESENT(forces))
THEN
402 cpassert(
PRESENT(descr_grad))
403 g = r12/sqrt(sum(r12**2))*descr_grad(1)
404 forces(1, :) = forces(1, :) + g
405 forces(2, :) = forces(2, :) - g
407 END SUBROUTINE calc_descriptor_r12
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Handles all functions related to the CELL.
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public rootpi
real(kind=dp), parameter, public fourpi
Collection of simple mathematical functions and subroutines.
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Feature vectors for describing chemical environments in a rotationally invariant fashion.
subroutine, public pao_ml_calc_descriptor(pao, particle_set, qs_kind_set, cell, iatom, descriptor, descr_grad, forces)
Calculates a descriptor for chemical environment of given atom.
Factory routines for potentials used e.g. by pao_param_exp and pao_ml.
subroutine, public pao_calc_gaussian(basis_set, block_v, block_d, rab, lpot, beta, weight, min_shell, max_shell, min_l, max_l)
Calculates potential term of the form r**lpot * Exp(-beta*r**2) One needs to call init_orbital_pointe...
Types used by the PAO machinery.
Define the data structure for the particle information.
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, 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, 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_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
All kind of helpful little routines.
Type defining parameters related to the simulation cell.
Holds information about a PAO descriptor.
Provides all information about a quickstep kind.