(git:374b731)
Loading...
Searching...
No Matches
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! **************************************************************************************************
14
18 USE cp_output_handling, ONLY: cp_p_file,&
29 USE kinds, ONLY: default_path_length,&
31 dp
32 USE nnp_acsf, ONLY: nnp_calc_acsf
35 USE nnp_model, ONLY: nnp_gradients,&
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
52CONTAINS
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
674END 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
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.
Main data type collecting all relevant data for neural network potentials.