51#include "./base/base_uses.f90"
57 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .false.
58 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'nnp_force'
73 TYPE(
nnp_type),
INTENT(INOUT),
POINTER :: nnp
74 LOGICAL,
INTENT(IN) :: calc_forces
76 CHARACTER(len=*),
PARAMETER :: routinen =
'nnp_calc_energy_force'
78 INTEGER :: handle, handle_loop, i, i_com, ie, ig, &
79 il, ind, istart, j, k, m, &
80 max_input_nodes, mecalc, &
81 n_input_nodes, nthreads, t, tid
82 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: allcalc
83 LOGICAL :: calc_stress, run_cpu_path, use_gpu_path, &
85 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: denergydsym
86 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: val_energy
87 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: stress, val_force, val_stress
88 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :, :) :: my_cstress_t, my_force_t
98 CALL timeset(routinen, handle)
100 NULLIFY (particle_set, logger, local_particles, subsys, &
104 cpassert(
ASSOCIATED(nnp))
105 cpassert(nnp%n_committee >= 1)
106 CALL nnp_env_get(nnp_env=nnp, particle_set=particle_set, &
107 subsys=subsys, local_particles=local_particles, &
108 atomic_kind_set=atomic_kind_set)
113 calc_stress = virial%pv_availability .AND. (.NOT. virial%pv_numer)
114 IF (calc_stress .AND. .NOT. calc_forces)
THEN
115 cpabort(
'Stress cannot be calculated without forces')
118 nnp%atomic_energy(:, :) = 0.0_dp
119 IF (calc_forces) nnp%myforce(:, :, :) = 0.0_dp
120 IF (calc_forces) nnp%committee_forces(:, :, :) = 0.0_dp
121 IF (calc_stress) nnp%committee_stress(:, :, :) = 0.0_dp
126 DO j = 1, nnp%num_atoms
127 IF (nnp%ele(i) == particle_set(j)%atomic_kind%element_symbol)
THEN
129 nnp%coord(m, ig) = particle_set(j)%r(m)
131 nnp%atoms(ig) = nnp%ele(i)
142 mecalc = nnp%num_atoms/logger%para_env%num_pe + &
143 min(mod(nnp%num_atoms, logger%para_env%num_pe)/ &
144 (logger%para_env%mepos + 1), 1)
145 ALLOCATE (allcalc(logger%para_env%num_pe))
147 CALL logger%para_env%allgather(mecalc, allcalc)
149 DO i = 2, logger%para_env%mepos + 1
150 istart = istart + allcalc(i - 1)
154 nnp%output_expol = .false.
160 max_input_nodes = max(max_input_nodes, nnp%arc(i)%n_nodes(1))
171 validate = use_gpu_path .AND. nnp%validate_gpu
172 run_cpu_path = (.NOT. use_gpu_path) .OR. validate
179 IF (calc_forces .AND. run_cpu_path)
THEN
181 ALLOCATE (my_force_t(3, nnp%num_atoms, nnp%n_committee, 0:nthreads - 1))
182 my_force_t(:, :, :, :) = 0.0_dp
183 IF (calc_stress)
THEN
184 ALLOCATE (my_cstress_t(3, 3, nnp%n_committee, 0:nthreads - 1))
185 my_cstress_t(:, :, :, :) = 0.0_dp
191 CALL timeset(
'nnp_per_rank_atom_loop', handle_loop)
193 IF (use_gpu_path)
THEN
198 ALLOCATE (val_energy, source=nnp%atomic_energy)
199 ALLOCATE (val_force, source=nnp%myforce)
200 IF (calc_stress)
ALLOCATE (val_stress, source=nnp%committee_stress)
201 nnp%atomic_energy(:, :) = 0.0_dp
202 nnp%myforce(:, :, :) = 0.0_dp
203 IF (calc_stress) nnp%committee_stress(:, :, :) = 0.0_dp
206 IF (run_cpu_path)
THEN
228 ALLOCATE (my_arc(nnp%n_ele))
230 ALLOCATE (my_arc(ie)%n_nodes, source=nnp%arc(ie)%n_nodes)
231 ALLOCATE (my_arc(ie)%layer(nnp%n_layer))
232 DO il = 1, nnp%n_layer
233 IF (
ALLOCATED(nnp%arc(ie)%layer(il)%weights))
THEN
234 ALLOCATE (my_arc(ie)%layer(il)%weights, source=nnp%arc(ie)%layer(il)%weights)
236 IF (
ALLOCATED(nnp%arc(ie)%layer(il)%bweights))
THEN
237 ALLOCATE (my_arc(ie)%layer(il)%bweights, source=nnp%arc(ie)%layer(il)%bweights)
239 IF (
ALLOCATED(nnp%arc(ie)%layer(il)%node))
THEN
240 ALLOCATE (my_arc(ie)%layer(il)%node, source=nnp%arc(ie)%layer(il)%node)
242 IF (
ALLOCATED(nnp%arc(ie)%layer(il)%node_grad))
THEN
243 ALLOCATE (my_arc(ie)%layer(il)%node_grad, source=nnp%arc(ie)%layer(il)%node_grad)
245 IF (
ALLOCATED(nnp%arc(ie)%layer(il)%tmp_der))
THEN
246 ALLOCATE (my_arc(ie)%layer(il)%tmp_der, source=nnp%arc(ie)%layer(il)%tmp_der)
251 IF (calc_forces)
THEN
252 ALLOCATE (denergydsym(max_input_nodes))
253 denergydsym(:) = 0.0_dp
254 IF (calc_stress)
THEN
255 ALLOCATE (stress(3, 3, max_input_nodes))
256 stress(:, :, :) = 0.0_dp
262 DO i = istart, istart + mecalc - 1
266 n_input_nodes = nnp%arc(ind)%n_nodes(1)
269 my_arc(ind)%layer(1)%node(:) = 0.0_dp
272 IF (calc_forces)
THEN
274 my_arc(ind)%layer(1)%node_grad(:) = 0.0_dp
275 IF (calc_stress)
THEN
276 stress(:, :, 1:n_input_nodes) = 0.0_dp
277 CALL nnp_calc_acsf(nnp, i, .true., my_arc(ind), stress(:, :, 1:n_input_nodes))
285 DO i_com = 1, nnp%n_committee
288 nnp%atomic_energy(i, i_com) = my_arc(ind)%layer(nnp%n_layer)%node(1) + &
289 nnp%atom_energies(ind)
292 IF (calc_forces)
THEN
293 denergydsym(1:n_input_nodes) = 0.0_dp
294 CALL nnp_gradients(my_arc(ind), nnp, i_com, denergydsym(1:n_input_nodes))
300 my_force_t(:, :, i_com, tid - 1))
302 IF (calc_stress)
THEN
303 DO j = 1, n_input_nodes
304 my_cstress_t(:, :, i_com, tid - 1) = my_cstress_t(:, :, i_com, tid - 1) - &
305 denergydsym(j)*stress(:, :, j)
314 IF (calc_forces)
THEN
315 DEALLOCATE (denergydsym)
316 IF (calc_stress)
DEALLOCATE (stress)
326 DO il = 1, nnp%n_layer
327 IF (
ALLOCATED(my_arc(ie)%layer(il)%weights))
DEALLOCATE (my_arc(ie)%layer(il)%weights)
328 IF (
ALLOCATED(my_arc(ie)%layer(il)%bweights))
DEALLOCATE (my_arc(ie)%layer(il)%bweights)
329 IF (
ALLOCATED(my_arc(ie)%layer(il)%node))
DEALLOCATE (my_arc(ie)%layer(il)%node)
330 IF (
ALLOCATED(my_arc(ie)%layer(il)%node_grad))
DEALLOCATE (my_arc(ie)%layer(il)%node_grad)
331 IF (
ALLOCATED(my_arc(ie)%layer(il)%tmp_der))
DEALLOCATE (my_arc(ie)%layer(il)%tmp_der)
333 DEALLOCATE (my_arc(ie)%layer)
341 IF (calc_forces)
THEN
342 DO t = 0, nthreads - 1
343 nnp%myforce(:, :, :) = nnp%myforce(:, :, :) + my_force_t(:, :, :, t)
345 DEALLOCATE (my_force_t)
346 IF (calc_stress)
THEN
347 DO t = 0, nthreads - 1
348 nnp%committee_stress(:, :, :) = nnp%committee_stress(:, :, :) + my_cstress_t(:, :, :, t)
350 DEALLOCATE (my_cstress_t)
356 CALL timestop(handle_loop)
361 IF (calc_stress)
THEN
362 CALL nnp_gpu_validate(nnp, logger, val_energy, val_force, val_stress)
364 CALL nnp_gpu_validate(nnp, logger, val_energy, val_force)
369 CALL logger%para_env%sum(nnp%atomic_energy(:, :))
370 nnp%committee_energy(:) = sum(nnp%atomic_energy, 1)
371 nnp%nnp_potential_energy = sum(nnp%committee_energy)/real(nnp%n_committee,
dp)
373 IF (calc_forces)
THEN
375 DO j = 1, nnp%num_atoms
377 nnp%committee_forces(k, (nnp%sort(j)), :) = nnp%myforce(k, j, :)
380 CALL logger%para_env%sum(nnp%committee_forces)
381 nnp%nnp_forces(:, :) = sum(nnp%committee_forces, dim=3)/real(nnp%n_committee,
dp)
382 DO j = 1, nnp%num_atoms
383 particle_set(j)%f(:) = nnp%nnp_forces(:, j)
387 IF (calc_stress)
THEN
388 CALL logger%para_env%sum(nnp%committee_stress)
389 virial%pv_virial = sum(nnp%committee_stress, dim=3)/real(nnp%n_committee,
dp)
394 CALL nnp_bias_sigma(nnp, calc_forces)
395 nnp%nnp_potential_energy = nnp%nnp_potential_energy + nnp%bias_energy
396 IF (calc_forces)
THEN
397 DO j = 1, nnp%num_atoms
398 particle_set(j)%f(:) = particle_set(j)%f(:) + nnp%bias_forces(:, j)
403 CALL nnp_print_bias(nnp, print_section)
408 CALL nnp_print(nnp, print_section)
412 CALL timestop(handle)
438 SUBROUTINE nnp_gpu_validate(nnp, logger, gpu_energy, gpu_force, gpu_stress)
439 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
441 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gpu_energy
442 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: gpu_force
443 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
444 OPTIONAL :: gpu_stress
446 CHARACTER(len=*),
PARAMETER :: routinen =
'nnp_gpu_validate'
448 CHARACTER(LEN=2*default_string_length) :: message
449 INTEGER :: handle, unit_nr
450 REAL(kind=
dp) :: diff_energy, diff_force, diff_stress, &
451 tol_energy, tol_force
453 CALL timeset(routinen, handle)
456 tol_energy = 1.0e-5_dp
457 tol_force = 1.0e-4_dp
459 tol_energy = 1.0e-9_dp
460 tol_force = 1.0e-8_dp
463 diff_energy = maxval(abs(nnp%atomic_energy - gpu_energy)/ &
464 max(1.0_dp, abs(nnp%atomic_energy)))
465 diff_force = maxval(abs(nnp%myforce - gpu_force)/ &
466 max(1.0_dp, abs(nnp%myforce)))
468 IF (
PRESENT(gpu_stress))
THEN
469 diff_stress = maxval(abs(nnp%committee_stress - gpu_stress)/ &
470 max(1.0_dp, abs(nnp%committee_stress)))
474 CALL logger%para_env%max(diff_energy)
475 CALL logger%para_env%max(diff_force)
476 CALL logger%para_env%max(diff_stress)
478 IF (diff_energy > tol_energy .OR. diff_force > tol_force .OR. &
479 diff_stress > tol_force)
THEN
480 WRITE (message,
"(A,3ES11.3,A,2ES10.1)") &
481 "NNP GPU validation failure. Max rel. diff (energies, forces, "// &
482 "stress):", diff_energy, diff_force, diff_stress, &
483 ", tolerances:", tol_energy, tol_force
484 cpabort(trim(message))
488 IF (unit_nr > 0)
THEN
489 WRITE (unit_nr,
"(T2,A,3ES11.3)") &
490 "NNP| Validated GPU force evaluation, max rel. diff: ", &
491 diff_energy, diff_force, diff_stress
496 nnp%atomic_energy(:, :) = gpu_energy(:, :)
497 nnp%myforce(:, :, :) = gpu_force(:, :, :)
498 IF (
PRESENT(gpu_stress)) nnp%committee_stress(:, :, :) = gpu_stress(:, :, :)
500 CALL timestop(handle)
502 END SUBROUTINE nnp_gpu_validate
511 SUBROUTINE nnp_bias_sigma(nnp, calc_forces)
512 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
513 LOGICAL,
INTENT(IN) :: calc_forces
515 CHARACTER(len=*),
PARAMETER :: routinen =
'nnp_bias_sigma'
518 REAL(kind=
dp) :: avrg, pref, sigma
520 CALL timeset(routinen, handle)
524 nnp%bias_energy = 0.0_dp
525 IF (calc_forces) nnp%bias_forces = 0.0_dp
528 IF (nnp%bias_align)
THEN
530 nnp%committee_energy(:) = nnp%committee_energy(:) - nnp%bias_e_avrg(:)
536 avrg = sum(nnp%committee_energy)/real(nnp%n_committee,
dp)
537 DO i = 1, nnp%n_committee
538 sigma = sigma + (nnp%committee_energy(i) - avrg)**2
540 sigma = sqrt(sigma/real(nnp%n_committee,
dp))
541 nnp%bias_sigma = sigma
543 IF (sigma > nnp%bias_sigma0)
THEN
545 nnp%bias_energy = 0.5_dp*nnp%bias_kb*(sigma - nnp%bias_sigma0)**2
547 IF (calc_forces)
THEN
551 pref = nnp%bias_kb*(1.0_dp - nnp%bias_sigma0/sigma)
552 DO i = 1, nnp%n_committee
553 nnp%bias_forces(:, :) = nnp%bias_forces(:, :) + &
554 (nnp%committee_energy(i) - avrg)* &
555 (nnp%committee_forces(:, :, i) - nnp%nnp_forces(:, :))
557 pref = pref/real(nnp%n_committee,
dp)
558 nnp%bias_forces(:, :) = nnp%bias_forces(:, :)*pref
562 CALL timestop(handle)
564 END SUBROUTINE nnp_bias_sigma
573 SUBROUTINE nnp_print(nnp, print_section)
574 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
578 LOGICAL :: explicit, file_is_new
582 NULLIFY (logger, print_key)
588 middle_name=
"nnp-energies", is_new_file=file_is_new)
589 IF (unit_nr > 0)
CALL nnp_print_energies(nnp, unit_nr, file_is_new)
595 CALL nnp_print_forces(nnp, print_key)
601 middle_name=
"nnp-forces-std")
602 IF (unit_nr > 0)
CALL nnp_print_force_sigma(nnp, unit_nr)
607 CALL logger%para_env%sum(nnp%output_expol)
608 IF (nnp%output_expol)
THEN
612 middle_name=
"nnp-extrapolation")
613 IF (unit_nr > 0)
CALL nnp_print_expol(nnp, unit_nr)
625 middle_name=
"nnp-sumforce", is_new_file=file_is_new)
626 IF (unit_nr > 0)
CALL nnp_print_sumforces(nnp, print_section, unit_nr, file_is_new)
631 END SUBROUTINE nnp_print
641 SUBROUTINE nnp_print_energies(nnp, unit_nr, file_is_new)
642 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
643 INTEGER,
INTENT(IN) :: unit_nr
644 LOGICAL,
INTENT(IN) :: file_is_new
646 CHARACTER(LEN=12) :: fmt_string
650 IF (file_is_new)
THEN
651 WRITE (unit_nr,
"(A1,1X,A20)", advance=
'no')
"#",
"NNP Average [a.u.],"
652 WRITE (unit_nr,
"(A20)", advance=
'no')
"NNP sigma [a.u.]"
653 DO i = 1, nnp%n_committee
654 WRITE (unit_nr,
"(A17,I3)", advance=
'no')
"NNP", i
656 WRITE (unit_nr,
"(A)")
""
659 fmt_string =
"(2X, F20.9)"
660 WRITE (unit=fmt_string(5:6), fmt=
"(I2)") nnp%n_committee + 2
661 std = sum((sum(nnp%atomic_energy, 1) - nnp%nnp_potential_energy)**2)
662 std = std/real(nnp%n_committee,
dp)
664 WRITE (unit_nr, fmt_string) nnp%nnp_potential_energy, std, sum(nnp%atomic_energy, 1)
666 END SUBROUTINE nnp_print_energies
675 SUBROUTINE nnp_print_forces(nnp, print_key)
676 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
679 CHARACTER(len=default_path_length) :: fmt_string, middle_name
680 INTEGER :: i, j, unit_nr
686 DO i = 1, nnp%n_committee
687 WRITE (fmt_string, *) i
688 WRITE (middle_name,
"(A,A)")
"nnp-forces-", adjustl(trim(fmt_string))
690 middle_name=trim(middle_name))
691 IF (unit_nr > 0)
THEN
692 WRITE (unit_nr, *) nnp%num_atoms
693 WRITE (unit_nr,
"(A,1X,A,A,F20.9)")
"NNP forces [a.u.] of committee member", &
694 adjustl(trim(fmt_string)),
"energy [a.u.]=", nnp%committee_energy(i)
696 fmt_string =
"(A4,1X,3F20.10)"
697 DO j = 1, nnp%num_atoms
698 WRITE (unit_nr, fmt_string) nnp%atoms(nnp%sort_inv(j)), nnp%committee_forces(:, j, i)
704 END SUBROUTINE nnp_print_forces
713 SUBROUTINE nnp_print_force_sigma(nnp, unit_nr)
714 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
715 INTEGER,
INTENT(IN) :: unit_nr
718 REAL(kind=
dp),
DIMENSION(3) :: var
720 IF (unit_nr > 0)
THEN
721 WRITE (unit_nr, *) nnp%num_atoms
722 WRITE (unit_nr,
"(A,1X,A)")
"NNP sigma of forces [a.u.]"
724 DO i = 1, nnp%num_atoms
726 DO j = 1, nnp%n_committee
727 var = var + (nnp%committee_forces(:, i, j) - nnp%nnp_forces(:, i))**2
729 var = var/real(nnp%n_committee,
dp)
731 WRITE (unit_nr,
"(A4,1X,3F20.10)") nnp%atoms(nnp%sort_inv(i)), var
735 END SUBROUTINE nnp_print_force_sigma
744 SUBROUTINE nnp_print_expol(nnp, unit_nr)
745 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
746 INTEGER,
INTENT(IN) :: unit_nr
748 CHARACTER(len=default_path_length) :: fmt_string
750 REAL(kind=
dp) :: mass, unit_conv
751 REAL(kind=
dp),
DIMENSION(3) :: com
753 nnp%expol = nnp%expol + 1
754 WRITE (unit_nr, *) nnp%num_atoms
755 WRITE (unit_nr,
"(A,1X,I6)")
"NNP extrapolation point N =", nnp%expol
761 DO i = 1, nnp%num_atoms
763 com(:) = com(:) + nnp%coord(:, i)*unit_conv
764 mass = mass + unit_conv
768 DO i = 1, nnp%num_atoms
769 nnp%coord(:, i) = nnp%coord(:, i) - com(:)
774 fmt_string =
"(A4,1X,3F20.10)"
775 DO i = 1, nnp%num_atoms
776 WRITE (unit_nr, fmt_string) &
777 nnp%atoms(nnp%sort_inv(i)), &
778 nnp%coord(1, nnp%sort_inv(i))*unit_conv, &
779 nnp%coord(2, nnp%sort_inv(i))*unit_conv, &
780 nnp%coord(3, nnp%sort_inv(i))*unit_conv
783 END SUBROUTINE nnp_print_expol
792 SUBROUTINE nnp_print_bias(nnp, print_section)
793 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
797 LOGICAL :: file_is_new
801 NULLIFY (logger, print_key)
807 middle_name=
"nnp-bias-energy", is_new_file=file_is_new)
808 IF (unit_nr > 0)
CALL nnp_print_bias_energy(nnp, unit_nr, file_is_new)
815 middle_name=
"nnp-bias-forces")
816 IF (unit_nr > 0)
CALL nnp_print_bias_forces(nnp, unit_nr)
820 END SUBROUTINE nnp_print_bias
830 SUBROUTINE nnp_print_bias_energy(nnp, unit_nr, file_is_new)
831 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
832 INTEGER,
INTENT(IN) :: unit_nr
833 LOGICAL,
INTENT(IN) :: file_is_new
835 CHARACTER(len=default_path_length) :: fmt_string
838 IF (file_is_new)
THEN
839 WRITE (unit_nr,
"(A1)", advance=
'no')
"#"
840 WRITE (unit_nr,
"(2(2X,A19))", advance=
'no')
"Sigma [a.u.]",
"Bias energy [a.u.]"
841 DO i = 1, nnp%n_committee
842 IF (nnp%bias_align)
THEN
843 WRITE (unit_nr,
"(2X,A16,I3)", advance=
'no')
"shifted E_NNP", i
845 WRITE (unit_nr,
"(2X,A16,I3)", advance=
'no')
"E_NNP", i
848 WRITE (unit_nr,
"(A)")
""
852 WRITE (fmt_string,
"(A,I3,A)")
"(2X,", nnp%n_committee + 2,
"(F20.9,1X))"
853 WRITE (unit_nr, fmt_string) nnp%bias_sigma, nnp%bias_energy, nnp%committee_energy
855 END SUBROUTINE nnp_print_bias_energy
864 SUBROUTINE nnp_print_bias_forces(nnp, unit_nr)
865 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
866 INTEGER,
INTENT(IN) :: unit_nr
868 CHARACTER(len=default_path_length) :: fmt_string
871 WRITE (unit_nr, *) nnp%num_atoms
872 WRITE (unit_nr,
"(A,F20.9)")
"NNP bias forces [a.u.] for bias energy [a.u]=", nnp%bias_energy
874 fmt_string =
"(A4,1X,3F20.10)"
875 DO i = 1, nnp%num_atoms
876 WRITE (unit_nr, fmt_string) nnp%atoms(nnp%sort_inv(i)), nnp%bias_forces(:, i)
879 END SUBROUTINE nnp_print_bias_forces
890 SUBROUTINE nnp_print_sumforces(nnp, print_section, unit_nr, file_is_new)
891 TYPE(
nnp_type),
INTENT(INOUT) :: nnp
893 INTEGER,
INTENT(IN) :: unit_nr
894 LOGICAL,
INTENT(IN) :: file_is_new
896 CHARACTER(len=default_path_length) :: fmt_string
897 CHARACTER(LEN=default_string_length), &
898 DIMENSION(:),
POINTER :: atomlist
899 INTEGER :: i, ig, j, n
900 REAL(kind=
dp),
DIMENSION(3) :: rvec
903 IF (file_is_new)
THEN
904 WRITE (unit_nr,
"(A)")
"# Summed forces [a.u.]"
912 IF (
ASSOCIATED(atomlist))
THEN
914 DO i = 1, nnp%num_atoms
917 IF (trim(adjustl(atomlist(j))) == trim(adjustl(nnp%atoms(ig))))
THEN
918 rvec(:) = rvec(:) + nnp%nnp_forces(:, i)
924 fmt_string =
"(3(F20.10,1X))"
925 WRITE (unit_nr, fmt_string) rvec
927 END SUBROUTINE nnp_print_sumforces
952 INTEGER,
INTENT(IN) :: ind, i
953 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: denergydsym
954 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: force_xyz
956 INTEGER :: j, k, k_atom, m, n_ang1_s, n_ang2_s, &
957 n_input_nodes, n_symf_s, off, s, sf, &
964 associate(workspace => nnp%neighbor_interface_state%workspace(ind, tid), &
965 neighbor => nnp%neighbor_interface_state%workspace(ind, tid)%neighbor, &
966 self_dgdr => nnp%neighbor_interface_state%workspace(ind, tid)%self_dGdr)
968 n_input_nodes = workspace%n_input_nodes
971 DO j = 1, n_input_nodes
973 force_xyz(1, i) = force_xyz(1, i) - de*self_dgdr(1, j)
974 force_xyz(2, i) = force_xyz(2, i) - de*self_dgdr(2, j)
975 force_xyz(3, i) = force_xyz(3, i) - de*self_dgdr(3, j)
979 DO s = 1, nnp%rad(ind)%n_symfgrp
980 n_symf_s = nnp%rad(ind)%symfgrp(s)%n_symf
981 associate(rad_buf => workspace%dGdr_rad(s)%data)
982 DO j = 1, neighbor%n_rad(s)
983 k_atom = neighbor%rad(s)%ind(j)
985 m = nnp%rad(ind)%symfgrp(s)%symf(sf)
987 force_xyz(1, k_atom) = force_xyz(1, k_atom) - de*rad_buf(1, sf, j)
988 force_xyz(2, k_atom) = force_xyz(2, k_atom) - de*rad_buf(2, sf, j)
989 force_xyz(3, k_atom) = force_xyz(3, k_atom) - de*rad_buf(3, sf, j)
997 DO s = 1, nnp%ang(ind)%n_symfgrp
998 n_symf_s = nnp%ang(ind)%symfgrp(s)%n_symf
999 n_ang1_s = neighbor%n_ang1(s)
1000 homo_grp = (nnp%ang(ind)%symfgrp(s)%ele(1) == nnp%ang(ind)%symfgrp(s)%ele(2))
1004 n_ang2_s = neighbor%n_ang2(s)
1007 associate(jj_buf => workspace%dGdr_ang_jj(s)%data, &
1008 kk_buf => workspace%dGdr_ang_kk(s)%data)
1011 k_atom = neighbor%ang1(s)%ind(j)
1013 m = off + nnp%ang(ind)%symfgrp(s)%symf(sf)
1015 force_xyz(1, k_atom) = force_xyz(1, k_atom) - de*jj_buf(1, sf, j)
1016 force_xyz(2, k_atom) = force_xyz(2, k_atom) - de*jj_buf(2, sf, j)
1017 force_xyz(3, k_atom) = force_xyz(3, k_atom) - de*jj_buf(3, sf, j)
1024 k_atom = neighbor%ang1(s)%ind(k)
1026 m = off + nnp%ang(ind)%symfgrp(s)%symf(sf)
1028 force_xyz(1, k_atom) = force_xyz(1, k_atom) - de*kk_buf(1, sf, k)
1029 force_xyz(2, k_atom) = force_xyz(2, k_atom) - de*kk_buf(2, sf, k)
1030 force_xyz(3, k_atom) = force_xyz(3, k_atom) - de*kk_buf(3, sf, k)
1035 k_atom = neighbor%ang2(s)%ind(k)
1037 m = off + nnp%ang(ind)%symfgrp(s)%symf(sf)
1039 force_xyz(1, k_atom) = force_xyz(1, k_atom) - de*kk_buf(1, sf, k)
1040 force_xyz(2, k_atom) = force_xyz(2, k_atom) - de*kk_buf(2, sf, k)
1041 force_xyz(3, k_atom) = force_xyz(3, k_atom) - de*kk_buf(3, sf, k)
Define the atomic kind types and their sub types.
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout, file_access)
...
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell)
returns information about various attributes of the given subsys
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Functionality for atom centered symmetry functions for neural network potentials.
subroutine, public nnp_calc_acsf(nnp, i, calc_forces, arc, stress)
Calculate atom centered symmetry functions for given atom i.
subroutine, public nnp_prepare_neighbor_cache(nnp)
Prepare or update the linked-cell / Verlet cache for the current geometry. Lazily allocates nnpcell_l...
Data types for neural network potentials.
subroutine, public nnp_env_get(nnp_env, nnp_forces, subsys, atomic_kind_set, particle_set, local_particles, molecule_kind_set, molecule_set, local_molecules, nnp_input, force_env_input, cell, cell_ref, use_ref_cell, nnp_potential_energy, virial)
Returns various attributes of the nnp environment.
Methods dealing with Neural Network potentials.
subroutine, public nnp_scatter_dgdr_to_forces(nnp, ind, i, denergydsym, force_xyz)
Scatter the per-neighbour dG/dr arrays held in the nnp_neighbor_workspace into a per-atom Cartesian f...
subroutine, public nnp_calc_energy_force(nnp, calc_forces)
Calculate the energy and force for a given configuration with the NNP.
GPU offload driver for the NNP force evaluation. Hosts the ISO_C_BINDING interfaces to the CUDA launc...
subroutine, public nnp_gpu_energy_force(nnp, istart, mecalc, n_input_max, calc_stress)
Run the whole per-step NNP force evaluation on the device: the cell-list walk, the descriptor build,...
Methods dealing with core routines for artificial neural networks.
subroutine, public nnp_predict(arc, nnp, i_com)
Predict energy by evaluating neural network.
subroutine, public nnp_gradients(arc, nnp, i_com, denergydsym)
Calculate gradients of neural network.
Define the data structure for the particle information.
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.
Definition of physical constants:
real(kind=dp), parameter, public angstrom
Provides all information about an atomic kind.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represents a system: atoms, molecules, their pos,vel,...
structure to store local (to a processor) ordered lists of integers.
Data type for artificial neural networks.
Main data type collecting all relevant data for neural network potentials.