38#include "./base/base_uses.f90"
44 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .false.
45 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'nnp_acsf'
50 REAL(KIND=
dp),
PARAMETER,
PRIVATE :: cutoff_eq_tol = 1.0e-5_dp
85 TYPE(
nnp_type),
INTENT(INOUT),
POINTER :: nnp
86 INTEGER,
INTENT(IN) :: i
87 LOGICAL,
INTENT(IN) :: calc_forces
88 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(INOUT), &
91 CHARACTER(len=*),
PARAMETER :: routinen =
'nnp_calc_acsf'
93 INTEGER :: handle, handle_nlist, handle_sf, ii, ind, izeta_il, j, k, l, m, n_ang1_s, &
94 n_ang2_s, n_input_nodes, n_symf_s, nthreads_ang, off, peak, s, sf
95 LOGICAL :: do_forces, homo_grp
96 REAL(kind=
dp) :: angular_il, arg_il, costheta_il, cutoff_s, cutoff_sqr, dfcut3_il, &
97 dfcutdr1_il, dfcutdr2_il, dfcutdr3_il, dgdx_t1, dgdx_t2, dsymdr1_il, dsymdr2_il, &
98 dsymdr3_il, eta_il, f_il, fcut3_il, ftot_il, g_il, inv_g2_il, lam_il, pref_il, &
99 pref_lam_il, prefzeta_il, r1, r1_inv, r2, r2_inv, r2sum_il, r3, r3_inv, r3_sqr, rsqr1, &
100 rsqr2, rsqr3, sym_il, symtmp_il, tanh_il, tmp1_il, tmp2_il, tmp3_il, tmp_il, tmpzeta_il, &
102 REAL(kind=
dp),
DIMENSION(3) :: dcosbase1_il, dcosbase2_il, &
103 dcosbase3_il, dr1dx_il, dr2dx_il, &
104 dr3dx_il, f_jj_il, f_kk_il, rvect1, &
110 CALL timeset(routinen, handle)
114 do_forces = calc_forces
120 IF (nnp%rad(ind)%n_symfgrp > 0)
THEN
121 IF (.NOT. nnp%rad(ind)%symfgrp(1)%spline_built)
CALL nnp_build_radial_splines(nnp)
128 associate(workspace => nnp%neighbor_interface_state%workspace(ind), &
129 neighbor => nnp%neighbor_interface_state%workspace(ind)%neighbor, &
130 radial_symtmp => nnp%neighbor_interface_state%workspace(ind)%radial_sym, &
131 radial_forcetmp => nnp%neighbor_interface_state%workspace(ind)%radial_force, &
132 angular_symtmp => nnp%neighbor_interface_state%workspace(ind)%angular_sym, &
133 angular_force3tmp => nnp%neighbor_interface_state%workspace(ind)%angular_force, &
134 self_dgdr => nnp%neighbor_interface_state%workspace(ind)%self_dGdr)
136 n_input_nodes = nnp%neighbor_interface_state%workspace(ind)%n_input_nodes
137 IF (do_forces) self_dgdr(:, 1:n_input_nodes) = 0.0_dp
142 CALL timeset(
'nnp_acsf_neighbor_fill', handle_nlist)
143 neighbor%pbc_copies = nnp%cell_list_cache%exact_pbc_copies
146 CALL timestop(handle_nlist)
149 nnp%rad(ind)%y = 0.0_dp
150 nnp%ang(ind)%y = 0.0_dp
156 IF (
SIZE(neighbor%n_ang1) > 0) peak = max(peak, maxval(neighbor%n_ang1))
157 IF (
SIZE(neighbor%n_ang2) > 0) peak = max(peak, maxval(neighbor%n_ang2))
160 associate(fc_cache1 => workspace%fc_cache1, &
161 dfc_cache1 => workspace%dfc_cache1, &
162 fc_cache2 => workspace%fc_cache2, &
163 dfc_cache2 => workspace%dfc_cache2)
168 CALL timeset(
'nnp_acsf_radial', handle_sf)
169 DO s = 1, nnp%rad(ind)%n_symfgrp
170 n_symf_s = nnp%rad(ind)%symfgrp(s)%n_symf
173 associate(rad_buf => workspace%dGdr_rad(s)%data)
175 DO j = 1, neighbor%n_rad(s)
176 rvect1 = neighbor%rad(s)%dist(1:3, j)
177 r1 = neighbor%rad(s)%dist(4, j)
178 CALL nnp_calc_rad(nnp, ind, s, rvect1, r1, &
179 radial_symtmp(1:n_symf_s), &
180 radial_forcetmp(:, 1:n_symf_s))
183 m = nnp%rad(ind)%symfgrp(s)%symf(sf)
184 self_dgdr(1, m) = self_dgdr(1, m) + radial_forcetmp(1, sf)
185 self_dgdr(2, m) = self_dgdr(2, m) + radial_forcetmp(2, sf)
186 self_dgdr(3, m) = self_dgdr(3, m) + radial_forcetmp(3, sf)
187 rad_buf(1, sf, j) = -radial_forcetmp(1, sf)
188 rad_buf(2, sf, j) = -radial_forcetmp(2, sf)
189 rad_buf(3, sf, j) = -radial_forcetmp(3, sf)
190 IF (
PRESENT(stress))
THEN
192 stress(:, l, m) = stress(:, l, m) + rvect1(:)*radial_forcetmp(l, sf)
195 nnp%rad(ind)%y(m) = nnp%rad(ind)%y(m) + radial_symtmp(sf)
200 CALL timestop(handle_sf)
203 CALL timeset(
'nnp_acsf_angular', handle_sf)
212 IF (nthreads_ang > 1 .AND. nnp%ang(ind)%n_symfgrp > 1)
THEN
213 IF (
PRESENT(stress))
THEN
214 CALL nnp_acsf_angular_loop_omp(nnp, ind, self_dgdr, off, stress)
216 CALL nnp_acsf_angular_loop_omp(nnp, ind, self_dgdr, off)
219 DO s = 1, nnp%ang(ind)%n_symfgrp
220 cutoff_s = nnp%ang(ind)%symfgrp(s)%cutoff
221 cutoff_sqr = cutoff_s*cutoff_s
222 n_symf_s = nnp%ang(ind)%symfgrp(s)%n_symf
223 n_ang1_s = neighbor%n_ang1(s)
224 homo_grp = (nnp%ang(ind)%symfgrp(s)%ele(1) == nnp%ang(ind)%symfgrp(s)%ele(2))
233 n_ang2_s = neighbor%n_ang2(s)
239 IF (n_ang1_s > 0) workspace%dGdr_ang_jj(s)%data(:, 1:n_symf_s, 1:n_ang1_s) = 0.0_dp
241 IF (n_ang1_s > 0) workspace%dGdr_ang_kk(s)%data(:, 1:n_symf_s, 1:n_ang1_s) = 0.0_dp
243 IF (n_ang2_s > 0) workspace%dGdr_ang_kk(s)%data(:, 1:n_symf_s, 1:n_ang2_s) = 0.0_dp
247 CALL nnp_fill_fc_dfc_cache(neighbor%ang1(s)%dist, n_ang1_s, &
248 nnp%cut_type, cutoff_s, fc_cache1, dfc_cache1)
256 associate(jj_buf => workspace%dGdr_ang_jj(s)%data, &
257 kk_buf => workspace%dGdr_ang_kk(s)%data, &
258 grp_il => nnp%ang(ind)%symfgrp(s))
260 rvect1 = neighbor%ang1(s)%dist(1:3, j)
261 r1 = neighbor%ang1(s)%dist(4, j)
262 DO k = j + 1, n_ang1_s
263 rvect2 = neighbor%ang1(s)%dist(1:3, k)
264 r2 = neighbor%ang1(s)%dist(4, k)
265 rvect3(1) = rvect2(1) - rvect1(1)
266 rvect3(2) = rvect2(2) - rvect1(2)
267 rvect3(3) = rvect2(3) - rvect1(3)
268 r3_sqr = rvect3(1)*rvect3(1) + rvect3(2)*rvect3(2) + rvect3(3)*rvect3(3)
269 IF (r3_sqr < cutoff_sqr)
THEN
273 rsqr1 = r1*r1; rsqr2 = r2*r2; rsqr3 = r3*r3
274 r2sum_il = rsqr1 + rsqr2 + rsqr3
275 f_il = rsqr3 - rsqr1 - rsqr2
277 costheta_il = f_il/g_il
279 SELECT CASE (nnp%cut_type)
281 arg_il =
pi*r3/cutoff_s
282 fcut3_il = 0.5_dp*(cos(arg_il) + 1.0_dp)
283 dfcut3_il = -0.5_dp*sin(arg_il)*(
pi/cutoff_s)
285 tanh_il = tanh(1.0_dp - r3/cutoff_s)
286 fcut3_il = tanh_il**3
287 dfcut3_il = (-3.0_dp/cutoff_s)*(tanh_il**2 - tanh_il**4)
289 cpabort(
"NNP| Cutoff function unknown")
292 ftot_il = fc_cache1(j)*fc_cache1(k)*fcut3_il
293 dfcutdr1_il = dfc_cache1(j)*fc_cache1(k)*fcut3_il
294 dfcutdr2_il = fc_cache1(j)*dfc_cache1(k)*fcut3_il
295 dfcutdr3_il = fc_cache1(j)*fc_cache1(k)*dfcut3_il
297 r1_inv = 1.0_dp/r1; r2_inv = 1.0_dp/r2; r3_inv = 1.0_dp/r3
298 dr1dx_il(:) = rvect1(:)*r1_inv
299 dr2dx_il(:) = rvect2(:)*r2_inv
300 dr3dx_il(:) = rvect3(:)*r3_inv
302 inv_g2_il = 1.0_dp/(g_il*g_il)
304 dgdx_t1 = 2.0_dp*r2*dr1dx_il(ii)
305 dgdx_t2 = 2.0_dp*r1*dr2dx_il(ii)
306 dcosbase1_il(ii) = -2.0_dp*(rvect1(ii) + rvect2(ii))*g_il &
307 - f_il*(-(dgdx_t1 + dgdx_t2))
308 dcosbase2_il(ii) = 2.0_dp*(rvect3(ii) + rvect1(ii))*g_il &
310 dcosbase3_il(ii) = 2.0_dp*(rvect2(ii) - rvect3(ii))*g_il &
316 m = off + grp_il%symf(sf)
317 lam_il = grp_il%pack_lam(sf)
318 zeta_il = grp_il%pack_zeta(sf)
319 eta_il = grp_il%pack_eta(sf)
320 prefzeta_il = grp_il%pack_prefzeta(sf)
322 tmp_il = 1.0_dp + lam_il*costheta_il
323 IF (tmp_il <= 0.0_dp)
THEN
327 IF (grp_il%pack_use_int_zeta(sf))
THEN
328 izeta_il = grp_il%pack_izeta(sf)
329 tmpzeta_il = tmp_il**(izeta_il - 1)
331 tmpzeta_il = tmp_il**(zeta_il - 1.0_dp)
333 angular_il = tmpzeta_il*tmp_il
336 symtmp_il = exp(-eta_il*r2sum_il)
337 sym_il = prefzeta_il*angular_il*symtmp_il*ftot_il
338 nnp%ang(ind)%y(m - off) = nnp%ang(ind)%y(m - off) + sym_il
340 pref_lam_il = zeta_il*tmpzeta_il*lam_il*inv_g2_il
341 tmp_il = -2.0_dp*symtmp_il*eta_il
342 dsymdr1_il = tmp_il*r1
343 dsymdr2_il = tmp_il*r2
344 dsymdr3_il = tmp_il*r3
346 pref_il = prefzeta_il*symtmp_il*ftot_il
347 tmp1_il = prefzeta_il*angular_il*(ftot_il*dsymdr1_il + dfcutdr1_il*symtmp_il)
348 tmp2_il = prefzeta_il*angular_il*(ftot_il*dsymdr2_il + dfcutdr2_il*symtmp_il)
349 tmp3_il = prefzeta_il*angular_il*(ftot_il*dsymdr3_il + dfcutdr3_il*symtmp_il)
352 f_jj_il(ii) = pref_il*pref_lam_il*dcosbase2_il(ii) &
353 - tmp1_il*dr1dx_il(ii) + tmp3_il*dr3dx_il(ii)
354 f_kk_il(ii) = pref_il*pref_lam_il*dcosbase3_il(ii) &
355 - tmp2_il*dr2dx_il(ii) - tmp3_il*dr3dx_il(ii)
356 self_dgdr(ii, m) = self_dgdr(ii, m) &
357 + pref_il*pref_lam_il*dcosbase1_il(ii) &
358 + tmp1_il*dr1dx_il(ii) + tmp2_il*dr2dx_il(ii)
359 jj_buf(ii, sf, j) = jj_buf(ii, sf, j) + f_jj_il(ii)
360 kk_buf(ii, sf, k) = kk_buf(ii, sf, k) + f_kk_il(ii)
362 IF (
PRESENT(stress))
THEN
364 stress(:, l, m) = stress(:, l, m) &
365 - rvect1(:)*f_jj_il(l) - rvect2(:)*f_kk_il(l)
376 CALL nnp_fill_fc_dfc_cache(neighbor%ang2(s)%dist, n_ang2_s, &
377 nnp%cut_type, cutoff_s, fc_cache2, dfc_cache2)
379 associate(jj_buf => workspace%dGdr_ang_jj(s)%data, &
380 kk_buf => workspace%dGdr_ang_kk(s)%data, &
381 grp_il => nnp%ang(ind)%symfgrp(s))
383 rvect1 = neighbor%ang1(s)%dist(1:3, j)
384 r1 = neighbor%ang1(s)%dist(4, j)
386 rvect2 = neighbor%ang2(s)%dist(1:3, k)
387 r2 = neighbor%ang2(s)%dist(4, k)
388 rvect3(1) = rvect2(1) - rvect1(1)
389 rvect3(2) = rvect2(2) - rvect1(2)
390 rvect3(3) = rvect2(3) - rvect1(3)
391 r3_sqr = rvect3(1)*rvect3(1) + rvect3(2)*rvect3(2) + rvect3(3)*rvect3(3)
392 IF (r3_sqr < cutoff_sqr)
THEN
396 rsqr1 = r1*r1; rsqr2 = r2*r2; rsqr3 = r3*r3
397 r2sum_il = rsqr1 + rsqr2 + rsqr3
398 f_il = rsqr3 - rsqr1 - rsqr2
400 costheta_il = f_il/g_il
402 SELECT CASE (nnp%cut_type)
404 arg_il = pi*r3/cutoff_s
405 fcut3_il = 0.5_dp*(cos(arg_il) + 1.0_dp)
406 dfcut3_il = -0.5_dp*sin(arg_il)*(pi/cutoff_s)
408 tanh_il = tanh(1.0_dp - r3/cutoff_s)
409 fcut3_il = tanh_il**3
410 dfcut3_il = (-3.0_dp/cutoff_s)*(tanh_il**2 - tanh_il**4)
412 cpabort(
"NNP| Cutoff function unknown")
415 ftot_il = fc_cache1(j)*fc_cache2(k)*fcut3_il
416 dfcutdr1_il = dfc_cache1(j)*fc_cache2(k)*fcut3_il
417 dfcutdr2_il = fc_cache1(j)*dfc_cache2(k)*fcut3_il
418 dfcutdr3_il = fc_cache1(j)*fc_cache2(k)*dfcut3_il
420 r1_inv = 1.0_dp/r1; r2_inv = 1.0_dp/r2; r3_inv = 1.0_dp/r3
421 dr1dx_il(:) = rvect1(:)*r1_inv
422 dr2dx_il(:) = rvect2(:)*r2_inv
423 dr3dx_il(:) = rvect3(:)*r3_inv
425 inv_g2_il = 1.0_dp/(g_il*g_il)
427 dgdx_t1 = 2.0_dp*r2*dr1dx_il(ii)
428 dgdx_t2 = 2.0_dp*r1*dr2dx_il(ii)
429 dcosbase1_il(ii) = -2.0_dp*(rvect1(ii) + rvect2(ii))*g_il &
430 - f_il*(-(dgdx_t1 + dgdx_t2))
431 dcosbase2_il(ii) = 2.0_dp*(rvect3(ii) + rvect1(ii))*g_il &
433 dcosbase3_il(ii) = 2.0_dp*(rvect2(ii) - rvect3(ii))*g_il &
439 m = off + grp_il%symf(sf)
440 lam_il = grp_il%pack_lam(sf)
441 zeta_il = grp_il%pack_zeta(sf)
442 eta_il = grp_il%pack_eta(sf)
443 prefzeta_il = grp_il%pack_prefzeta(sf)
445 tmp_il = 1.0_dp + lam_il*costheta_il
446 IF (tmp_il <= 0.0_dp)
THEN
450 IF (grp_il%pack_use_int_zeta(sf))
THEN
451 izeta_il = grp_il%pack_izeta(sf)
452 tmpzeta_il = tmp_il**(izeta_il - 1)
454 tmpzeta_il = tmp_il**(zeta_il - 1.0_dp)
456 angular_il = tmpzeta_il*tmp_il
459 symtmp_il = exp(-eta_il*r2sum_il)
460 sym_il = prefzeta_il*angular_il*symtmp_il*ftot_il
461 nnp%ang(ind)%y(m - off) = nnp%ang(ind)%y(m - off) + sym_il
463 pref_lam_il = zeta_il*tmpzeta_il*lam_il*inv_g2_il
464 tmp_il = -2.0_dp*symtmp_il*eta_il
465 dsymdr1_il = tmp_il*r1
466 dsymdr2_il = tmp_il*r2
467 dsymdr3_il = tmp_il*r3
469 pref_il = prefzeta_il*symtmp_il*ftot_il
470 tmp1_il = prefzeta_il*angular_il*(ftot_il*dsymdr1_il + dfcutdr1_il*symtmp_il)
471 tmp2_il = prefzeta_il*angular_il*(ftot_il*dsymdr2_il + dfcutdr2_il*symtmp_il)
472 tmp3_il = prefzeta_il*angular_il*(ftot_il*dsymdr3_il + dfcutdr3_il*symtmp_il)
475 f_jj_il(ii) = pref_il*pref_lam_il*dcosbase2_il(ii) &
476 - tmp1_il*dr1dx_il(ii) + tmp3_il*dr3dx_il(ii)
477 f_kk_il(ii) = pref_il*pref_lam_il*dcosbase3_il(ii) &
478 - tmp2_il*dr2dx_il(ii) - tmp3_il*dr3dx_il(ii)
479 self_dgdr(ii, m) = self_dgdr(ii, m) &
480 + pref_il*pref_lam_il*dcosbase1_il(ii) &
481 + tmp1_il*dr1dx_il(ii) + tmp2_il*dr2dx_il(ii)
482 jj_buf(ii, sf, j) = jj_buf(ii, sf, j) + f_jj_il(ii)
483 kk_buf(ii, sf, k) = kk_buf(ii, sf, k) + f_kk_il(ii)
485 IF (
PRESENT(stress))
THEN
487 stress(:, l, m) = stress(:, l, m) &
488 - rvect1(:)*f_jj_il(l) - rvect2(:)*f_kk_il(l)
500 CALL timestop(handle_sf)
503 CALL timeset(
'nnp_acsf_radial', handle_sf)
504 DO s = 1, nnp%rad(ind)%n_symfgrp
506 DO j = 1, neighbor%n_rad(s)
507 rvect1 = neighbor%rad(s)%dist(1:3, j)
508 r1 = neighbor%rad(s)%dist(4, j)
509 CALL nnp_calc_rad(nnp, ind, s, rvect1, r1, radial_symtmp(1:nnp%rad(ind)%symfgrp(s)%n_symf))
510 DO sf = 1, nnp%rad(ind)%symfgrp(s)%n_symf
511 m = nnp%rad(ind)%symfgrp(s)%symf(sf)
512 nnp%rad(ind)%y(m) = nnp%rad(ind)%y(m) + radial_symtmp(sf)
516 CALL timestop(handle_sf)
519 CALL timeset(
'nnp_acsf_angular', handle_sf)
521 DO s = 1, nnp%ang(ind)%n_symfgrp
522 cutoff_s = nnp%ang(ind)%symfgrp(s)%cutoff
523 cutoff_sqr = cutoff_s*cutoff_s
524 n_symf_s = nnp%ang(ind)%symfgrp(s)%n_symf
525 n_ang1_s = neighbor%n_ang1(s)
528 CALL nnp_fill_fc_cache(neighbor%ang1(s)%dist, n_ang1_s, &
529 nnp%cut_type, cutoff_s, fc_cache1)
531 IF (nnp%ang(ind)%symfgrp(s)%ele(1) == nnp%ang(ind)%symfgrp(s)%ele(2))
THEN
533 rvect1 = neighbor%ang1(s)%dist(1:3, j)
534 r1 = neighbor%ang1(s)%dist(4, j)
535 DO k = j + 1, n_ang1_s
536 rvect2 = neighbor%ang1(s)%dist(1:3, k)
537 r2 = neighbor%ang1(s)%dist(4, k)
538 rvect3(1) = rvect2(1) - rvect1(1)
539 rvect3(2) = rvect2(2) - rvect1(2)
540 rvect3(3) = rvect2(3) - rvect1(3)
541 r3_sqr = rvect3(1)*rvect3(1) + rvect3(2)*rvect3(2) + rvect3(3)*rvect3(3)
542 IF (r3_sqr < cutoff_sqr)
THEN
544 CALL nnp_calc_ang(nnp, ind, s, rvect1, rvect2, rvect3, r1, r2, r3, &
545 fc_cache1(j), 0.0_dp, fc_cache1(k), 0.0_dp, &
546 angular_symtmp(1:n_symf_s))
548 m = off + nnp%ang(ind)%symfgrp(s)%symf(sf)
549 nnp%ang(ind)%y(m - off) = nnp%ang(ind)%y(m - off) + angular_symtmp(sf)
556 n_ang2_s = neighbor%n_ang2(s)
557 CALL nnp_fill_fc_cache(neighbor%ang2(s)%dist, n_ang2_s, &
558 nnp%cut_type, cutoff_s, fc_cache2)
561 rvect1 = neighbor%ang1(s)%dist(1:3, j)
562 r1 = neighbor%ang1(s)%dist(4, j)
564 rvect2 = neighbor%ang2(s)%dist(1:3, k)
565 r2 = neighbor%ang2(s)%dist(4, k)
566 rvect3(1) = rvect2(1) - rvect1(1)
567 rvect3(2) = rvect2(2) - rvect1(2)
568 rvect3(3) = rvect2(3) - rvect1(3)
569 r3_sqr = rvect3(1)*rvect3(1) + rvect3(2)*rvect3(2) + rvect3(3)*rvect3(3)
570 IF (r3_sqr < cutoff_sqr)
THEN
572 CALL nnp_calc_ang(nnp, ind, s, rvect1, rvect2, rvect3, r1, r2, r3, &
573 fc_cache1(j), 0.0_dp, fc_cache2(k), 0.0_dp, &
574 angular_symtmp(1:n_symf_s))
576 m = off + nnp%ang(ind)%symfgrp(s)%symf(sf)
577 nnp%ang(ind)%y(m - off) = nnp%ang(ind)%y(m - off) + angular_symtmp(sf)
584 CALL timestop(handle_sf)
594 CALL nnp_check_extrapolation(nnp, ind)
596 IF (
PRESENT(stress))
THEN
597 CALL nnp_scale_acsf(nnp, ind, do_forces, stress)
599 CALL nnp_scale_acsf(nnp, ind, do_forces)
602 CALL timestop(handle)
616 PURE SUBROUTINE nnp_fill_fc_dfc_cache(dist, n, cut_type, cutoff_s, fc_cache, dfc_cache)
617 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: dist
618 INTEGER,
INTENT(IN) :: n, cut_type
619 REAL(kind=dp),
INTENT(IN) :: cutoff_s
620 REAL(kind=dp),
DIMENSION(:),
INTENT(OUT) :: fc_cache, dfc_cache
623 REAL(kind=dp) :: arg_tmp, r_tmp, tanh_tmp
627 SELECT CASE (cut_type)
629 arg_tmp = pi*r_tmp/cutoff_s
630 fc_cache(j) = 0.5_dp*(cos(arg_tmp) + 1.0_dp)
631 dfc_cache(j) = -0.5_dp*sin(arg_tmp)*(pi/cutoff_s)
633 tanh_tmp = tanh(1.0_dp - r_tmp/cutoff_s)
634 fc_cache(j) = tanh_tmp**3
635 dfc_cache(j) = (-3.0_dp/cutoff_s)*(tanh_tmp**2 - tanh_tmp**4)
639 END SUBROUTINE nnp_fill_fc_dfc_cache
650 PURE SUBROUTINE nnp_fill_fc_cache(dist, n, cut_type, cutoff_s, fc_cache)
651 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: dist
652 INTEGER,
INTENT(IN) :: n, cut_type
653 REAL(kind=dp),
INTENT(IN) :: cutoff_s
654 REAL(kind=dp),
DIMENSION(:),
INTENT(OUT) :: fc_cache
657 REAL(kind=dp) :: r_tmp, tanh_tmp
661 SELECT CASE (cut_type)
663 fc_cache(j) = 0.5_dp*(cos(pi*r_tmp/cutoff_s) + 1.0_dp)
665 tanh_tmp = tanh(1.0_dp - r_tmp/cutoff_s)
666 fc_cache(j) = tanh_tmp**3
670 END SUBROUTINE nnp_fill_fc_cache
685 SUBROUTINE nnp_acsf_angular_loop_omp(nnp, ind, self_dGdr, off, stress)
686 TYPE(nnp_type),
INTENT(INOUT),
POINTER :: nnp
687 INTEGER,
INTENT(IN) :: ind
688 REAL(kind=dp),
DIMENSION(:, :),
INTENT(INOUT) :: self_dgdr
689 INTEGER,
INTENT(IN) :: off
690 REAL(kind=dp),
DIMENSION(:, :, :),
INTENT(INOUT), &
693 INTEGER :: cache_cap_loc, j, k, l, m, &
694 max_ang_symf_loc, n_ang1_s, n_ang2_s, &
697 REAL(kind=dp) :: cutoff_s, cutoff_sqr, r1, r2, r3, r3_sqr
698 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: dfc_c1_loc, dfc_c2_loc, fc_c1_loc, &
700 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: force_loc
701 REAL(kind=dp),
DIMENSION(3) :: rvect1, rvect2, rvect3
708 associate(workspace => nnp%neighbor_interface_state%workspace(ind), &
709 neighbor => nnp%neighbor_interface_state%workspace(ind)%neighbor)
711 cache_cap_loc = max(1, workspace%cache_cap)
712 max_ang_symf_loc = max(1, workspace%max_ang_symf)
717 DO s = 1, nnp%ang(ind)%n_symfgrp
718 n_symf_s = nnp%ang(ind)%symfgrp(s)%n_symf
719 n_ang1_s = neighbor%n_ang1(s)
720 homo_grp = (nnp%ang(ind)%symfgrp(s)%ele(1) == nnp%ang(ind)%symfgrp(s)%ele(2))
721 CALL nnp_grp_grow_dgdr(workspace%dGdr_ang_jj(s), n_ang1_s)
723 CALL nnp_grp_grow_dgdr(workspace%dGdr_ang_kk(s), n_ang1_s)
726 n_ang2_s = neighbor%n_ang2(s)
727 CALL nnp_grp_grow_dgdr(workspace%dGdr_ang_kk(s), n_ang2_s)
729 IF (n_ang1_s > 0) workspace%dGdr_ang_jj(s)%data(:, 1:n_symf_s, 1:n_ang1_s) = 0.0_dp
731 IF (n_ang1_s > 0) workspace%dGdr_ang_kk(s)%data(:, 1:n_symf_s, 1:n_ang1_s) = 0.0_dp
733 IF (n_ang2_s > 0) workspace%dGdr_ang_kk(s)%data(:, 1:n_symf_s, 1:n_ang2_s) = 0.0_dp
753 ALLOCATE (fc_c1_loc(cache_cap_loc))
754 ALLOCATE (dfc_c1_loc(cache_cap_loc))
755 ALLOCATE (fc_c2_loc(cache_cap_loc))
756 ALLOCATE (dfc_c2_loc(cache_cap_loc))
757 ALLOCATE (sym_loc(max_ang_symf_loc))
758 ALLOCATE (force_loc(3, 3, max_ang_symf_loc))
761 DO s = 1, nnp%ang(ind)%n_symfgrp
762 cutoff_s = nnp%ang(ind)%symfgrp(s)%cutoff
763 cutoff_sqr = cutoff_s*cutoff_s
764 n_symf_s = nnp%ang(ind)%symfgrp(s)%n_symf
765 n_ang1_s = neighbor%n_ang1(s)
766 homo_grp = (nnp%ang(ind)%symfgrp(s)%ele(1) == nnp%ang(ind)%symfgrp(s)%ele(2))
768 CALL nnp_fill_fc_dfc_cache(neighbor%ang1(s)%dist, n_ang1_s, &
769 nnp%cut_type, cutoff_s, fc_c1_loc, dfc_c1_loc)
773 rvect1 = neighbor%ang1(s)%dist(1:3, j)
774 r1 = neighbor%ang1(s)%dist(4, j)
775 DO k = j + 1, n_ang1_s
776 rvect2 = neighbor%ang1(s)%dist(1:3, k)
777 r2 = neighbor%ang1(s)%dist(4, k)
778 rvect3(1) = rvect2(1) - rvect1(1)
779 rvect3(2) = rvect2(2) - rvect1(2)
780 rvect3(3) = rvect2(3) - rvect1(3)
781 r3_sqr = rvect3(1)*rvect3(1) + rvect3(2)*rvect3(2) + rvect3(3)*rvect3(3)
782 IF (r3_sqr < cutoff_sqr)
THEN
784 CALL nnp_calc_ang(nnp, ind, s, rvect1, rvect2, rvect3, &
786 fc_c1_loc(j), dfc_c1_loc(j), &
787 fc_c1_loc(k), dfc_c1_loc(k), &
788 sym_loc(1:n_symf_s), &
789 force_loc(:, :, 1:n_symf_s))
791 m = off + nnp%ang(ind)%symfgrp(s)%symf(sf)
792 self_dgdr(1, m) = self_dgdr(1, m) + force_loc(1, 1, sf)
793 self_dgdr(2, m) = self_dgdr(2, m) + force_loc(2, 1, sf)
794 self_dgdr(3, m) = self_dgdr(3, m) + force_loc(3, 1, sf)
795 workspace%dGdr_ang_jj(s)%data(1, sf, j) = workspace%dGdr_ang_jj(s)%data(1, sf, j) + force_loc(1, 2, sf)
796 workspace%dGdr_ang_jj(s)%data(2, sf, j) = workspace%dGdr_ang_jj(s)%data(2, sf, j) + force_loc(2, 2, sf)
797 workspace%dGdr_ang_jj(s)%data(3, sf, j) = workspace%dGdr_ang_jj(s)%data(3, sf, j) + force_loc(3, 2, sf)
798 workspace%dGdr_ang_kk(s)%data(1, sf, k) = workspace%dGdr_ang_kk(s)%data(1, sf, k) + force_loc(1, 3, sf)
799 workspace%dGdr_ang_kk(s)%data(2, sf, k) = workspace%dGdr_ang_kk(s)%data(2, sf, k) + force_loc(2, 3, sf)
800 workspace%dGdr_ang_kk(s)%data(3, sf, k) = workspace%dGdr_ang_kk(s)%data(3, sf, k) + force_loc(3, 3, sf)
801 IF (
PRESENT(stress))
THEN
803 stress(:, l, m) = stress(:, l, m) - rvect1(:)*force_loc(l, 2, sf)
804 stress(:, l, m) = stress(:, l, m) - rvect2(:)*force_loc(l, 3, sf)
807 nnp%ang(ind)%y(m - off) = nnp%ang(ind)%y(m - off) + sym_loc(sf)
813 n_ang2_s = neighbor%n_ang2(s)
814 CALL nnp_fill_fc_dfc_cache(neighbor%ang2(s)%dist, n_ang2_s, &
815 nnp%cut_type, cutoff_s, fc_c2_loc, dfc_c2_loc)
818 rvect1 = neighbor%ang1(s)%dist(1:3, j)
819 r1 = neighbor%ang1(s)%dist(4, j)
821 rvect2 = neighbor%ang2(s)%dist(1:3, k)
822 r2 = neighbor%ang2(s)%dist(4, k)
823 rvect3(1) = rvect2(1) - rvect1(1)
824 rvect3(2) = rvect2(2) - rvect1(2)
825 rvect3(3) = rvect2(3) - rvect1(3)
826 r3_sqr = rvect3(1)*rvect3(1) + rvect3(2)*rvect3(2) + rvect3(3)*rvect3(3)
827 IF (r3_sqr < cutoff_sqr)
THEN
829 CALL nnp_calc_ang(nnp, ind, s, rvect1, rvect2, rvect3, &
831 fc_c1_loc(j), dfc_c1_loc(j), &
832 fc_c2_loc(k), dfc_c2_loc(k), &
833 sym_loc(1:n_symf_s), &
834 force_loc(:, :, 1:n_symf_s))
836 m = off + nnp%ang(ind)%symfgrp(s)%symf(sf)
837 self_dgdr(1, m) = self_dgdr(1, m) + force_loc(1, 1, sf)
838 self_dgdr(2, m) = self_dgdr(2, m) + force_loc(2, 1, sf)
839 self_dgdr(3, m) = self_dgdr(3, m) + force_loc(3, 1, sf)
840 workspace%dGdr_ang_jj(s)%data(1, sf, j) = workspace%dGdr_ang_jj(s)%data(1, sf, j) + force_loc(1, 2, sf)
841 workspace%dGdr_ang_jj(s)%data(2, sf, j) = workspace%dGdr_ang_jj(s)%data(2, sf, j) + force_loc(2, 2, sf)
842 workspace%dGdr_ang_jj(s)%data(3, sf, j) = workspace%dGdr_ang_jj(s)%data(3, sf, j) + force_loc(3, 2, sf)
843 workspace%dGdr_ang_kk(s)%data(1, sf, k) = workspace%dGdr_ang_kk(s)%data(1, sf, k) + force_loc(1, 3, sf)
844 workspace%dGdr_ang_kk(s)%data(2, sf, k) = workspace%dGdr_ang_kk(s)%data(2, sf, k) + force_loc(2, 3, sf)
845 workspace%dGdr_ang_kk(s)%data(3, sf, k) = workspace%dGdr_ang_kk(s)%data(3, sf, k) + force_loc(3, 3, sf)
846 IF (
PRESENT(stress))
THEN
848 stress(:, l, m) = stress(:, l, m) - rvect1(:)*force_loc(l, 2, sf)
849 stress(:, l, m) = stress(:, l, m) - rvect2(:)*force_loc(l, 3, sf)
852 nnp%ang(ind)%y(m - off) = nnp%ang(ind)%y(m - off) + sym_loc(sf)
861 DEALLOCATE (fc_c1_loc, dfc_c1_loc, fc_c2_loc, dfc_c2_loc, sym_loc, force_loc)
866 END SUBROUTINE nnp_acsf_angular_loop_omp
880 TYPE(nnp_type),
INTENT(INOUT),
POINTER :: nnp
882 IF (.NOT.
ALLOCATED(nnp%cell_list_cache))
ALLOCATE (nnp%cell_list_cache)
883 IF (.NOT.
ALLOCATED(nnp%neighbor_interface_state))
ALLOCATE (nnp%neighbor_interface_state)
884 CALL nnp_prepare_cell_list_cache(nnp)
885 CALL nnp_neighbor_interface_prepare(nnp)
896 SUBROUTINE nnp_check_extrapolation(nnp, ind)
898 TYPE(nnp_type),
INTENT(INOUT) :: nnp
899 INTEGER,
INTENT(IN) :: ind
901 REAL(kind=dp),
PARAMETER :: threshold = 0.0001_dp
904 LOGICAL :: extrapolate
906 extrapolate = nnp%output_expol
908 DO j = 1, nnp%n_rad(ind)
909 IF (nnp%rad(ind)%y(j) - nnp%rad(ind)%loc_max(j) > threshold)
THEN
911 ELSE IF (-nnp%rad(ind)%y(j) + nnp%rad(ind)%loc_min(j) > threshold)
THEN
915 DO j = 1, nnp%n_ang(ind)
916 IF (nnp%ang(ind)%y(j) - nnp%ang(ind)%loc_max(j) > threshold)
THEN
918 ELSE IF (-nnp%ang(ind)%y(j) + nnp%ang(ind)%loc_min(j) > threshold)
THEN
923 nnp%output_expol = extrapolate
925 END SUBROUTINE nnp_check_extrapolation
936 SUBROUTINE nnp_scale_acsf(nnp, ind, do_forces, stress)
938 TYPE(nnp_type),
INTENT(INOUT) :: nnp
939 INTEGER,
INTENT(IN) :: ind
940 LOGICAL,
INTENT(IN) :: do_forces
941 REAL(kind=dp),
DIMENSION(:, :, :),
INTENT(INOUT), &
944 INTEGER :: j, k, m, n_ang1_s, n_ang2_s, n_symf_s, &
947 REAL(kind=dp) :: scale
951 IF (nnp%center_acsf)
THEN
952 DO j = 1, nnp%n_rad(ind)
953 nnp%arc(ind)%layer(1)%node(j) = nnp%rad(ind)%y(j) - nnp%rad(ind)%loc_av(j)
956 DO j = 1, nnp%n_ang(ind)
957 nnp%arc(ind)%layer(1)%node(j + off) = nnp%ang(ind)%y(j) - nnp%ang(ind)%loc_av(j)
960 IF (nnp%scale_acsf)
THEN
961 DO j = 1, nnp%n_rad(ind)
962 nnp%arc(ind)%layer(1)%node(j) = nnp%arc(ind)%layer(1)%node(j)/ &
963 (nnp%rad(ind)%loc_max(j) - nnp%rad(ind)%loc_min(j))*(nnp%scmax - nnp%scmin) + nnp%scmin
966 DO j = 1, nnp%n_ang(ind)
967 nnp%arc(ind)%layer(1)%node(j + off) = nnp%arc(ind)%layer(1)%node(j + off)/ &
968 (nnp%ang(ind)%loc_max(j) - nnp%ang(ind)%loc_min(j))*(nnp%scmax - nnp%scmin) + nnp%scmin
971 ELSE IF (nnp%scale_acsf)
THEN
972 DO j = 1, nnp%n_rad(ind)
973 nnp%arc(ind)%layer(1)%node(j) = (nnp%rad(ind)%y(j) - nnp%rad(ind)%loc_min(j))/ &
974 (nnp%rad(ind)%loc_max(j) - nnp%rad(ind)%loc_min(j))* &
975 (nnp%scmax - nnp%scmin) + nnp%scmin
978 DO j = 1, nnp%n_ang(ind)
979 nnp%arc(ind)%layer(1)%node(j + off) = (nnp%ang(ind)%y(j) - nnp%ang(ind)%loc_min(j))/ &
980 (nnp%ang(ind)%loc_max(j) - nnp%ang(ind)%loc_min(j))* &
981 (nnp%scmax - nnp%scmin) + nnp%scmin
983 ELSE IF (nnp%scale_sigma_acsf)
THEN
984 DO j = 1, nnp%n_rad(ind)
985 nnp%arc(ind)%layer(1)%node(j) = (nnp%rad(ind)%y(j) - nnp%rad(ind)%loc_av(j))/ &
986 nnp%rad(ind)%sigma(j)*(nnp%scmax - nnp%scmin) + nnp%scmin
989 DO j = 1, nnp%n_ang(ind)
990 nnp%arc(ind)%layer(1)%node(j + off) = (nnp%ang(ind)%y(j) - nnp%ang(ind)%loc_av(j))/ &
991 nnp%ang(ind)%sigma(j)*(nnp%scmax - nnp%scmin) + nnp%scmin
994 DO j = 1, nnp%n_rad(ind)
995 nnp%arc(ind)%layer(1)%node(j) = nnp%rad(ind)%y(j)
998 DO j = 1, nnp%n_ang(ind)
999 nnp%arc(ind)%layer(1)%node(j + off) = nnp%ang(ind)%y(j)
1003 IF (do_forces .AND. (nnp%scale_acsf .OR. nnp%scale_sigma_acsf))
THEN
1009 associate(workspace => nnp%neighbor_interface_state%workspace(ind), &
1010 neighbor => nnp%neighbor_interface_state%workspace(ind)%neighbor, &
1011 self_dgdr => nnp%neighbor_interface_state%workspace(ind)%self_dGdr)
1014 DO s = 1, nnp%rad(ind)%n_symfgrp
1015 n_symf_s = nnp%rad(ind)%symfgrp(s)%n_symf
1016 associate(rad_buf => workspace%dGdr_rad(s)%data)
1018 m = nnp%rad(ind)%symfgrp(s)%symf(sf)
1019 IF (nnp%scale_acsf)
THEN
1020 scale = (nnp%scmax - nnp%scmin)/ &
1021 (nnp%rad(ind)%loc_max(m) - nnp%rad(ind)%loc_min(m))
1023 scale = (nnp%scmax - nnp%scmin)/nnp%rad(ind)%sigma(m)
1025 self_dgdr(1, m) = self_dgdr(1, m)*scale
1026 self_dgdr(2, m) = self_dgdr(2, m)*scale
1027 self_dgdr(3, m) = self_dgdr(3, m)*scale
1028 DO j = 1, neighbor%n_rad(s)
1029 rad_buf(1, sf, j) = rad_buf(1, sf, j)*scale
1030 rad_buf(2, sf, j) = rad_buf(2, sf, j)*scale
1031 rad_buf(3, sf, j) = rad_buf(3, sf, j)*scale
1038 off = nnp%n_rad(ind)
1039 DO s = 1, nnp%ang(ind)%n_symfgrp
1040 n_symf_s = nnp%ang(ind)%symfgrp(s)%n_symf
1041 n_ang1_s = neighbor%n_ang1(s)
1042 homo_grp = (nnp%ang(ind)%symfgrp(s)%ele(1) == nnp%ang(ind)%symfgrp(s)%ele(2))
1047 n_ang2_s = neighbor%n_ang2(s)
1049 associate(jj_buf => workspace%dGdr_ang_jj(s)%data, &
1050 kk_buf => workspace%dGdr_ang_kk(s)%data)
1052 m = off + nnp%ang(ind)%symfgrp(s)%symf(sf)
1053 IF (nnp%scale_acsf)
THEN
1054 scale = (nnp%scmax - nnp%scmin)/ &
1055 (nnp%ang(ind)%loc_max(m - off) - nnp%ang(ind)%loc_min(m - off))
1057 scale = (nnp%scmax - nnp%scmin)/nnp%ang(ind)%sigma(m - off)
1059 self_dgdr(1, m) = self_dgdr(1, m)*scale
1060 self_dgdr(2, m) = self_dgdr(2, m)*scale
1061 self_dgdr(3, m) = self_dgdr(3, m)*scale
1063 jj_buf(1, sf, j) = jj_buf(1, sf, j)*scale
1064 jj_buf(2, sf, j) = jj_buf(2, sf, j)*scale
1065 jj_buf(3, sf, j) = jj_buf(3, sf, j)*scale
1068 kk_buf(1, sf, k) = kk_buf(1, sf, k)*scale
1069 kk_buf(2, sf, k) = kk_buf(2, sf, k)*scale
1070 kk_buf(3, sf, k) = kk_buf(3, sf, k)*scale
1079 IF (
PRESENT(stress))
THEN
1080 IF (nnp%scale_acsf)
THEN
1081 DO j = 1, nnp%n_rad(ind)
1082 stress(:, :, j) = stress(:, :, j)/(nnp%rad(ind)%loc_max(j) - nnp%rad(ind)%loc_min(j))* &
1083 (nnp%scmax - nnp%scmin)
1085 off = nnp%n_rad(ind)
1086 DO j = 1, nnp%n_ang(ind)
1087 stress(:, :, j + off) = stress(:, :, j + off)/ &
1088 (nnp%ang(ind)%loc_max(j) - nnp%ang(ind)%loc_min(j))* &
1089 (nnp%scmax - nnp%scmin)
1091 ELSE IF (nnp%scale_sigma_acsf)
THEN
1092 DO j = 1, nnp%n_rad(ind)
1093 stress(:, :, j) = stress(:, :, j)/nnp%rad(ind)%sigma(j)*(nnp%scmax - nnp%scmin)
1095 off = nnp%n_rad(ind)
1096 DO j = 1, nnp%n_ang(ind)
1097 stress(:, :, j + off) = stress(:, :, j + off)/nnp%ang(ind)%sigma(j)*(nnp%scmax - nnp%scmin)
1102 END SUBROUTINE nnp_scale_acsf
1116 SUBROUTINE nnp_calc_rad(nnp, ind, s, rvect, r, sym, force)
1118 TYPE(nnp_type),
INTENT(IN),
TARGET :: nnp
1119 INTEGER,
INTENT(IN) :: ind, s
1120 REAL(kind=dp),
DIMENSION(3),
INTENT(IN) :: rvect
1121 REAL(kind=dp),
INTENT(IN) :: r
1122 REAL(kind=dp),
DIMENSION(:),
INTENT(OUT) :: sym
1123 REAL(kind=dp),
DIMENSION(:, :),
INTENT(OUT), &
1126 INTEGER :: i, n_symf, sf
1127 REAL(kind=dp) :: dh00, dh01, dh10, dh11, drdx_x, drdx_y, &
1128 drdx_z, dsymdr_full, dyi, dyi1, h00, &
1129 h01, h10, h10_dx, h11, h11_dx, r_inv, &
1131 TYPE(nnp_symfgrp_type),
POINTER :: grp
1133 grp => nnp%rad(ind)%symfgrp(s)
1144 IF (r >= grp%spline_x_max)
THEN
1148 IF (
PRESENT(force))
THEN
1150 force(1, sf) = 0.0_dp
1151 force(2, sf) = 0.0_dp
1152 force(3, sf) = 0.0_dp
1158 i = int(r*grp%spline_dx_inv) + 1
1160 IF (i > grp%spline_n - 1) i = grp%spline_n - 1
1162 t = (r - real(i - 1, kind=dp)*grp%spline_dx)*grp%spline_dx_inv
1166 h00 = 2.0_dp*t3 - 3.0_dp*t2 + 1.0_dp
1167 h10 = t3 - 2.0_dp*t2 + t
1168 h01 = -2.0_dp*t3 + 3.0_dp*t2
1170 h10_dx = h10*grp%spline_dx
1171 h11_dx = h11*grp%spline_dx
1173 IF (
PRESENT(force))
THEN
1174 dh00 = 6.0_dp*(t2 - t)
1175 dh10 = 3.0_dp*t2 - 4.0_dp*t + 1.0_dp
1177 dh11 = 3.0_dp*t2 - 2.0_dp*t
1180 drdx_x = rvect(1)*r_inv
1181 drdx_y = rvect(2)*r_inv
1182 drdx_z = rvect(3)*r_inv
1186 associate(spy_i => grp%spline_y(:, i), spy_i1 => grp%spline_y(:, i + 1), &
1187 spdy_i => grp%spline_dy(:, i), spdy_i1 => grp%spline_dy(:, i + 1))
1194 sym(sf) = h00*yi + h10_dx*dyi + h01*yi1 + h11_dx*dyi1
1195 dsymdr_full = (dh00*yi + dh01*yi1)*grp%spline_dx_inv + dh10*dyi + dh11*dyi1
1196 force(1, sf) = dsymdr_full*drdx_x
1197 force(2, sf) = dsymdr_full*drdx_y
1198 force(3, sf) = dsymdr_full*drdx_z
1202 associate(spy_i => grp%spline_y(:, i), spy_i1 => grp%spline_y(:, i + 1), &
1203 spdy_i => grp%spline_dy(:, i), spdy_i1 => grp%spline_dy(:, i + 1))
1206 sym(sf) = h00*spy_i(sf) + h10_dx*spdy_i(sf) + &
1207 h01*spy_i1(sf) + h11_dx*spdy_i1(sf)
1212 END SUBROUTINE nnp_calc_rad
1220 SUBROUTINE nnp_build_radial_splines(nnp)
1222 TYPE(nnp_type),
INTENT(INOUT),
POINTER :: nnp
1224 CHARACTER(len=*),
PARAMETER :: routinen =
'nnp_build_radial_splines'
1226 INTEGER :: handle, ind, k, n_symf, p, s, sf
1227 REAL(kind=dp) :: arg, cutoff, dfcutdr, dr, eta, exp_term, &
1228 fcut, r, rs, tanh_tmp
1230 CALL timeset(routinen, handle)
1232 DO ind = 1, nnp%n_ele
1233 DO s = 1, nnp%rad(ind)%n_symfgrp
1234 associate(grp => nnp%rad(ind)%symfgrp(s))
1237 dr = cutoff/real(nnp%rad_spline_n - 1, kind=dp)
1239 IF (
ALLOCATED(grp%spline_y))
DEALLOCATE (grp%spline_y)
1240 IF (
ALLOCATED(grp%spline_dy))
DEALLOCATE (grp%spline_dy)
1241 ALLOCATE (grp%spline_y(max(1, n_symf), nnp%rad_spline_n))
1242 ALLOCATE (grp%spline_dy(max(1, n_symf), nnp%rad_spline_n))
1243 grp%spline_n = nnp%rad_spline_n
1245 grp%spline_dx_inv = 1.0_dp/dr
1246 grp%spline_x_max = cutoff
1252 eta = nnp%rad(ind)%eta(k)
1253 rs = nnp%rad(ind)%rs(k)
1255 DO p = 1, nnp%rad_spline_n
1256 r = real(p - 1, kind=dp)*dr
1258 SELECT CASE (nnp%cut_type)
1261 fcut = 0.5_dp*(cos(arg) + 1.0_dp)
1262 dfcutdr = -0.5_dp*sin(arg)*(pi/cutoff)
1264 tanh_tmp = tanh(1.0_dp - r/cutoff)
1266 dfcutdr = (-3.0_dp/cutoff)*(tanh_tmp**2 - tanh_tmp**4)
1268 cpabort(
"NNP| Cutoff function unknown")
1271 exp_term = exp(-eta*(r - rs)**2)
1273 grp%spline_y(sf, p) = exp_term*fcut
1274 grp%spline_dy(sf, p) = exp_term*(-2.0_dp*eta*(r - rs))*fcut + &
1282 grp%spline_y(sf, nnp%rad_spline_n) = 0.0_dp
1283 grp%spline_dy(sf, nnp%rad_spline_n) = 0.0_dp
1286 grp%spline_built = .true.
1291 CALL timestop(handle)
1293 END SUBROUTINE nnp_build_radial_splines
1336 SUBROUTINE nnp_calc_ang(nnp, ind, s, rvect1, rvect2, rvect3, r1, r2, r3, &
1337 fcut_j, dfcut_j, fcut_k, dfcut_k, sym, force)
1339 TYPE(nnp_type),
INTENT(IN),
TARGET :: nnp
1340 INTEGER,
INTENT(IN) :: ind, s
1341 REAL(kind=dp),
DIMENSION(3),
INTENT(IN) :: rvect1, rvect2, rvect3
1342 REAL(kind=dp),
INTENT(IN) :: r1, r2, r3, fcut_j, dfcut_j, fcut_k, &
1344 REAL(kind=dp),
DIMENSION(:),
INTENT(OUT) :: sym
1345 REAL(kind=dp),
DIMENSION(:, :, :),
INTENT(OUT), &
1348 INTEGER :: ii, izeta, n_symf, sf
1349 LOGICAL :: do_forces
1350 REAL(kind=dp) :: angular, arg_tmp, costheta, dfcut3, dfcutdr1, dfcutdr2, dfcutdr3, dsymdr1, &
1351 dsymdr2, dsymdr3, eta, f, fcut3, fcut_rc, ftot, g, inv_g2, lam, pref_lam, prefzeta, &
1352 r2sum, rsqr1, rsqr2, rsqr3, symtmp, tanh_tmp, tmp, tmp1, tmp2, tmp3, tmpzeta, zeta
1353 REAL(kind=dp),
DIMENSION(3) :: dcosbase1, dcosbase2, dcosbase3, dgdx1, &
1354 dgdx2, dgdx3, dr1dx, dr2dx, dr3dx
1355 TYPE(nnp_symfgrp_type),
POINTER :: grp
1357 DIMENSION(nnp%ang(ind)%symfgrp(s)%n_symf) :: angular_arr, symtmp_arr, tmpzeta_arr
1364 do_forces =
PRESENT(force)
1365 grp => nnp%ang(ind)%symfgrp(s)
1367 fcut_rc = grp%cutoff
1372 r2sum = rsqr1 + rsqr2 + rsqr3
1374 f = rsqr3 - rsqr1 - rsqr2
1379 SELECT CASE (nnp%cut_type)
1381 arg_tmp = pi*r3/fcut_rc
1382 fcut3 = 0.5_dp*(cos(arg_tmp) + 1.0_dp)
1383 IF (do_forces) dfcut3 = -0.5_dp*sin(arg_tmp)*(pi/fcut_rc)
1385 tanh_tmp = tanh(1.0_dp - r3/fcut_rc)
1387 IF (do_forces) dfcut3 = (-3.0_dp/fcut_rc)*(tanh_tmp**2 - tanh_tmp**4)
1389 cpabort(
"NNP| Cutoff function unknown")
1393 ftot = fcut_j*fcut_k*fcut3
1397 dfcutdr1 = dfcut_j*fcut_k*fcut3
1398 dfcutdr2 = fcut_j*dfcut_k*fcut3
1399 dfcutdr3 = fcut_j*fcut_k*dfcut3
1401 dr1dx(:) = rvect1(:)/r1
1402 dr2dx(:) = rvect2(:)/r2
1403 dr3dx(:) = rvect3(:)/r3
1409 inv_g2 = 1.0_dp/(g*g)
1411 tmp1 = 2.0_dp*r2*dr1dx(ii)
1412 tmp2 = 2.0_dp*r1*dr2dx(ii)
1413 dgdx1(ii) = -(tmp1 + tmp2)
1417 dcosbase1(ii) = -2.0_dp*(rvect1(ii) + rvect2(ii))*g - f*dgdx1(ii)
1418 dcosbase2(ii) = 2.0_dp*(rvect3(ii) + rvect1(ii))*g - f*dgdx2(ii)
1419 dcosbase3(ii) = 2.0_dp*(rvect2(ii) - rvect3(ii))*g - f*dgdx3(ii)
1427 tmp = 1.0_dp + grp%pack_lam(sf)*costheta
1428 IF (tmp <= 0.0_dp)
THEN
1429 tmpzeta_arr(sf) = 0.0_dp
1430 angular_arr(sf) = 0.0_dp
1432 IF (grp%pack_use_int_zeta(sf))
THEN
1433 izeta = grp%pack_izeta(sf)
1434 tmpzeta_arr(sf) = tmp**(izeta - 1)
1436 tmpzeta_arr(sf) = tmp**(grp%pack_zeta(sf) - 1.0_dp)
1438 angular_arr(sf) = tmpzeta_arr(sf)*tmp
1450 symtmp_arr(sf) = exp(-grp%pack_eta(sf)*r2sum)
1456 sym(sf) = grp%pack_prefzeta(sf)*angular_arr(sf)*symtmp_arr(sf)*ftot
1462 symtmp = symtmp_arr(sf)
1463 angular = angular_arr(sf)
1464 tmpzeta = tmpzeta_arr(sf)
1465 eta = grp%pack_eta(sf)
1466 lam = grp%pack_lam(sf)
1467 zeta = grp%pack_zeta(sf)
1468 prefzeta = grp%pack_prefzeta(sf)
1472 pref_lam = zeta*tmpzeta*lam*inv_g2
1474 tmp = -2.0_dp*symtmp*eta
1479 tmp = prefzeta*symtmp*ftot
1480 tmp1 = prefzeta*angular*(ftot*dsymdr1 + dfcutdr1*symtmp)
1481 tmp2 = prefzeta*angular*(ftot*dsymdr2 + dfcutdr2*symtmp)
1482 tmp3 = prefzeta*angular*(ftot*dsymdr3 + dfcutdr3*symtmp)
1484 force(ii, 1, sf) = tmp*pref_lam*dcosbase1(ii) + tmp1*dr1dx(ii) + tmp2*dr2dx(ii)
1485 force(ii, 2, sf) = tmp*pref_lam*dcosbase2(ii) - tmp1*dr1dx(ii) + tmp3*dr3dx(ii)
1486 force(ii, 3, sf) = tmp*pref_lam*dcosbase3(ii) - tmp2*dr2dx(ii) - tmp3*dr3dx(ii)
1491 END SUBROUTINE nnp_calc_ang
1503 CHARACTER(len=2),
DIMENSION(:),
INTENT(INOUT) :: ele
1504 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: nuc_ele
1506 CHARACTER(len=2) :: tmp_ele
1507 INTEGER :: i, j, loc, minimum, tmp_nuc_ele
1510 CALL get_ptable_info(ele(i), number=nuc_ele(i))
1513 DO i = 1,
SIZE(ele) - 1
1514 minimum = nuc_ele(i)
1516 DO j = i + 1,
SIZE(ele)
1517 IF (nuc_ele(j) < minimum)
THEN
1519 minimum = nuc_ele(j)
1522 tmp_nuc_ele = nuc_ele(i)
1523 nuc_ele(i) = nuc_ele(loc)
1524 nuc_ele(loc) = tmp_nuc_ele
1542 TYPE(nnp_type),
INTENT(INOUT) :: nnp
1544 INTEGER :: i, j, k, loc
1547 DO j = 1, nnp%n_rad(i) - 1
1549 DO k = j + 1, nnp%n_rad(i)
1550 IF (nnp%rad(i)%funccut(loc) > nnp%rad(i)%funccut(k))
THEN
1554 CALL nnp_swaprad(nnp%rad(i), j, loc)
1557 DO j = 1, nnp%n_rad(i) - 1
1559 DO k = j + 1, nnp%n_rad(i)
1560 IF (nnp%rad(i)%funccut(loc) == nnp%rad(i)%funccut(k) .AND. &
1561 nnp%rad(i)%eta(loc) > nnp%rad(i)%eta(k))
THEN
1565 CALL nnp_swaprad(nnp%rad(i), j, loc)
1568 DO j = 1, nnp%n_rad(i) - 1
1570 DO k = j + 1, nnp%n_rad(i)
1571 IF (nnp%rad(i)%funccut(loc) == nnp%rad(i)%funccut(k) .AND. &
1572 nnp%rad(i)%eta(loc) == nnp%rad(i)%eta(k) .AND. &
1573 nnp%rad(i)%rs(loc) > nnp%rad(i)%rs(k))
THEN
1577 CALL nnp_swaprad(nnp%rad(i), j, loc)
1580 DO j = 1, nnp%n_rad(i) - 1
1582 DO k = j + 1, nnp%n_rad(i)
1583 IF (nnp%rad(i)%funccut(loc) == nnp%rad(i)%funccut(k) .AND. &
1584 nnp%rad(i)%eta(loc) == nnp%rad(i)%eta(k) .AND. &
1585 nnp%rad(i)%rs(loc) == nnp%rad(i)%rs(k) .AND. &
1586 nnp%rad(i)%nuc_ele(loc) > nnp%rad(i)%nuc_ele(k))
THEN
1590 CALL nnp_swaprad(nnp%rad(i), j, loc)
1593 DO j = 1, nnp%n_ang(i) - 1
1595 DO k = j + 1, nnp%n_ang(i)
1596 IF (nnp%ang(i)%funccut(loc) > nnp%ang(i)%funccut(k))
THEN
1600 CALL nnp_swapang(nnp%ang(i), j, loc)
1603 DO j = 1, nnp%n_ang(i) - 1
1605 DO k = j + 1, nnp%n_ang(i)
1606 IF (nnp%ang(i)%funccut(loc) == nnp%ang(i)%funccut(k) .AND. &
1607 nnp%ang(i)%eta(loc) > nnp%ang(i)%eta(k))
THEN
1611 CALL nnp_swapang(nnp%ang(i), j, loc)
1614 DO j = 1, nnp%n_ang(i) - 1
1616 DO k = j + 1, nnp%n_ang(i)
1617 IF (nnp%ang(i)%funccut(loc) == nnp%ang(i)%funccut(k) .AND. &
1618 nnp%ang(i)%eta(loc) == nnp%ang(i)%eta(k) .AND. &
1619 nnp%ang(i)%zeta(loc) > nnp%ang(i)%zeta(k))
THEN
1623 CALL nnp_swapang(nnp%ang(i), j, loc)
1626 DO j = 1, nnp%n_ang(i) - 1
1628 DO k = j + 1, nnp%n_ang(i)
1629 IF (nnp%ang(i)%funccut(loc) == nnp%ang(i)%funccut(k) .AND. &
1630 nnp%ang(i)%eta(loc) == nnp%ang(i)%eta(k) .AND. &
1631 nnp%ang(i)%zeta(loc) == nnp%ang(i)%zeta(k) .AND. &
1632 nnp%ang(i)%lam(loc) > nnp%ang(i)%lam(k))
THEN
1636 CALL nnp_swapang(nnp%ang(i), j, loc)
1639 DO j = 1, nnp%n_ang(i) - 1
1641 DO k = j + 1, nnp%n_ang(i)
1642 IF (nnp%ang(i)%funccut(loc) == nnp%ang(i)%funccut(k) .AND. &
1643 nnp%ang(i)%eta(loc) == nnp%ang(i)%eta(k) .AND. &
1644 nnp%ang(i)%zeta(loc) == nnp%ang(i)%zeta(k) .AND. &
1645 nnp%ang(i)%lam(loc) == nnp%ang(i)%lam(k) .AND. &
1646 nnp%ang(i)%nuc_ele1(loc) > nnp%ang(i)%nuc_ele1(k))
THEN
1650 CALL nnp_swapang(nnp%ang(i), j, loc)
1653 DO j = 1, nnp%n_ang(i) - 1
1655 DO k = j + 1, nnp%n_ang(i)
1656 IF (nnp%ang(i)%funccut(loc) == nnp%ang(i)%funccut(k) .AND. &
1657 nnp%ang(i)%eta(loc) == nnp%ang(i)%eta(k) .AND. &
1658 nnp%ang(i)%zeta(loc) == nnp%ang(i)%zeta(k) .AND. &
1659 nnp%ang(i)%lam(loc) == nnp%ang(i)%lam(k) .AND. &
1660 nnp%ang(i)%nuc_ele1(loc) == nnp%ang(i)%nuc_ele1(k) .AND. &
1661 nnp%ang(i)%nuc_ele2(loc) > nnp%ang(i)%nuc_ele2(k))
THEN
1665 CALL nnp_swapang(nnp%ang(i), j, loc)
1679 SUBROUTINE nnp_swaprad(rad, i, j)
1680 TYPE(nnp_acsf_rad_type),
INTENT(INOUT) :: rad
1681 INTEGER,
INTENT(IN) :: i, j
1683 CHARACTER(len=2) :: tmpc
1685 REAL(kind=dp) :: tmpr
1687 tmpr = rad%funccut(i)
1688 rad%funccut(i) = rad%funccut(j)
1689 rad%funccut(j) = tmpr
1692 rad%eta(i) = rad%eta(j)
1696 rad%rs(i) = rad%rs(j)
1700 rad%ele(i) = rad%ele(j)
1703 tmpi = rad%nuc_ele(i)
1704 rad%nuc_ele(i) = rad%nuc_ele(j)
1705 rad%nuc_ele(j) = tmpi
1707 END SUBROUTINE nnp_swaprad
1717 SUBROUTINE nnp_swapang(ang, i, j)
1718 TYPE(nnp_acsf_ang_type),
INTENT(INOUT) :: ang
1719 INTEGER,
INTENT(IN) :: i, j
1721 CHARACTER(len=2) :: tmpc
1723 REAL(kind=dp) :: tmpr
1725 tmpr = ang%funccut(i)
1726 ang%funccut(i) = ang%funccut(j)
1727 ang%funccut(j) = tmpr
1730 ang%eta(i) = ang%eta(j)
1734 ang%zeta(i) = ang%zeta(j)
1737 tmpr = ang%prefzeta(i)
1738 ang%prefzeta(i) = ang%prefzeta(j)
1739 ang%prefzeta(j) = tmpr
1742 ang%lam(i) = ang%lam(j)
1746 ang%ele1(i) = ang%ele1(j)
1749 tmpi = ang%nuc_ele1(i)
1750 ang%nuc_ele1(i) = ang%nuc_ele1(j)
1751 ang%nuc_ele1(j) = tmpi
1754 ang%ele2(i) = ang%ele2(j)
1757 tmpi = ang%nuc_ele2(i)
1758 ang%nuc_ele2(i) = ang%nuc_ele2(j)
1759 ang%nuc_ele2(j) = tmpi
1761 END SUBROUTINE nnp_swapang
1775 TYPE(nnp_type),
INTENT(INOUT) :: nnp
1777 INTEGER :: ang, i, izeta_tmp, j, k, m, n_symf, rad, &
1779 REAL(kind=dp) :: eta_tmp, funccut, zeta_tmp
1782 nnp%rad(i)%n_symfgrp = 0
1783 nnp%ang(i)%n_symfgrp = 0
1786 DO s = 1, nnp%n_rad(i)
1787 IF (nnp%rad(i)%ele(s) == nnp%ele(j))
THEN
1788 IF (abs(nnp%rad(i)%funccut(s) - funccut) > cutoff_eq_tol)
THEN
1789 nnp%rad(i)%n_symfgrp = nnp%rad(i)%n_symfgrp + 1
1790 funccut = nnp%rad(i)%funccut(s)
1798 DO s = 1, nnp%n_ang(i)
1799 IF ((nnp%ang(i)%ele1(s) == nnp%ele(j) .AND. &
1800 nnp%ang(i)%ele2(s) == nnp%ele(k)) .OR. &
1801 (nnp%ang(i)%ele1(s) == nnp%ele(k) .AND. &
1802 nnp%ang(i)%ele2(s) == nnp%ele(j)))
THEN
1803 IF (abs(nnp%ang(i)%funccut(s) - funccut) > cutoff_eq_tol)
THEN
1804 nnp%ang(i)%n_symfgrp = nnp%ang(i)%n_symfgrp + 1
1805 funccut = nnp%ang(i)%funccut(s)
1814 ALLOCATE (nnp%rad(i)%symfgrp(nnp%rad(i)%n_symfgrp))
1815 ALLOCATE (nnp%ang(i)%symfgrp(nnp%ang(i)%n_symfgrp))
1816 DO j = 1, nnp%rad(i)%n_symfgrp
1817 nnp%rad(i)%symfgrp(j)%n_symf = 0
1819 DO j = 1, nnp%ang(i)%n_symfgrp
1820 nnp%ang(i)%symfgrp(j)%n_symf = 0
1829 DO s = 1, nnp%n_rad(i)
1830 IF (nnp%rad(i)%ele(s) == nnp%ele(j))
THEN
1831 IF (abs(nnp%rad(i)%funccut(s) - funccut) > cutoff_eq_tol)
THEN
1833 funccut = nnp%rad(i)%funccut(s)
1834 nnp%rad(i)%symfgrp(rad)%cutoff = funccut
1835 ALLOCATE (nnp%rad(i)%symfgrp(rad)%ele(1))
1836 ALLOCATE (nnp%rad(i)%symfgrp(rad)%ele_ind(1))
1837 nnp%rad(i)%symfgrp(rad)%ele(1) = nnp%ele(j)
1838 nnp%rad(i)%symfgrp(rad)%ele_ind(1) = j
1840 nnp%rad(i)%symfgrp(rad)%n_symf = nnp%rad(i)%symfgrp(rad)%n_symf + 1
1847 DO s = 1, nnp%n_ang(i)
1848 IF ((nnp%ang(i)%ele1(s) == nnp%ele(j) .AND. &
1849 nnp%ang(i)%ele2(s) == nnp%ele(k)) .OR. &
1850 (nnp%ang(i)%ele1(s) == nnp%ele(k) .AND. &
1851 nnp%ang(i)%ele2(s) == nnp%ele(j)))
THEN
1852 IF (abs(nnp%ang(i)%funccut(s) - funccut) > cutoff_eq_tol)
THEN
1854 funccut = nnp%ang(i)%funccut(s)
1855 nnp%ang(i)%symfgrp(ang)%cutoff = funccut
1856 ALLOCATE (nnp%ang(i)%symfgrp(ang)%ele(2))
1857 ALLOCATE (nnp%ang(i)%symfgrp(ang)%ele_ind(2))
1858 nnp%ang(i)%symfgrp(ang)%ele(1) = nnp%ele(j)
1859 nnp%ang(i)%symfgrp(ang)%ele(2) = nnp%ele(k)
1860 nnp%ang(i)%symfgrp(ang)%ele_ind(1) = j
1861 nnp%ang(i)%symfgrp(ang)%ele_ind(2) = k
1863 nnp%ang(i)%symfgrp(ang)%n_symf = nnp%ang(i)%symfgrp(ang)%n_symf + 1
1871 DO j = 1, nnp%rad(i)%n_symfgrp
1872 ALLOCATE (nnp%rad(i)%symfgrp(j)%symf(nnp%rad(i)%symfgrp(j)%n_symf))
1874 DO s = 1, nnp%n_rad(i)
1875 IF (nnp%rad(i)%ele(s) == nnp%rad(i)%symfgrp(j)%ele(1))
THEN
1876 IF (abs(nnp%rad(i)%funccut(s) - nnp%rad(i)%symfgrp(j)%cutoff) <= cutoff_eq_tol)
THEN
1878 nnp%rad(i)%symfgrp(j)%symf(rad) = s
1883 DO j = 1, nnp%ang(i)%n_symfgrp
1884 ALLOCATE (nnp%ang(i)%symfgrp(j)%symf(nnp%ang(i)%symfgrp(j)%n_symf))
1886 DO s = 1, nnp%n_ang(i)
1887 IF ((nnp%ang(i)%ele1(s) == nnp%ang(i)%symfgrp(j)%ele(1) .AND. &
1888 nnp%ang(i)%ele2(s) == nnp%ang(i)%symfgrp(j)%ele(2)) .OR. &
1889 (nnp%ang(i)%ele1(s) == nnp%ang(i)%symfgrp(j)%ele(2) .AND. &
1890 nnp%ang(i)%ele2(s) == nnp%ang(i)%symfgrp(j)%ele(1)))
THEN
1891 IF (abs(nnp%ang(i)%funccut(s) - nnp%ang(i)%symfgrp(j)%cutoff) <= cutoff_eq_tol)
THEN
1893 nnp%ang(i)%symfgrp(j)%symf(ang) = s
1908 DO j = 1, nnp%ang(i)%n_symfgrp
1909 n_symf = nnp%ang(i)%symfgrp(j)%n_symf
1910 ALLOCATE (nnp%ang(i)%symfgrp(j)%pack_eta(n_symf))
1911 ALLOCATE (nnp%ang(i)%symfgrp(j)%pack_zeta(n_symf))
1912 ALLOCATE (nnp%ang(i)%symfgrp(j)%pack_lam(n_symf))
1913 ALLOCATE (nnp%ang(i)%symfgrp(j)%pack_prefzeta(n_symf))
1914 ALLOCATE (nnp%ang(i)%symfgrp(j)%pack_izeta(n_symf))
1915 ALLOCATE (nnp%ang(i)%symfgrp(j)%pack_use_int_zeta(n_symf))
1917 m = nnp%ang(i)%symfgrp(j)%symf(sf)
1918 eta_tmp = nnp%ang(i)%eta(m)
1919 zeta_tmp = nnp%ang(i)%zeta(m)
1920 nnp%ang(i)%symfgrp(j)%pack_eta(sf) = eta_tmp
1921 nnp%ang(i)%symfgrp(j)%pack_zeta(sf) = zeta_tmp
1922 nnp%ang(i)%symfgrp(j)%pack_lam(sf) = nnp%ang(i)%lam(m)
1923 nnp%ang(i)%symfgrp(j)%pack_prefzeta(sf) = nnp%ang(i)%prefzeta(m)
1924 izeta_tmp = nint(zeta_tmp)
1925 nnp%ang(i)%symfgrp(j)%pack_izeta(sf) = izeta_tmp
1926 nnp%ang(i)%symfgrp(j)%pack_use_int_zeta(sf) = &
1927 (real(izeta_tmp, dp) == zeta_tmp)
1945 TYPE(nnp_type),
INTENT(INOUT) :: nnp
1946 TYPE(mp_para_env_type),
POINTER :: para_env
1947 CHARACTER(LEN=*),
INTENT(IN) :: printtag
1949 CHARACTER(len=default_string_length) :: my_label
1950 INTEGER :: i, j, unit_nr
1951 TYPE(cp_logger_type),
POINTER :: logger
1954 logger => cp_get_default_logger()
1956 my_label = trim(printtag)//
"| "
1957 IF (para_env%is_source())
THEN
1958 unit_nr = cp_logger_get_default_unit_nr(logger)
1959 WRITE (unit_nr,
'(1X,A,1X,10(I2,1X))') trim(my_label)//
" Activation functions:", nnp%actfnct(:)
1961 WRITE (unit_nr, *) trim(my_label)//
" short range atomic symmetry functions element "// &
1963 DO j = 1, nnp%n_rad(i)
1964 WRITE (unit_nr,
'(1X,A,1X,I3,1X,A2,1X,I2,1X,A2,11X,3(F6.3,1X))') trim(my_label), j, nnp%ele(i), 2, &
1965 nnp%rad(i)%ele(j), nnp%rad(i)%eta(j), &
1966 nnp%rad(i)%rs(j), nnp%rad(i)%funccut(j)
1968 DO j = 1, nnp%n_ang(i)
1969 WRITE (unit_nr,
'(1X,A,1X,I3,1X,A2,1X,I2,2(1X,A2),1X,4(F6.3,1X))') &
1970 trim(my_label), j, nnp%ele(i), 3, &
1971 nnp%ang(i)%ele1(j), nnp%ang(i)%ele2(j), &
1972 nnp%ang(i)%eta(j), nnp%ang(i)%lam(j), &
1973 nnp%ang(i)%zeta(j), nnp%ang(i)%funccut(j)
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Interface to the message passing library MPI.
Functionality for atom centered symmetry functions for neural network potentials.
subroutine, public nnp_calc_acsf(nnp, i, calc_forces, stress)
Calculate atom centered symmetry functions for given atom i.
subroutine, public nnp_write_acsf(nnp, para_env, printtag)
Print a summary of the active symmetry-function set on the source rank. Emits one line per element li...
subroutine, public nnp_init_acsf_groups(nnp)
Pack symmetry functions into groups that share input parameters. Builds nnprad(i)symfgrp(:) and nnpan...
subroutine, public nnp_prepare_neighbor_cache(nnp)
Prepare or update the linked-cell / Verlet cache for the current geometry. Lazily allocates nnpcell_l...
subroutine, public nnp_sort_acsf(nnp)
Sort radial and angular symmetry functions in canonical order. Radial SFs are sorted by eta (ascendin...
subroutine, public nnp_sort_ele(ele, nuc_ele)
Sort an (ele, nuc_ele) pair of arrays in ascending order of atomic number. Used to canonicalise eleme...
Linked-cell neighbour finder with a Verlet skin for the NNP descriptor. Owns the per-nnp cell-list ca...
subroutine, public nnp_prepare_cell_list_cache(nnp)
Prepare the cell-list cache for the current force evaluation: wrap positions into the primary cell,...
subroutine, public nnp_compute_neighbors_cell_list(nnp, neighbor, i)
Fill the ACSF neighbour buffers for one central atom by walking the linked-cell stencil around its bi...
Data types for neural network potentials.
integer, parameter, public nnp_cut_tanh
integer, parameter, public nnp_cut_cos
derived data types
Per-nnp persistent neighbour-interface state for the NNP hot path. Separates neighbour bookkeeping fr...
subroutine, public nnp_grp_grow_dgdr(grp, n_needed)
Ensure a per-group dG/dr buffer holds n_needed neighbours, growing by 1.5x (with an additive floor) s...
subroutine, public nnp_workspace_grow_caches(workspace, n_needed)
Ensure the four per-element angular cutoff caches hold at least n_needed entries. These 1D scratch ar...
subroutine, public nnp_neighbor_interface_reset_neighbor(nnp, ind)
Reset per-group neighbour counters for one central element before refilling the reusable buffers....
subroutine, public nnp_neighbor_interface_prepare(nnp)
Ensure pair-routing metadata and reusable workspaces are ready for the current NNP model.
Periodic Table related data definitions.
subroutine, public get_ptable_info(symbol, number, amass, ielement, covalent_radius, metallic_radius, vdw_radius, found)
Pass information about the kind given the element symbol.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
Set of angular symmetry function type.
Set of radial symmetry function type.
Symmetry functions group type.
Main data type collecting all relevant data for neural network potentials.