(git:e7e05ae)
nnp_force.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief Methods dealing with Neural Network potentials
10 !> \author Christoph Schran (christoph.schran@rub.de)
11 !> \date 2020-10-10
12 ! **************************************************************************************************
13 MODULE nnp_force
14 
15  USE atomic_kind_types, ONLY: atomic_kind_type
17  cp_logger_type
18  USE cp_output_handling, ONLY: cp_p_file,&
22  USE cp_subsys_types, ONLY: cp_subsys_get,&
23  cp_subsys_type
24  USE cp_units, ONLY: cp_unit_from_cp2k
25  USE distribution_1d_types, ONLY: distribution_1d_type
27  section_vals_type,&
29  USE kinds, ONLY: default_path_length,&
31  dp
32  USE nnp_acsf, ONLY: nnp_calc_acsf
34  nnp_type
35  USE nnp_model, ONLY: nnp_gradients,&
37  USE particle_types, ONLY: particle_type
39  USE physcon, ONLY: angstrom
40  USE virial_types, ONLY: virial_type
41 #include "./base/base_uses.f90"
42 
43  IMPLICIT NONE
44 
45  PRIVATE
46 
47  LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .true.
48  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'nnp_force'
49 
50  PUBLIC :: nnp_calc_energy_force
51 
52 CONTAINS
53 
54 ! **************************************************************************************************
55 !> \brief Calculate the energy and force for a given configuration with the NNP
56 !> \param nnp ...
57 !> \param calc_forces ...
58 !> \date 2020-10-10
59 !> \author Christoph Schran (christoph.schran@rub.de)
60 ! **************************************************************************************************
61  SUBROUTINE nnp_calc_energy_force(nnp, calc_forces)
62  TYPE(nnp_type), INTENT(INOUT), POINTER :: nnp
63  LOGICAL, INTENT(IN) :: calc_forces
64 
65  CHARACTER(len=*), PARAMETER :: routinen = 'nnp_calc_energy_force'
66 
67  INTEGER :: handle, i, i_com, ig, ind, istart, j, k, &
68  m, mecalc
69  INTEGER, ALLOCATABLE, DIMENSION(:) :: allcalc
70  LOGICAL :: calc_stress
71  REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: denergydsym
72  REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: dsymdxyz, stress
73  TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
74  TYPE(cp_logger_type), POINTER :: logger
75  TYPE(cp_subsys_type), POINTER :: subsys
76  TYPE(distribution_1d_type), POINTER :: local_particles
77  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
78  TYPE(section_vals_type), POINTER :: print_section
79  TYPE(virial_type), POINTER :: virial
80 
81  CALL timeset(routinen, handle)
82 
83  NULLIFY (particle_set, logger, local_particles, subsys, &
84  atomic_kind_set)
85  logger => cp_get_default_logger()
86 
87  cpassert(ASSOCIATED(nnp))
88  CALL nnp_env_get(nnp_env=nnp, particle_set=particle_set, &
89  subsys=subsys, local_particles=local_particles, &
90  atomic_kind_set=atomic_kind_set)
91 
92  CALL cp_subsys_get(subsys, &
93  virial=virial)
94 
95  calc_stress = virial%pv_availability .AND. (.NOT. virial%pv_numer)
96  IF (calc_stress .AND. .NOT. calc_forces) cpabort('Stress cannot be calculated without forces')
97 
98  ! Initialize energy and gradient:
99  nnp%atomic_energy(:, :) = 0.0_dp
100  IF (calc_forces) nnp%myforce(:, :, :) = 0.0_dp
101  IF (calc_forces) nnp%committee_forces(:, :, :) = 0.0_dp
102  IF (calc_stress) nnp%committee_stress(:, :, :) = 0.0_dp
103 
104  !fill coord array
105  ig = 1
106  DO i = 1, nnp%n_ele
107  DO j = 1, nnp%num_atoms
108  IF (nnp%ele(i) == particle_set(j)%atomic_kind%element_symbol) THEN
109  DO m = 1, 3
110  nnp%coord(m, ig) = particle_set(j)%r(m)
111  END DO
112  nnp%atoms(ig) = nnp%ele(i)
113  CALL get_ptable_info(nnp%atoms(ig), number=nnp%nuc_atoms(ig))
114  nnp%ele_ind(ig) = i
115  nnp%sort(ig) = j
116  nnp%sort_inv(j) = ig
117  ig = ig + 1
118  END IF
119  END DO
120  END DO
121 
122  ! parallization:
123  mecalc = nnp%num_atoms/logger%para_env%num_pe + &
124  min(mod(nnp%num_atoms, logger%para_env%num_pe)/ &
125  (logger%para_env%mepos + 1), 1)
126  ALLOCATE (allcalc(logger%para_env%num_pe))
127  allcalc(:) = 0
128  CALL logger%para_env%allgather(mecalc, allcalc)
129  istart = 1
130  DO i = 2, logger%para_env%mepos + 1
131  istart = istart + allcalc(i - 1)
132  END DO
133 
134  ! reset extrapolation status
135  nnp%output_expol = .false.
136 
137  ! calc atomic contribution to energy and force
138  DO i = istart, istart + mecalc - 1
139 
140  ! determine index of atom type and offset
141  ind = nnp%ele_ind(i)
142 
143  ! reset input nodes of ele(ind):
144  nnp%arc(ind)%layer(1)%node(:) = 0.0_dp
145 
146  ! compute sym fnct values
147  IF (calc_forces) THEN
148  !reset input grads of ele(ind):
149  nnp%arc(ind)%layer(1)%node_grad(:) = 0.0_dp
150  ALLOCATE (dsymdxyz(3, nnp%arc(ind)%n_nodes(1), nnp%num_atoms))
151  dsymdxyz(:, :, :) = 0.0_dp
152  IF (calc_stress) THEN
153  ALLOCATE (stress(3, 3, nnp%arc(ind)%n_nodes(1)))
154  stress(:, :, :) = 0.0_dp
155  CALL nnp_calc_acsf(nnp, i, dsymdxyz, stress)
156  ELSE
157  CALL nnp_calc_acsf(nnp, i, dsymdxyz)
158  END IF
159  ELSE
160  CALL nnp_calc_acsf(nnp, i)
161  END IF
162 
163  DO i_com = 1, nnp%n_committee
164  ! predict energy
165  CALL nnp_predict(nnp%arc(ind), nnp, i_com)
166  nnp%atomic_energy(i, i_com) = nnp%arc(ind)%layer(nnp%n_layer)%node(1) + &
167  nnp%atom_energies(ind)
168 
169  ! predict forces
170  IF (calc_forces) THEN
171  ALLOCATE (denergydsym(nnp%arc(ind)%n_nodes(1)))
172  denergydsym(:) = 0.0_dp
173  CALL nnp_gradients(nnp%arc(ind), nnp, i_com, denergydsym)
174  DO j = 1, nnp%arc(ind)%n_nodes(1)
175  DO k = 1, nnp%num_atoms
176  DO m = 1, 3
177  nnp%myforce(m, k, i_com) = nnp%myforce(m, k, i_com) - denergydsym(j)*dsymdxyz(m, j, k)
178  END DO
179  END DO
180  IF (calc_stress) THEN
181  nnp%committee_stress(:, :, i_com) = nnp%committee_stress(:, :, i_com) - &
182  denergydsym(j)*stress(:, :, j)
183  END IF
184  END DO
185  DEALLOCATE (denergydsym)
186  END IF
187  END DO
188 
189  !deallocate memory
190  IF (calc_forces) THEN
191  DEALLOCATE (dsymdxyz)
192  IF (calc_stress) THEN
193  DEALLOCATE (stress)
194  END IF
195  END IF
196 
197  END DO ! loop over num_atoms
198 
199  ! calculate energy:
200  CALL logger%para_env%sum(nnp%atomic_energy(:, :))
201  nnp%committee_energy(:) = sum(nnp%atomic_energy, 1)
202  nnp%nnp_potential_energy = sum(nnp%committee_energy)/real(nnp%n_committee, dp)
203 
204  IF (calc_forces) THEN
205  ! bring myforce to force array
206  DO j = 1, nnp%num_atoms
207  DO k = 1, 3
208  nnp%committee_forces(k, (nnp%sort(j)), :) = nnp%myforce(k, j, :)
209  END DO
210  END DO
211  CALL logger%para_env%sum(nnp%committee_forces)
212  nnp%nnp_forces(:, :) = sum(nnp%committee_forces, dim=3)/real(nnp%n_committee, dp)
213  DO j = 1, nnp%num_atoms
214  particle_set(j)%f(:) = nnp%nnp_forces(:, j)
215  END DO
216  END IF
217 
218  IF (calc_stress) THEN
219  CALL logger%para_env%sum(nnp%committee_stress)
220  virial%pv_virial = sum(nnp%committee_stress, dim=3)/real(nnp%n_committee, dp)
221  END IF
222 
223  ! Bias the standard deviation of committee disagreement
224  IF (nnp%bias) THEN
225  CALL nnp_bias_sigma(nnp, calc_forces)
226  nnp%nnp_potential_energy = nnp%nnp_potential_energy + nnp%bias_energy
227  IF (calc_forces) THEN
228  DO j = 1, nnp%num_atoms
229  particle_set(j)%f(:) = particle_set(j)%f(:) + nnp%bias_forces(:, j)
230  END DO
231  END IF
232  ! print properties if requested
233  print_section => section_vals_get_subs_vals(nnp%nnp_input, "BIAS%PRINT")
234  CALL nnp_print_bias(nnp, print_section)
235  END IF
236 
237  ! print properties if requested
238  print_section => section_vals_get_subs_vals(nnp%nnp_input, "PRINT")
239  CALL nnp_print(nnp, print_section)
240 
241  DEALLOCATE (allcalc)
242 
243  CALL timestop(handle)
244 
245  END SUBROUTINE nnp_calc_energy_force
246 
247 ! **************************************************************************************************
248 !> \brief Calculate bias potential and force based on standard deviation of committee disagreement
249 !> \param nnp ...
250 !> \param calc_forces ...
251 !> \date 2020-10-10
252 !> \author Christoph Schran (christoph.schran@rub.de)
253 ! **************************************************************************************************
254  SUBROUTINE nnp_bias_sigma(nnp, calc_forces)
255  TYPE(nnp_type), INTENT(INOUT) :: nnp
256  LOGICAL, INTENT(IN) :: calc_forces
257 
258  CHARACTER(len=*), PARAMETER :: routinen = 'nnp_bias_sigma'
259 
260  INTEGER :: handle, i
261  REAL(kind=dp) :: avrg, pref, sigma
262 
263  CALL timeset(routinen, handle)
264 
265  ! init
266  sigma = 0.0_dp
267  nnp%bias_energy = 0.0_dp
268  IF (calc_forces) nnp%bias_forces = 0.0_dp
269 
270  ! Subtract reference energy of each committee member, if requested
271  IF (nnp%bias_align) THEN
272  ! committee energy not used afterward, therefore overwritten
273  nnp%committee_energy(:) = nnp%committee_energy(:) - nnp%bias_e_avrg(:)
274  END IF
275 
276  ! <E> = 1/n sum(E_i)
277  ! sigma = sqrt(1/n sum((E_i - <E>)**2))
278  ! = sqrt(1/n sum(dE_i**2))
279  avrg = sum(nnp%committee_energy)/real(nnp%n_committee, dp)
280  DO i = 1, nnp%n_committee
281  sigma = sigma + (nnp%committee_energy(i) - avrg)**2
282  END DO
283  sigma = sqrt(sigma/real(nnp%n_committee, dp))
284  nnp%bias_sigma = sigma
285 
286  IF (sigma > nnp%bias_sigma0) THEN
287  ! E_b = 0.5 * kb * (sigma - sigma_0)**2
288  nnp%bias_energy = 0.5_dp*nnp%bias_kb*(sigma - nnp%bias_sigma0)**2
289 
290  IF (calc_forces) THEN
291  ! nabla(E_b) = kb*(sigma - sigma_0)*nabla(sigma)
292  ! nabla(sigma) = 1/sigma * 1/n sum(dE_i* nabla(dE_i))
293  ! nabla(dE_i) = nabla(E_i) - nabla(<E>)
294  pref = nnp%bias_kb*(1.0_dp - nnp%bias_sigma0/sigma)
295  DO i = 1, nnp%n_committee
296  nnp%bias_forces(:, :) = nnp%bias_forces(:, :) + &
297  (nnp%committee_energy(i) - avrg)* &
298  (nnp%committee_forces(:, :, i) - nnp%nnp_forces(:, :))
299  END DO
300  pref = pref/real(nnp%n_committee, dp)
301  nnp%bias_forces(:, :) = nnp%bias_forces(:, :)*pref
302  END IF
303  END IF
304 
305  CALL timestop(handle)
306 
307  END SUBROUTINE nnp_bias_sigma
308 
309 ! **************************************************************************************************
310 !> \brief Print properties according to the requests in input file
311 !> \param nnp ...
312 !> \param print_section ...
313 !> \date 2020-10-10
314 !> \author Christoph Schran (christoph.schran@rub.de)
315 ! **************************************************************************************************
316  SUBROUTINE nnp_print(nnp, print_section)
317  TYPE(nnp_type), INTENT(INOUT) :: nnp
318  TYPE(section_vals_type), INTENT(IN), POINTER :: print_section
319 
320  INTEGER :: unit_nr
321  LOGICAL :: explicit, file_is_new
322  TYPE(cp_logger_type), POINTER :: logger
323  TYPE(section_vals_type), POINTER :: print_key
324 
325  NULLIFY (logger, print_key)
326  logger => cp_get_default_logger()
327 
328  print_key => section_vals_get_subs_vals(print_section, "ENERGIES")
329  IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
330  unit_nr = cp_print_key_unit_nr(logger, print_key, extension=".data", &
331  middle_name="nnp-energies", is_new_file=file_is_new)
332  IF (unit_nr > 0) CALL nnp_print_energies(nnp, unit_nr, file_is_new)
333  CALL cp_print_key_finished_output(unit_nr, logger, print_key)
334  END IF
335 
336  print_key => section_vals_get_subs_vals(print_section, "FORCES")
337  IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
338  IF (unit_nr > 0) CALL nnp_print_forces(nnp, print_key)
339  END IF
340 
341  print_key => section_vals_get_subs_vals(print_section, "FORCES_SIGMA")
342  IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
343  unit_nr = cp_print_key_unit_nr(logger, print_key, extension=".xyz", &
344  middle_name="nnp-forces-std")
345  IF (unit_nr > 0) CALL nnp_print_force_sigma(nnp, unit_nr)
346  CALL cp_print_key_finished_output(unit_nr, logger, print_key)
347  END IF
348 
349  ! Output structures with extrapolation warning on any processor
350  CALL logger%para_env%sum(nnp%output_expol)
351  IF (nnp%output_expol) THEN
352  print_key => section_vals_get_subs_vals(print_section, "EXTRAPOLATION")
353  IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
354  unit_nr = cp_print_key_unit_nr(logger, print_key, extension=".xyz", &
355  middle_name="nnp-extrapolation")
356  IF (unit_nr > 0) CALL nnp_print_expol(nnp, unit_nr)
357  CALL cp_print_key_finished_output(unit_nr, logger, print_key)
358  END IF
359  END IF
360 
361  print_key => section_vals_get_subs_vals(print_section, "SUM_FORCE")
362 
363  CALL section_vals_val_get(print_section, "SUM_FORCE%ATOM_LIST", &
364  explicit=explicit)
365  IF (explicit) THEN
366  IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
367  unit_nr = cp_print_key_unit_nr(logger, print_key, extension=".dat", &
368  middle_name="nnp-sumforce", is_new_file=file_is_new)
369  IF (unit_nr > 0) CALL nnp_print_sumforces(nnp, print_section, unit_nr, file_is_new)
370  CALL cp_print_key_finished_output(unit_nr, logger, print_key)
371  END IF
372  END IF
373 
374  END SUBROUTINE nnp_print
375 
376 ! **************************************************************************************************
377 !> \brief Print NNP energies and standard deviation sigma
378 !> \param nnp ...
379 !> \param unit_nr ...
380 !> \param file_is_new ...
381 !> \date 2020-10-10
382 !> \author Christoph Schran (christoph.schran@rub.de)
383 ! **************************************************************************************************
384  SUBROUTINE nnp_print_energies(nnp, unit_nr, file_is_new)
385  TYPE(nnp_type), INTENT(INOUT) :: nnp
386  INTEGER, INTENT(IN) :: unit_nr
387  LOGICAL, INTENT(IN) :: file_is_new
388 
389  CHARACTER(len=default_path_length) :: fmt_string
390  INTEGER :: i
391  REAL(kind=dp) :: std
392 
393  IF (file_is_new) THEN
394  WRITE (unit_nr, "(A1,1X,A20)", advance='no') "#", "NNP Average [a.u.],"
395  WRITE (unit_nr, "(A20)", advance='no') "NNP sigma [a.u.]"
396  DO i = 1, nnp%n_committee
397  WRITE (unit_nr, "(A17,I3)", advance='no') "NNP", i
398  END DO
399  WRITE (unit_nr, "(A)") ""
400  END IF
401 
402  fmt_string = "(2X,2(F20.9))"
403  WRITE (fmt_string, "(A,I3,A)") "(2X", nnp%n_committee + 2, "(F20.9))"
404  std = sum((sum(nnp%atomic_energy, 1) - nnp%nnp_potential_energy)**2)
405  std = std/real(nnp%n_committee, dp)
406  std = sqrt(std)
407  WRITE (unit_nr, fmt_string) nnp%nnp_potential_energy, std, sum(nnp%atomic_energy, 1)
408 
409  END SUBROUTINE nnp_print_energies
410 
411 ! **************************************************************************************************
412 !> \brief Print nnp forces
413 !> \param nnp ...
414 !> \param print_key ...
415 !> \date 2020-10-10
416 !> \author Christoph Schran (christoph.schran@rub.de)
417 ! **************************************************************************************************
418  SUBROUTINE nnp_print_forces(nnp, print_key)
419  TYPE(nnp_type), INTENT(INOUT) :: nnp
420  TYPE(section_vals_type), INTENT(IN), POINTER :: print_key
421 
422  CHARACTER(len=default_path_length) :: fmt_string, middle_name
423  INTEGER :: i, j, unit_nr
424  TYPE(cp_logger_type), POINTER :: logger
425 
426  NULLIFY (logger)
427  logger => cp_get_default_logger()
428 
429  ! TODO use write_particle_coordinates from particle_methods.F
430  DO i = 1, nnp%n_committee
431  WRITE (fmt_string, *) i
432  WRITE (middle_name, "(A,A)") "nnp-forces-", adjustl(trim(fmt_string))
433  unit_nr = cp_print_key_unit_nr(logger, print_key, extension=".xyz", &
434  middle_name=trim(middle_name))
435  IF (unit_nr > 0) THEN
436  WRITE (unit_nr, *) nnp%num_atoms
437  WRITE (unit_nr, "(A,1X,A,A,F20.9)") "NNP forces [a.u.] of committee member", &
438  adjustl(trim(fmt_string)), "energy [a.u.]=", nnp%committee_energy(i)
439 
440  fmt_string = "(A4,1X,3F20.10)"
441  DO j = 1, nnp%num_atoms
442  WRITE (unit_nr, fmt_string) nnp%atoms(nnp%sort_inv(j)), nnp%committee_forces(:, j, i)
443  END DO
444  END IF
445  CALL cp_print_key_finished_output(unit_nr, logger, print_key)
446  END DO
447 
448  END SUBROUTINE nnp_print_forces
449 
450 ! **************************************************************************************************
451 !> \brief Print standard deviation sigma of NNP forces
452 !> \param nnp ...
453 !> \param unit_nr ...
454 !> \date 2020-10-10
455 !> \author Christoph Schran (christoph.schran@rub.de)
456 ! **************************************************************************************************
457  SUBROUTINE nnp_print_force_sigma(nnp, unit_nr)
458  TYPE(nnp_type), INTENT(INOUT) :: nnp
459  INTEGER, INTENT(IN) :: unit_nr
460 
461  INTEGER :: i, j
462  REAL(kind=dp), DIMENSION(3) :: var
463 
464  IF (unit_nr > 0) THEN
465  WRITE (unit_nr, *) nnp%num_atoms
466  WRITE (unit_nr, "(A,1X,A)") "NNP sigma of forces [a.u.]"
467 
468  DO i = 1, nnp%num_atoms
469  var = 0.0_dp
470  DO j = 1, nnp%n_committee
471  var = var + (nnp%committee_forces(:, i, j) - nnp%nnp_forces(:, i))**2
472  END DO
473  var = var/real(nnp%n_committee, dp)
474  var = sqrt(var)
475  WRITE (unit_nr, "(A4,1X,3F20.10)") nnp%atoms(nnp%sort_inv(i)), var
476  END DO
477  END IF
478 
479  END SUBROUTINE nnp_print_force_sigma
480 
481 ! **************************************************************************************************
482 !> \brief Print structures with extrapolation warning
483 !> \param nnp ...
484 !> \param unit_nr ...
485 !> \date 2020-10-10
486 !> \author Christoph Schran (christoph.schran@rub.de)
487 ! **************************************************************************************************
488  SUBROUTINE nnp_print_expol(nnp, unit_nr)
489  TYPE(nnp_type), INTENT(INOUT) :: nnp
490  INTEGER, INTENT(IN) :: unit_nr
491 
492  CHARACTER(len=default_path_length) :: fmt_string
493  INTEGER :: i
494  REAL(kind=dp) :: mass, unit_conv
495  REAL(kind=dp), DIMENSION(3) :: com
496 
497  nnp%expol = nnp%expol + 1
498  WRITE (unit_nr, *) nnp%num_atoms
499  WRITE (unit_nr, "(A,1X,I6)") "NNP extrapolation point N =", nnp%expol
500 
501  ! move to COM of solute and wrap the box
502  ! coord not needed afterwards, therefore manipulation ok
503  com = 0.0_dp
504  mass = 0.0_dp
505  DO i = 1, nnp%num_atoms
506  CALL get_ptable_info(nnp%atoms(i), amass=unit_conv)
507  com(:) = com(:) + nnp%coord(:, i)*unit_conv
508  mass = mass + unit_conv
509  END DO
510  com(:) = com(:)/mass
511 
512  DO i = 1, nnp%num_atoms
513  nnp%coord(:, i) = nnp%coord(:, i) - com(:)
514  END DO
515 
516  ! write out coordinates
517  unit_conv = cp_unit_from_cp2k(1.0_dp, trim("angstrom"))
518  fmt_string = "(A4,1X,3F20.10)"
519  DO i = 1, nnp%num_atoms
520  WRITE (unit_nr, fmt_string) &
521  nnp%atoms(nnp%sort_inv(i)), &
522  nnp%coord(1, nnp%sort_inv(i))*unit_conv, &
523  nnp%coord(2, nnp%sort_inv(i))*unit_conv, &
524  nnp%coord(3, nnp%sort_inv(i))*unit_conv
525  END DO
526 
527  END SUBROUTINE nnp_print_expol
528 
529 ! **************************************************************************************************
530 !> \brief Print properties number according the requests in input file
531 !> \param nnp ...
532 !> \param print_section ...
533 !> \date 2020-10-10
534 !> \author Christoph Schran (christoph.schran@rub.de)
535 ! **************************************************************************************************
536  SUBROUTINE nnp_print_bias(nnp, print_section)
537  TYPE(nnp_type), INTENT(INOUT) :: nnp
538  TYPE(section_vals_type), INTENT(IN), POINTER :: print_section
539 
540  INTEGER :: unit_nr
541  LOGICAL :: file_is_new
542  TYPE(cp_logger_type), POINTER :: logger
543  TYPE(section_vals_type), POINTER :: print_key
544 
545  NULLIFY (logger, print_key)
546  logger => cp_get_default_logger()
547 
548  print_key => section_vals_get_subs_vals(print_section, "BIAS_ENERGY")
549  IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
550  unit_nr = cp_print_key_unit_nr(logger, print_key, extension=".data", &
551  middle_name="nnp-bias-energy", is_new_file=file_is_new)
552  IF (unit_nr > 0) CALL nnp_print_bias_energy(nnp, unit_nr, file_is_new)
553  CALL cp_print_key_finished_output(unit_nr, logger, print_key)
554  END IF
555 
556  print_key => section_vals_get_subs_vals(print_section, "BIAS_FORCES")
557  IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
558  unit_nr = cp_print_key_unit_nr(logger, print_key, extension=".xyz", &
559  middle_name="nnp-bias-forces")
560  IF (unit_nr > 0) CALL nnp_print_bias_forces(nnp, unit_nr)
561  CALL cp_print_key_finished_output(unit_nr, logger, print_key)
562  END IF
563 
564  END SUBROUTINE nnp_print_bias
565 
566 ! **************************************************************************************************
567 !> \brief Print NNP bias energies
568 !> \param nnp ...
569 !> \param unit_nr ...
570 !> \param file_is_new ...
571 !> \date 2020-10-10
572 !> \author Christoph Schran (christoph.schran@rub.de)
573 ! **************************************************************************************************
574  SUBROUTINE nnp_print_bias_energy(nnp, unit_nr, file_is_new)
575  TYPE(nnp_type), INTENT(INOUT) :: nnp
576  INTEGER, INTENT(IN) :: unit_nr
577  LOGICAL, INTENT(IN) :: file_is_new
578 
579  CHARACTER(len=default_path_length) :: fmt_string
580  INTEGER :: i
581 
582  IF (file_is_new) THEN
583  WRITE (unit_nr, "(A1)", advance='no') "#"
584  WRITE (unit_nr, "(2(2X,A19))", advance='no') "Sigma [a.u.]", "Bias energy [a.u.]"
585  DO i = 1, nnp%n_committee
586  IF (nnp%bias_align) THEN
587  WRITE (unit_nr, "(2X,A16,I3)", advance='no') "shifted E_NNP", i
588  ELSE
589  WRITE (unit_nr, "(2X,A16,I3)", advance='no') "E_NNP", i
590  END IF
591  END DO
592  WRITE (unit_nr, "(A)") ""
593 
594  END IF
595 
596  WRITE (fmt_string, "(A,I3,A)") "(2X,", nnp%n_committee + 2, "(F20.9,1X))"
597  WRITE (unit_nr, fmt_string) nnp%bias_sigma, nnp%bias_energy, nnp%committee_energy
598 
599  END SUBROUTINE nnp_print_bias_energy
600 
601 ! **************************************************************************************************
602 !> \brief Print NNP bias forces
603 !> \param nnp ...
604 !> \param unit_nr ...
605 !> \date 2020-10-10
606 !> \author Christoph Schran (christoph.schran@rub.de)
607 ! **************************************************************************************************
608  SUBROUTINE nnp_print_bias_forces(nnp, unit_nr)
609  TYPE(nnp_type), INTENT(INOUT) :: nnp
610  INTEGER, INTENT(IN) :: unit_nr
611 
612  CHARACTER(len=default_path_length) :: fmt_string
613  INTEGER :: i
614 
615  ! TODO use write_particle_coordinates from particle_methods.F
616  WRITE (unit_nr, *) nnp%num_atoms
617  WRITE (unit_nr, "(A,F20.9)") "NNP bias forces [a.u.] for bias energy [a.u]=", nnp%bias_energy
618 
619  fmt_string = "(A4,1X,3F20.10)"
620  DO i = 1, nnp%num_atoms
621  WRITE (unit_nr, fmt_string) nnp%atoms(nnp%sort_inv(i)), nnp%bias_forces(:, i)
622  END DO
623 
624  END SUBROUTINE nnp_print_bias_forces
625 
626 ! **************************************************************************************************
627 !> \brief Print NNP summed forces
628 !> \param nnp ...
629 !> \param print_section ...
630 !> \param unit_nr ...
631 !> \param file_is_new ...
632 !> \date 2020-10-10
633 !> \author Christoph Schran (christoph.schran@rub.de)
634 ! **************************************************************************************************
635  SUBROUTINE nnp_print_sumforces(nnp, print_section, unit_nr, file_is_new)
636  TYPE(nnp_type), INTENT(INOUT) :: nnp
637  TYPE(section_vals_type), INTENT(IN), POINTER :: print_section
638  INTEGER, INTENT(IN) :: unit_nr
639  LOGICAL, INTENT(IN) :: file_is_new
640 
641  CHARACTER(len=default_path_length) :: fmt_string
642  CHARACTER(LEN=default_string_length), &
643  DIMENSION(:), POINTER :: atomlist
644  INTEGER :: i, ig, j, n
645  REAL(kind=dp), DIMENSION(3) :: rvec
646 
647  NULLIFY (atomlist)
648  IF (file_is_new) THEN
649  WRITE (unit_nr, "(A)") "# Summed forces [a.u.]"
650  END IF
651 
652  rvec = 0.0_dp
653 
654  ! get atoms to sum over:
655  CALL section_vals_val_get(print_section, "SUM_FORCE%ATOM_LIST", &
656  c_vals=atomlist)
657  IF (ASSOCIATED(atomlist)) THEN
658  n = SIZE(atomlist)
659  DO i = 1, nnp%num_atoms
660  DO j = 1, n
661  ig = nnp%sort_inv(i)
662  IF (trim(adjustl(atomlist(j))) == trim(adjustl(nnp%atoms(ig)))) THEN
663  rvec(:) = rvec(:) + nnp%nnp_forces(:, i)
664  END IF
665  END DO
666  END DO
667  END IF
668 
669  fmt_string = "(3(F20.10,1X))"
670  WRITE (unit_nr, fmt_string) rvec
671 
672  END SUBROUTINE nnp_print_sumforces
673 
674 END MODULE nnp_force
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 ...
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...
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)
...
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...
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)
returns information about various attributes of the given subsys
unit conversion facility
Definition: cp_units.F:30
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Definition: cp_units.F:1179
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public default_string_length
Definition: kinds.F:57
integer, parameter, public default_path_length
Definition: kinds.F:58
Functionality for atom centered symmetry functions for neural network potentials.
Definition: nnp_acsf.F:14
subroutine, public nnp_calc_acsf(nnp, i, dsymdxyz, stress)
Calculate atom centered symmetry functions for given atom i.
Definition: nnp_acsf.F:59
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.
Definition: nnp_force.F:13
subroutine, public nnp_calc_energy_force(nnp, calc_forces)
Calculate the energy and force for a given configuration with the NNP.
Definition: nnp_force.F:62
Methods dealing with core routines for artificial neural networks.
Definition: nnp_model.F:13
subroutine, public nnp_predict(arc, nnp, i_com)
Predict energy by evaluating neural network.
Definition: nnp_model.F:82
subroutine, public nnp_gradients(arc, nnp, i_com, denergydsym)
Calculate gradients of neural network.
Definition: nnp_model.F:169
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:
Definition: physcon.F:68
real(kind=dp), parameter, public angstrom
Definition: physcon.F:144