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)
THEN
142 cpabort(
"Not all KINDs have the same number of PAO_DESCRIPTOR sections")
144 weight = pao_descriptors(idesc)%weight
145 beta = pao_descriptors(idesc)%beta
146 CALL pao_calc_gaussian(basis_set, block_v=block_v, rab=rab, lpot=0, beta=beta, weight=weight)
150 v_evecs(:, :) = block_v(:, :)
154 IF (
PRESENT(descriptor))
THEN
155 descriptor((idesc - 1)*n + 1:idesc*n) = v_evals(:)
159 IF (
PRESENT(forces))
THEN
160 cpassert(
PRESENT(descr_grad))
163 w = descr_grad((idesc - 1)*n + k)
164 block_m(:, :) = block_m(:, :) + w*matmul(v_evecs(:, k:k), transpose(v_evecs(:, k:k)))
167 IF (jatom == iatom) cycle
168 ra = particle_set(iatom)%r
169 rb = particle_set(jatom)%r
170 rab =
pbc(ra, rb, cell)
171 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
172 CALL get_qs_kind(qs_kind_set(jkind), pao_descriptors=pao_descriptors)
173 weight = pao_descriptors(idesc)%weight
174 beta = pao_descriptors(idesc)%beta
176 CALL pao_calc_gaussian(basis_set, block_d=block_d, rab=rab, lpot=0, beta=beta, weight=weight)
178 forces(iatom, i) = forces(iatom, i) - sum(block_m*block_d(:, :, i))
179 forces(jatom, i) = forces(jatom, i) + sum(block_m*block_d(:, :, i))
186 CALL timestop(handle)
187 END SUBROUTINE calc_descriptor_pot
199 SUBROUTINE calc_descriptor_overlap(particle_set, qs_kind_set, cell, iatom, descriptor, descr_grad, forces)
201 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
203 INTEGER,
INTENT(IN) :: iatom
204 REAL(
dp),
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: descriptor
205 REAL(
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: descr_grad
206 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT),
OPTIONAL :: forces
208 CHARACTER(len=*),
PARAMETER :: routinen =
'calc_descriptor_overlap'
210 INTEGER :: handle, idesc, ikind, j, jatom, jkind, &
211 k, katom, kkind, n, natoms, ndesc
212 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: neighbor_order
213 REAL(
dp) :: beta_sum, deriv, exponent, integral, jbeta, jweight, kbeta, kweight, &
214 normalization, rij2, rik2, rjk2, sbeta, screening_radius, screening_volume, w
215 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: s_evals
216 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: block_m, block_s, s_evecs
217 REAL(
dp),
DIMENSION(3) :: ri, rij, rik, rj, rjk, rk
218 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: neighbor_dist
222 CALL timeset(routinen, handle)
224 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
225 CALL get_qs_kind(qs_kind_set(ikind), pao_descriptors=ipao_descriptors)
227 natoms =
SIZE(particle_set)
228 ndesc =
SIZE(ipao_descriptors)
229 IF (ndesc == 0) cpabort(
"No PAO_DESCRIPTOR section found")
232 screening_radius = 0.0_dp
234 screening_radius = max(screening_radius, ipao_descriptors(idesc)%screening_radius)
238 screening_volume =
fourpi/3.0_dp*screening_radius**3
239 n = int(screening_volume/35.0_dp)
241 ALLOCATE (block_s(n, n), s_evals(n), s_evecs(n, n))
242 IF (
PRESENT(descriptor))
ALLOCATE (descriptor(n*ndesc))
243 IF (
PRESENT(forces))
ALLOCATE (block_m(n, n))
247 ALLOCATE (neighbor_dist(natoms), neighbor_order(natoms))
248 ri = particle_set(iatom)%r
250 rj = particle_set(jatom)%r
251 rij =
pbc(ri, rj, cell)
252 neighbor_dist(jatom) = sqrt(sum(rij**2))
254 CALL sort(neighbor_dist, natoms, neighbor_order)
255 cpassert(neighbor_order(1) == iatom)
259 IF (neighbor_dist(n + 1) < screening_radius)
THEN
260 cpabort(
"PAO heuristic for descriptor size broke down")
265 sbeta = ipao_descriptors(idesc)%screening
269 DO j = 1, min(natoms, n)
270 DO k = 1, min(natoms, n)
271 jatom = neighbor_order(j)
272 katom = neighbor_order(k)
275 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
276 CALL get_qs_kind(qs_kind_set(jkind), pao_descriptors=jpao_descriptors)
277 CALL get_atomic_kind(particle_set(katom)%atomic_kind, kind_number=kkind)
278 CALL get_qs_kind(qs_kind_set(kkind), pao_descriptors=kpao_descriptors)
279 IF (
SIZE(jpao_descriptors) /= ndesc .OR.
SIZE(kpao_descriptors) /= ndesc)
THEN
280 cpabort(
"Not all KINDs have the same number of PAO_DESCRIPTOR sections")
282 jweight = jpao_descriptors(idesc)%weight
283 jbeta = jpao_descriptors(idesc)%beta
284 kweight = kpao_descriptors(idesc)%weight
285 kbeta = kpao_descriptors(idesc)%beta
286 beta_sum = sbeta + jbeta + kbeta
289 rj = particle_set(jatom)%r
290 rk = particle_set(katom)%r
291 rij =
pbc(ri, rj, cell)
292 rik =
pbc(ri, rk, cell)
293 rjk =
pbc(rj, rk, cell)
299 exponent = -(sbeta*jbeta*rij2 + sbeta*kbeta*rik2 + jbeta*kbeta*rjk2)/beta_sum
300 integral = exp(exponent)*
rootpi/sqrt(beta_sum)
301 normalization = sqrt(jbeta*kbeta)/
rootpi**2
302 block_s(j, k) = jweight*kweight*normalization*integral
307 s_evecs(:, :) = block_s(:, :)
311 IF (
PRESENT(descriptor))
THEN
312 descriptor((idesc - 1)*n + 1:idesc*n) = s_evals(:)
316 IF (
PRESENT(forces))
THEN
317 cpassert(
PRESENT(descr_grad))
320 w = descr_grad((idesc - 1)*n + k)
321 block_m(:, :) = block_m(:, :) + w*matmul(s_evecs(:, k:k), transpose(s_evecs(:, k:k)))
324 DO j = 1, min(natoms, n)
325 DO k = 1, min(natoms, n)
326 jatom = neighbor_order(j)
327 katom = neighbor_order(k)
330 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
331 CALL get_qs_kind(qs_kind_set(jkind), pao_descriptors=jpao_descriptors)
332 CALL get_atomic_kind(particle_set(katom)%atomic_kind, kind_number=kkind)
333 CALL get_qs_kind(qs_kind_set(kkind), pao_descriptors=kpao_descriptors)
334 jweight = jpao_descriptors(idesc)%weight
335 jbeta = jpao_descriptors(idesc)%beta
336 kweight = kpao_descriptors(idesc)%weight
337 kbeta = kpao_descriptors(idesc)%beta
338 beta_sum = sbeta + jbeta + kbeta
341 rj = particle_set(jatom)%r
342 rk = particle_set(katom)%r
343 rij =
pbc(ri, rj, cell)
344 rik =
pbc(ri, rk, cell)
345 rjk =
pbc(rj, rk, cell)
351 exponent = -(sbeta*jbeta*rij2 + sbeta*kbeta*rik2 + jbeta*kbeta*rjk2)/beta_sum
352 integral = exp(exponent)*
rootpi/sqrt(beta_sum)
353 normalization = sqrt(jbeta*kbeta)/
rootpi**2
354 deriv = 2.0_dp/beta_sum*block_m(j, k)
355 w = jweight*kweight*normalization*integral*deriv
356 forces(iatom, :) = forces(iatom, :) - sbeta*jbeta*rij*w
357 forces(jatom, :) = forces(jatom, :) + sbeta*jbeta*rij*w
358 forces(iatom, :) = forces(iatom, :) - sbeta*kbeta*rik*w
359 forces(katom, :) = forces(katom, :) + sbeta*kbeta*rik*w
360 forces(jatom, :) = forces(jatom, :) - jbeta*kbeta*rjk*w
361 forces(katom, :) = forces(katom, :) + jbeta*kbeta*rjk*w
367 CALL timestop(handle)
368 END SUBROUTINE calc_descriptor_overlap
380 SUBROUTINE calc_descriptor_r12(particle_set, qs_kind_set, cell, iatom, descriptor, descr_grad, forces)
382 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
384 INTEGER,
INTENT(IN) :: iatom
385 REAL(
dp),
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: descriptor
386 REAL(
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: descr_grad
387 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT),
OPTIONAL :: forces
389 REAL(
dp),
DIMENSION(3) :: g, r1, r12, r2
391 cpassert(
SIZE(particle_set) == 2)
393 mark_used(qs_kind_set)
397 r1 = particle_set(1)%r
398 r2 = particle_set(2)%r
399 r12 =
pbc(r1, r2, cell)
401 IF (
PRESENT(descriptor))
THEN
402 ALLOCATE (descriptor(1))
403 descriptor(1) = sqrt(sum(r12**2))
406 IF (
PRESENT(forces))
THEN
407 cpassert(
PRESENT(descr_grad))
408 g = r12/sqrt(sum(r12**2))*descr_grad(1)
409 forces(1, :) = forces(1, :) + g
410 forces(2, :) = forces(2, :) - g
412 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, 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, 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, monovalent, 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.