(git:374b731)
Loading...
Searching...
No Matches
helium_interactions.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 that handle helium-solvent and helium-helium interactions
10!> \author Lukasz Walewski
11!> \date 2009-06-10
12! **************************************************************************************************
14
22 USE helium_types, ONLY: e_id_interact,&
36 USE kinds, ONLY: dp
37 USE nnp_acsf, ONLY: nnp_calc_acsf
39 USE nnp_model, ONLY: nnp_gradients,&
41 USE physcon, ONLY: angstrom,&
42 kelvin
43 USE pint_types, ONLY: pint_env_type
45#include "../base/base_uses.f90"
46
47 IMPLICIT NONE
48
49 PRIVATE
50
51 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
52 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'helium_interactions'
53
54 PUBLIC :: helium_calc_energy
58 PUBLIC :: helium_solute_e_f
60 PUBLIC :: helium_intpot_scan
61 PUBLIC :: helium_vij
62
63CONTAINS
64
65! ***************************************************************************
66!> \brief Calculate the helium energy (including helium-solute interaction)
67!> \param helium helium environment
68!> \param pint_env path integral environment
69!> \par History
70!> 2009-06 moved I/O out from here [lwalewski]
71!> \author hforbert
72! **************************************************************************************************
73 SUBROUTINE helium_calc_energy(helium, pint_env)
74 TYPE(helium_solvent_type), INTENT(INOUT) :: helium
75 TYPE(pint_env_type), INTENT(IN) :: pint_env
76
77 INTEGER :: b, bead, i, j, n
78 INTEGER, DIMENSION(:), POINTER :: perm
79 LOGICAL :: nperiodic
80 REAL(kind=dp) :: a, cell_size, en, interac, kin, pot, &
81 rmax, rmin, vkin
82 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: work2, work3
83 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: work
84 REAL(kind=dp), DIMENSION(3) :: r
85 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: pos
86 TYPE(spline_data_type), POINTER :: e0
87
88 pos => helium%pos
89 perm => helium%permutation
90 e0 => helium%e0
91 cell_size = 0.5_dp*helium%cell_size
92 nperiodic = .NOT. helium%periodic
93 n = helium%atoms
94 b = helium%beads
95 en = 0.0_dp
96 pot = 0.0_dp
97 rmin = 1.0e20_dp
98 rmax = 0.0_dp
99 ALLOCATE (work(3, helium%beads + 1), &
100 work2(helium%beads + 1), &
101 work3(SIZE(helium%uoffdiag, 1) + 1))
102 DO i = 1, n - 1
103 DO j = i + 1, n
104 DO bead = 1, b
105 work(:, bead) = pos(:, i, bead) - pos(:, j, bead)
106 END DO
107 work(:, b + 1) = pos(:, perm(i), 1) - pos(:, perm(j), 1)
108 en = en + helium_eval_chain(helium, work, b + 1, work2, work3, energy=.true.)
109 DO bead = 1, b
110 a = work2(bead)
111 IF (a < rmin) rmin = a
112 IF (a > rmax) rmax = a
113 IF ((a < cell_size) .OR. nperiodic) THEN
114 pot = pot + helium_spline(helium%vij, a)
115 END IF
116 END DO
117 END DO
118 END DO
119 DEALLOCATE (work, work2, work3)
120 pot = pot/b
121 en = en/b
122
123 ! helium-solute interaction energy (all beads of all particles)
124 interac = 0.0_dp
125 IF (helium%solute_present) THEN
126 CALL helium_solute_e(pint_env, helium, interac)
127 END IF
128 interac = interac/b
129
130!TODO:
131 vkin = 0.0_dp
132! vkin = helium_virial_energy(helium)
133
134 kin = 0.0_dp
135 DO i = 1, n
136 r(:) = pos(:, i, b) - pos(:, perm(i), 1)
137 CALL helium_pbc(helium, r)
138 kin = kin + r(1)*r(1) + r(2)*r(2) + r(3)*r(3)
139 DO bead = 2, b
140 r(:) = pos(:, i, bead - 1) - pos(:, i, bead)
141 CALL helium_pbc(helium, r)
142 kin = kin + r(1)*r(1) + r(2)*r(2) + r(3)*r(3)
143 END DO
144 END DO
145 kin = 1.5_dp*n/helium%tau - 0.5*kin/(b*helium%tau**2*helium%hb2m)
146
147! TODO: move printing somewhere else ?
148! print *,"POT = ",(pot/n+helium%e_corr)*kelvin,"K"
149! print *,"INTERAC = ",interac*kelvin,"K"
150! print *,"RMIN= ",rmin*angstrom,"A"
151! print *,"RMAX= ",rmax*angstrom,"A"
152! print *,"EVIRIAL not valid!"
153! print *,"ETHERMO= ",((en+kin)/n+helium%e_corr)*kelvin,"K"
154! print *,"ECORR= ",helium%e_corr*kelvin,"K"
155!! kin = helium_total_action(helium)
156!! print *,"ACTION= ",kin
157! print *,"WINDING#= ",helium_calc_winding(helium)
158
159 helium%energy_inst(e_id_potential) = pot/n + helium%e_corr
160 helium%energy_inst(e_id_kinetic) = (en - pot + kin)/n
161 helium%energy_inst(e_id_interact) = interac
162 helium%energy_inst(e_id_thermo) = (en + kin)/n + helium%e_corr
163 helium%energy_inst(e_id_virial) = vkin ! 0.0_dp at the moment
164 helium%energy_inst(e_id_total) = helium%energy_inst(e_id_thermo)
165 ! Once vkin is properly implemented, switch to:
166 ! helium%energy_inst(e_id_total) = (en+vkin)/n+helium%e_corr
167
168 END SUBROUTINE helium_calc_energy
169
170! ***************************************************************************
171!> \brief Computes the total harmonic link action of the helium
172!> \param helium ...
173!> \return ...
174!> \date 2016-05-03
175!> \author Felix Uhl
176! **************************************************************************************************
177 REAL(kind=dp) FUNCTION helium_total_link_action(helium) RESULT(linkaction)
178
179 TYPE(helium_solvent_type), INTENT(IN) :: helium
180
181 INTEGER :: iatom, ibead
182 INTEGER, DIMENSION(:), POINTER :: perm
183 REAL(kind=dp), DIMENSION(3) :: r
184
185 perm => helium%permutation
186 linkaction = 0.0_dp
187
188 ! Harmonic Link action
189 ! (r(m-1) - r(m))**2/(4*lambda*tau)
190 DO ibead = 1, helium%beads - 1
191 DO iatom = 1, helium%atoms
192 r(:) = helium%pos(:, iatom, ibead) - helium%pos(:, iatom, ibead + 1)
193 CALL helium_pbc(helium, r)
194 linkaction = linkaction + (r(1)*r(1) + r(2)*r(2) + r(3)*r(3))
195 END DO
196 END DO
197 DO iatom = 1, helium%atoms
198 ! choose last bead connection according to permutation table
199 r(:) = helium%pos(:, iatom, helium%beads) - helium%pos(:, perm(iatom), 1)
200 CALL helium_pbc(helium, r)
201 linkaction = linkaction + (r(1)*r(1) + r(2)*r(2) + r(3)*r(3))
202 END DO
203 linkaction = linkaction/(2.0_dp*helium%tau*helium%hb2m)
204
205 END FUNCTION helium_total_link_action
206
207! ***************************************************************************
208!> \brief Computes the total pair action of the helium
209!> \param helium ...
210!> \return ...
211!> \date 2016-05-03
212!> \author Felix Uhl
213! **************************************************************************************************
214 REAL(kind=dp) FUNCTION helium_total_pair_action(helium) RESULT(pairaction)
215
216 TYPE(helium_solvent_type), INTENT(INOUT) :: helium
217
218 INTEGER :: iatom, ibead, jatom, opatom, patom
219 INTEGER, DIMENSION(:), POINTER :: perm
220 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: work3
221 REAL(kind=dp), DIMENSION(3) :: r, rp
222
223 ALLOCATE (work3(SIZE(helium%uoffdiag, 1) + 1))
224 perm => helium%permutation
225 pairaction = 0.0_dp
226
227 ! He-He pair action
228 DO ibead = 1, helium%beads - 1
229 DO iatom = 1, helium%atoms - 1
230 DO jatom = iatom + 1, helium%atoms
231 r(:) = helium%pos(:, iatom, ibead) - helium%pos(:, jatom, ibead)
232 rp(:) = helium%pos(:, iatom, ibead + 1) - helium%pos(:, jatom, ibead + 1)
233 pairaction = pairaction + helium_eval_expansion(helium, r, rp, work3)
234 END DO
235 END DO
236 END DO
237 !Ensure right permutation for pair action of last and first beads.
238 DO iatom = 1, helium%atoms - 1
239 DO jatom = iatom + 1, helium%atoms
240 r(:) = helium%pos(:, iatom, helium%beads) - helium%pos(:, jatom, helium%beads)
241 rp(:) = helium%pos(:, perm(iatom), 1) - helium%pos(:, perm(jatom), 1)
242 pairaction = pairaction + helium_eval_expansion(helium, r, rp, work3)
243 END DO
244 END DO
245
246 ! correct for open worm configurations
247 IF (.NOT. helium%worm_is_closed) THEN
248 ! special treatment if double bead is first bead
249 iatom = helium%worm_atom_idx
250 IF (helium%worm_bead_idx == 1) THEN
251 ! patom is the atom in front of the lone head bead
252 patom = helium%iperm(iatom)
253 ! go through all atoms
254 DO jatom = 1, helium%atoms
255 IF (jatom == helium%worm_atom_idx) cycle
256 opatom = helium%iperm(jatom)
257 ! subtract pair action for closed link
258 r(:) = helium%pos(:, iatom, 1) - helium%pos(:, jatom, 1)
259 rp(:) = helium%pos(:, patom, helium%beads) - helium%pos(:, opatom, helium%beads)
260 pairaction = pairaction - helium_eval_expansion(helium, r, rp, work3)
261 ! and add corrected extra link
262 ! rp stays the same
263 r(:) = helium%worm_xtra_bead(:) - helium%pos(:, jatom, 1)
264 pairaction = pairaction + helium_eval_expansion(helium, r, rp, work3)
265 END DO
266 ELSE
267 ! bead stays constant
268 ibead = helium%worm_bead_idx
269 ! go through all atoms
270 DO jatom = 1, helium%atoms
271 IF (jatom == helium%worm_atom_idx) cycle
272 ! subtract pair action for closed link
273 r(:) = helium%pos(:, iatom, ibead) - helium%pos(:, jatom, ibead)
274 rp(:) = helium%pos(:, iatom, ibead - 1) - helium%pos(:, jatom, ibead - 1)
275 pairaction = pairaction - helium_eval_expansion(helium, r, rp, work3)
276 ! and add corrected extra link
277 ! rp stays the same
278 r(:) = helium%worm_xtra_bead(:) - helium%pos(:, jatom, ibead)
279 pairaction = pairaction + helium_eval_expansion(helium, r, rp, work3)
280 END DO
281 END IF
282 END IF
283 DEALLOCATE (work3)
284
285 END FUNCTION helium_total_pair_action
286
287! ***************************************************************************
288!> \brief Computes the total interaction of the helium with the solute
289!> \param pint_env ...
290!> \param helium ...
291!> \return ...
292!> \date 2016-05-03
293!> \author Felix Uhl
294! **************************************************************************************************
295 REAL(kind=dp) FUNCTION helium_total_inter_action(pint_env, helium) RESULT(interaction)
296
297 TYPE(pint_env_type), INTENT(IN) :: pint_env
298 TYPE(helium_solvent_type), INTENT(IN) :: helium
299
300 INTEGER :: iatom, ibead
301 REAL(kind=dp) :: e
302
303 interaction = 0.0_dp
304
305 ! InterAction with solute
306 IF (helium%solute_present) THEN
307 DO ibead = 1, helium%beads
308 DO iatom = 1, helium%atoms
309
310 CALL helium_bead_solute_e_f(pint_env, helium, &
311 iatom, ibead, helium%pos(:, iatom, ibead), e)
312 interaction = interaction + e
313 END DO
314 END DO
315 IF (helium%sampling_method == helium_sampling_worm) THEN
316 IF (.NOT. helium%worm_is_closed) THEN
317 ! subtract half of tail bead interaction again
318 CALL helium_bead_solute_e_f(pint_env, helium, &
319 helium%worm_atom_idx, helium%worm_bead_idx, &
320 helium%pos(:, helium%worm_atom_idx, helium%worm_bead_idx), e)
321 interaction = interaction - 0.5_dp*e
322 ! add half of head bead interaction
323 CALL helium_bead_solute_e_f(pint_env, helium, &
324 helium%worm_atom_idx, helium%worm_bead_idx, &
325 helium%worm_xtra_bead, e)
326 interaction = interaction + 0.5_dp*e
327 END IF
328 END IF
329 END IF
330
331 interaction = interaction*helium%tau
332
333 END FUNCTION helium_total_inter_action
334
335! ***************************************************************************
336!> \brief Calculate general helium-solute interaction energy (and forces)
337!> between one helium bead and the corresponding solute time slice.
338!> \param pint_env path integral environment
339!> \param helium ...
340!> \param helium_part_index helium particle index
341!> \param helium_slice_index helium time slice index
342!> \param helium_r_opt explicit helium bead coordinates (optional)
343!> \param energy calculated energy
344!> \param force calculated force (if requested)
345!> \par History
346!> 2019-09 Added multiple-time striding in imag. time [cschran]
347!> 2023-07-23 Modified to work with NNP solute-solvent interactions [lduran]
348!> \author Lukasz Walewski
349! **************************************************************************************************
350 SUBROUTINE helium_bead_solute_e_f(pint_env, helium, helium_part_index, &
351 helium_slice_index, helium_r_opt, energy, force)
352
353 TYPE(pint_env_type), INTENT(IN) :: pint_env
354 TYPE(helium_solvent_type), INTENT(IN) :: helium
355 INTEGER, INTENT(IN) :: helium_part_index, helium_slice_index
356 REAL(kind=dp), DIMENSION(3), INTENT(IN), OPTIONAL :: helium_r_opt
357 REAL(kind=dp), INTENT(OUT) :: energy
358 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT), &
359 OPTIONAL, POINTER :: force
360
361 INTEGER :: hbeads, hi, qi, stride
362 REAL(kind=dp), DIMENSION(3) :: helium_r
363 REAL(kind=dp), DIMENSION(:), POINTER :: my_force
364
365 hbeads = helium%beads
366 ! helium bead index that is invariant wrt the rotations
367 hi = mod(helium_slice_index - 1 + hbeads + helium%relrot, hbeads) + 1
368 ! solute bead index that belongs to hi helium index
369 qi = ((hi - 1)*pint_env%p)/hbeads + 1
370
371 ! coordinates of the helium bead
372 IF (PRESENT(helium_r_opt)) THEN
373 helium_r(:) = helium_r_opt(:)
374 ELSE
375 helium_r(:) = helium%pos(:, helium_part_index, helium_slice_index)
376 END IF
377
378 SELECT CASE (helium%solute_interaction)
379
381 IF (PRESENT(force)) THEN
382 force(:, :) = 0.0_dp
383 my_force => force(qi, :)
384 CALL helium_intpot_model_water( &
385 pint_env%x(qi, :), &
386 helium, &
387 helium_r, &
388 energy, &
389 my_force &
390 )
391 ELSE
392 CALL helium_intpot_model_water( &
393 pint_env%x(qi, :), &
394 helium, &
395 helium_r, &
396 energy &
397 )
398 END IF
399
401 IF (PRESENT(force)) THEN
402 force(:, :) = 0.0_dp
403 my_force => force(qi, :)
404 CALL helium_intpot_nnp( &
405 pint_env%x(qi, :), &
406 helium, &
407 helium_r, &
408 energy, &
409 my_force &
410 )
411 ELSE
412 CALL helium_intpot_nnp( &
413 pint_env%x(qi, :), &
414 helium, &
415 helium_r, &
416 energy &
417 )
418 END IF
419
421 energy = 0.0_dp
422 IF (PRESENT(force)) THEN
423 force(:, :) = 0.0_dp
424 END IF
425
426 CASE DEFAULT
427
428 END SELECT
429
430 ! Account for Imaginary time striding in forces:
431 IF (PRESENT(force)) THEN
432 IF (hbeads < pint_env%p) THEN
433 stride = pint_env%p/hbeads
434 force = force*real(stride, dp)
435 END IF
436 END IF
437
438 END SUBROUTINE helium_bead_solute_e_f
439
440! ***************************************************************************
441!> \brief Calculate total helium-solute interaction energy and forces.
442!> \param pint_env path integral environment
443!> \param helium ...
444!> \param energy calculated interaction energy
445!> \author Lukasz Walewski
446! **************************************************************************************************
447 SUBROUTINE helium_solute_e_f(pint_env, helium, energy)
448
449 TYPE(pint_env_type), INTENT(IN) :: pint_env
450 TYPE(helium_solvent_type), INTENT(INOUT) :: helium
451 REAL(kind=dp), INTENT(OUT) :: energy
452
453 INTEGER :: ia, ib, jb, jc
454 REAL(kind=dp) :: my_energy
455 REAL(kind=dp), DIMENSION(:, :), POINTER :: force
456
457 NULLIFY (force)
458 force => helium%force_inst
459
460 energy = 0.0_dp
461 force(:, :) = 0.0_dp
462
463 ! calculate the total interaction energy and gradients between the
464 ! solute and the helium, sum over all beads of all He particles
465 DO ia = 1, helium%atoms
466 DO ib = 1, helium%beads
467 CALL helium_bead_solute_e_f(pint_env, helium, ia, ib, &
468 energy=my_energy, force=helium%rtmp_p_ndim_2d)
469 energy = energy + my_energy
470 DO jb = 1, pint_env%p
471 DO jc = 1, pint_env%ndim
472 force(jb, jc) = force(jb, jc) + helium%rtmp_p_ndim_2d(jb, jc)
473 END DO
474 END DO
475 END DO
476 END DO
477
478 END SUBROUTINE helium_solute_e_f
479
480! ***************************************************************************
481!> \brief Calculate total helium-solute interaction energy.
482!> \param pint_env path integral environment
483!> \param helium ...
484!> \param energy calculated interaction energy
485!> \author Lukasz Walewski
486! **************************************************************************************************
487 SUBROUTINE helium_solute_e(pint_env, helium, energy)
488
489 TYPE(pint_env_type), INTENT(IN) :: pint_env
490 TYPE(helium_solvent_type), INTENT(IN) :: helium
491 REAL(kind=dp), INTENT(OUT) :: energy
492
493 INTEGER :: ia, ib
494 REAL(kind=dp) :: my_energy
495
496 energy = 0.0_dp
497
498 DO ia = 1, helium%atoms
499 DO ib = 1, helium%beads
500 CALL helium_bead_solute_e_f(pint_env, helium, ia, ib, energy=my_energy)
501 energy = energy + my_energy
502 END DO
503 END DO
504
505 END SUBROUTINE helium_solute_e
506
507! ***************************************************************************
508!> \brief Scan the helium-solute interaction energy within the periodic cell
509!> \param pint_env ...
510!> \param helium_env ...
511!> \date 2014-01-22
512!> \par History
513!> 2016-07-14 Modified to work with independent helium_env [cschran]
514!> \author Lukasz Walewski
515! **************************************************************************************************
516 SUBROUTINE helium_intpot_scan(pint_env, helium_env)
517
518 TYPE(pint_env_type), INTENT(IN) :: pint_env
519 TYPE(helium_solvent_p_type), DIMENSION(:), POINTER :: helium_env
520
521 CHARACTER(len=*), PARAMETER :: routinen = 'helium_intpot_scan'
522
523 INTEGER :: handle, ic, ix, iy, iz, k, nbin
524 LOGICAL :: wrapped
525 REAL(kind=dp) :: delr, my_en, ox, oy, oz
526 REAL(kind=dp), DIMENSION(3) :: pbc1, pbc2, pos
527
528 CALL timeset(routinen, handle)
529
530 ! Perform scan only on ionode, since this is only used to output the intpot
531 IF (pint_env%logger%para_env%is_source()) THEN
532 ! Assume ionode always to have at least one helium_env
533 k = 1
534 helium_env(k)%helium%rho_inst(1, :, :, :) = 0.0_dp
535 nbin = helium_env(k)%helium%rho_nbin
536 delr = helium_env(k)%helium%rho_delr
537 helium_env(k)%helium%center(:) = 0.0_dp
538 ox = helium_env(k)%helium%center(1) - helium_env(k)%helium%rho_maxr/2.0_dp
539 oy = helium_env(k)%helium%center(2) - helium_env(k)%helium%rho_maxr/2.0_dp
540 oz = helium_env(k)%helium%center(3) - helium_env(k)%helium%rho_maxr/2.0_dp
541
542 DO ix = 1, nbin
543 DO iy = 1, nbin
544 DO iz = 1, nbin
545
546 ! put the probe in the center of the current voxel
547 pos(:) = (/ox + (ix - 0.5_dp)*delr, oy + (iy - 0.5_dp)*delr, oz + (iz - 0.5_dp)*delr/)
548
549 ! calc interaction energy for the current probe position
550 helium_env(k)%helium%pos(:, 1, 1) = pos(:)
551 CALL helium_bead_solute_e_f(pint_env, helium_env(k)%helium, 1, 1, energy=my_en)
552
553 ! check if the probe fits within the unit cell
554 pbc1(:) = pos(:) - helium_env(k)%helium%center
555 pbc2(:) = pbc1(:)
556 CALL helium_pbc(helium_env(k)%helium, pbc2)
557 wrapped = .false.
558 DO ic = 1, 3
559 IF (abs(pbc1(ic) - pbc2(ic)) .GT. 10.0_dp*epsilon(0.0_dp)) THEN
560 wrapped = .true.
561 END IF
562 END DO
563
564 ! set the interaction energy value
565 IF (wrapped) THEN
566 helium_env(k)%helium%rho_inst(1, ix, iy, iz) = 0.0_dp
567 ELSE
568 helium_env(k)%helium%rho_inst(1, ix, iy, iz) = my_en
569 END IF
570
571 END DO
572 END DO
573 END DO
574 END IF
575
576 CALL timestop(handle)
577 END SUBROUTINE helium_intpot_scan
578
579! ***************************************************************************
580!> \brief Calculate model helium-solute interaction energy and forces
581!> between one helium bead and the corresponding solute time
582!> slice asuming water solute.
583!> \param solute_x solute positions ARR(3*NATOMS)
584!> to global atom indices
585!> \param helium only needed for helium_pbc call at the moment
586!> \param helium_x helium bead position ARR(3)
587!> \param energy calculated interaction energy
588!> \param force ...
589!> \author Felix Uhl
590! **************************************************************************************************
591 SUBROUTINE helium_intpot_model_water(solute_x, helium, helium_x, energy, force)
592
593 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: solute_x
594 TYPE(helium_solvent_type), INTENT(IN) :: helium
595 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: helium_x
596 REAL(kind=dp), INTENT(OUT) :: energy
597 REAL(kind=dp), DIMENSION(:), INTENT(INOUT), &
598 OPTIONAL, POINTER :: force
599
600 INTEGER :: i, ig
601 REAL(kind=dp) :: d, d2, dd, ep, eps, s1, s2, sig
602 REAL(kind=dp), DIMENSION(3) :: dr, solute_r
603
604 energy = 0.0_dp
605 IF (PRESENT(force)) THEN
606 force(:) = 0.0_dp
607 END IF
608
609 sig = 2.69_dp ! 1.4 Angstrom
610 eps = 60.61e-6_dp ! 19 K
611 s1 = 0.0_dp
612 DO i = 1, SIZE(helium%solute_element)
613 IF (helium%solute_element(i) == "H ") THEN
614 ig = i - 1
615 solute_r(1) = solute_x(3*ig + 1)
616 solute_r(2) = solute_x(3*ig + 2)
617 solute_r(3) = solute_x(3*ig + 3)
618 dr(:) = solute_r(:) - helium_x(:)
619 CALL helium_pbc(helium, dr)
620 d2 = dr(1)*dr(1) + dr(2)*dr(2) + dr(3)*dr(3)
621 d = sqrt(d2)
622 dd = (sig/d)**6
623 ep = 4.0_dp*eps*dd*(dd - 1.0_dp)
624 s1 = s1 + ep
625 s2 = 24.0_dp*eps*dd*(2.0_dp*dd - 1.0_dp)/d2
626 IF (PRESENT(force)) THEN
627 force(3*ig + 1) = force(3*ig + 1) + s2*dr(1)
628 force(3*ig + 2) = force(3*ig + 2) + s2*dr(2)
629 force(3*ig + 3) = force(3*ig + 3) + s2*dr(3)
630 END IF
631 END IF
632 END DO ! i = 1, num_hydrogen
633 energy = energy + s1
634
635 sig = 5.01_dp ! 2.6 Angstrom
636 eps = 104.5e-6_dp ! 33 K
637 s1 = 0.0_dp
638 DO i = 1, SIZE(helium%solute_element)
639 IF (helium%solute_element(i) == "O ") THEN
640 ig = i - 1
641 solute_r(1) = solute_x(3*ig + 1)
642 solute_r(2) = solute_x(3*ig + 2)
643 solute_r(3) = solute_x(3*ig + 3)
644 dr(:) = solute_r(:) - helium_x(:)
645 CALL helium_pbc(helium, dr)
646 d2 = dr(1)*dr(1) + dr(2)*dr(2) + dr(3)*dr(3)
647 d = sqrt(d2)
648 dd = (sig/d)**6
649 ep = 4.0_dp*eps*dd*(dd - 1.0_dp)
650 s1 = s1 + ep
651 s2 = 24.0_dp*eps*dd*(2.0_dp*dd - 1.0_dp)/d2
652 IF (PRESENT(force)) THEN
653 force(3*ig + 1) = force(3*ig + 1) + s2*dr(1)
654 force(3*ig + 2) = force(3*ig + 2) + s2*dr(2)
655 force(3*ig + 3) = force(3*ig + 3) + s2*dr(3)
656 END IF
657 END IF
658 END DO ! i = 1, num_chlorine
659 energy = energy + s1
660
661 END SUBROUTINE helium_intpot_model_water
662
663! ***************************************************************************
664!> \brief Calculate helium-solute interaction energy and forces between one
665!> helium bead and the corresponding solute time slice using NNP.
666!> \param solute_x solute positions ARR(3*NATOMS)
667!> to global atom indices
668!> \param helium only needed for helium_pbc call at the moment
669!> \param helium_x helium bead position ARR(3)
670!> \param energy calculated interaction energy
671!> \param force (optional) calculated force
672!> \date 2023-02-22
673!> \author Laura Duran
674! **************************************************************************************************
675 SUBROUTINE helium_intpot_nnp(solute_x, helium, helium_x, energy, force)
676
677 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: solute_x
678 TYPE(helium_solvent_type), INTENT(IN) :: helium
679 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: helium_x
680 REAL(kind=dp), INTENT(OUT) :: energy
681 REAL(kind=dp), DIMENSION(:), INTENT(INOUT), &
682 OPTIONAL, POINTER :: force
683
684 INTEGER :: i, i_com, ig, ind, ind_he, j, k, m
685 LOGICAL :: extrapolate
686 REAL(kind=dp) :: rsqr, rvect(3), threshold
687 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: denergydsym
688 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: dsymdxyz
689 TYPE(cp_logger_type), POINTER :: logger
690 TYPE(nnp_type), POINTER :: nnp
691 TYPE(section_vals_type), POINTER :: print_section
692
693 NULLIFY (logger)
694 logger => cp_get_default_logger()
695
696 IF (PRESENT(force)) THEN
697 helium%nnp%myforce(:, :, :) = 0.0_dp
698 END IF
699
700 extrapolate = .false.
701 threshold = 0.0001d0
702
703 !fill coord array
704 ig = 1
705 DO i = 1, helium%nnp%n_ele
706 IF (helium%nnp%ele(i) == 'He') THEN
707 ind_he = ig
708 DO m = 1, 3
709 helium%nnp%coord(m, ig) = helium_x(m)
710 END DO
711 ig = ig + 1
712 END IF
713 DO j = 1, helium%solute_atoms
714 IF (helium%nnp%ele(i) == helium%solute_element(j)) THEN
715 DO m = 1, 3
716 helium%nnp%coord(m, ig) = solute_x(3*(j - 1) + m)
717 END DO
718 ig = ig + 1
719 END IF
720 END DO
721 END DO
722
723 ! check for hard core condition
724 IF (ASSOCIATED(helium%nnp_sr_cut)) THEN
725 DO i = 1, helium%nnp%num_atoms
726 IF (i == ind_he) cycle
727 rvect(:) = helium%nnp%coord(:, i) - helium%nnp%coord(:, ind_he)
728 CALL helium_pbc(helium, rvect)
729 rsqr = rvect(1)*rvect(1) + rvect(2)*rvect(2) + rvect(3)*rvect(3)
730 IF (rsqr < helium%nnp_sr_cut(helium%nnp%ele_ind(i))) THEN
731 energy = 0.3_dp + 1.0_dp/rsqr
732 IF (PRESENT(force)) THEN
733 force = 0.0_dp
734 END IF
735 RETURN
736 END IF
737 END DO
738 END IF
739
740 ! reset flag if there's an extrapolation to report:
741 helium%nnp%output_expol = .false.
742
743 ! calc atomic contribution to energy and force
744!NOTE corresponds to nnp_force line with parallelization:
745!DO i = istart, istart + mecalc - 1
746 DO i = 1, helium%nnp%num_atoms
747
748 !determine index of atom type
749 ind = helium%nnp%ele_ind(i)
750
751 !reset input nodes and grads of ele(ind):
752 helium%nnp%arc(ind)%layer(1)%node(:) = 0.0_dp
753 nnp => helium%nnp ! work around wrong INTENT of nnp_calc_acsf
754 IF (PRESENT(force)) THEN
755 helium%nnp%arc(ind)%layer(1)%node_grad(:) = 0.0_dp
756 ALLOCATE (dsymdxyz(3, helium%nnp%arc(ind)%n_nodes(1), helium%nnp%num_atoms))
757 ALLOCATE (denergydsym(helium%nnp%arc(ind)%n_nodes(1)))
758 dsymdxyz(:, :, :) = 0.0_dp
759 CALL nnp_calc_acsf(nnp, i, dsymdxyz)
760 ELSE
761 CALL nnp_calc_acsf(nnp, i)
762 END IF
763
764 ! input nodes filled, perform prediction:
765 DO i_com = 1, helium%nnp%n_committee !loop over committee members
766 ! Predict energy
767 CALL nnp_predict(helium%nnp%arc(ind), helium%nnp, i_com)
768 helium%nnp%atomic_energy(i, i_com) = helium%nnp%arc(ind)%layer(helium%nnp%n_layer)%node(1) ! + helium%nnp%atom_energies(ind)
769
770 !Gradients
771 IF (PRESENT(force)) THEN
772
773 denergydsym(:) = 0.0_dp
774
775 CALL nnp_gradients(helium%nnp%arc(ind), helium%nnp, i_com, denergydsym)
776 DO j = 1, helium%nnp%arc(ind)%n_nodes(1)
777 DO k = 1, helium%nnp%num_atoms
778 DO m = 1, 3
779 helium%nnp%myforce(m, k, i_com) = helium%nnp%myforce(m, k, i_com) &
780 - denergydsym(j)*dsymdxyz(m, j, k)
781 END DO
782 END DO
783 END DO
784
785 END IF
786 END DO ! end loop over committee members
787
788 !deallocate memory
789 IF (PRESENT(force)) THEN
790 DEALLOCATE (denergydsym)
791 DEALLOCATE (dsymdxyz)
792 END IF
793
794 END DO ! end loop over num_atoms
795
796 ! calculate energy:
797 helium%nnp%committee_energy(:) = sum(helium%nnp%atomic_energy, 1)
798 energy = sum(helium%nnp%committee_energy)/real(helium%nnp%n_committee, dp)
799 helium%nnp%nnp_potential_energy = energy
800
801 IF (PRESENT(force)) THEN
802 ! bring myforce to force array
803 DO j = 1, helium%nnp%num_atoms
804 DO k = 1, 3
805 helium%nnp%committee_forces(k, j, :) = helium%nnp%myforce(k, j, :)
806 END DO
807 END DO
808 helium%nnp%nnp_forces(:, :) = sum(helium%nnp%committee_forces, dim=3)/real(helium%nnp%n_committee, dp)
809 ! project out helium force entry
810 ig = 1
811 DO j = 1, helium%nnp%num_atoms
812 IF (j == ind_he) cycle
813 DO k = 1, 3
814 force(3*(helium%nnp%sort(ig) - 1) + k) = helium%nnp%nnp_forces(k, j)
815 END DO
816 ig = ig + 1
817 END DO
818 END IF
819
820 ! print properties if requested
821 print_section => section_vals_get_subs_vals(helium%nnp%nnp_input, "PRINT")
822 CALL helium_nnp_print(helium%nnp, print_section, ind_he)
823
824 RETURN
825
826 END SUBROUTINE helium_intpot_nnp
827
828! ***************************************************************************
829!> \brief Helium-helium pair interaction potential.
830!> \param r ...
831!> \return ...
832! **************************************************************************************************
833 ELEMENTAL FUNCTION helium_vij(r) RESULT(vij)
834
835 REAL(kind=dp), INTENT(IN) :: r
836 REAL(kind=dp) :: vij
837
838 REAL(kind=dp) :: f, x, x2
839
840 x = angstrom*r/2.9673_dp
841 IF (x < 1.241314_dp) THEN
842 x2 = 1.241314_dp/x - 1.0_dp
843 f = exp(-x2*x2)
844 ELSE
845 f = 1.0_dp
846 END IF
847 x2 = 1.0_dp/(x*x)
848 vij = 10.8_dp/kelvin*(544850.4_dp*exp(-13.353384_dp*x) - f* &
849 ((0.1781_dp*x2 + 0.4253785_dp)*x2 + 1.3732412_dp)*x2*x2*x2)
850 END FUNCTION helium_vij
851
852#if 0
853
854 ! this block is currently turned off
855
856! ***************************************************************************
857!> \brief Helium-helium pair interaction potential's derivative.
858!> \param r ...
859!> \return ...
860! **************************************************************************************************
861 ELEMENTAL FUNCTION helium_d_vij(r) RESULT(dvij)
862
863 REAL(kind=dp), INTENT(IN) :: r
864 REAL(kind=dp) :: dvij
865
866 REAL(kind=dp) :: f, fp, x, x2, y
867
868 x = angstrom*r/2.9673_dp
869 x = r/2.9673_dp
870 x2 = 1.0_dp/(x*x)
871 IF (x < 1.241314_dp) THEN
872 y = 1.241314_dp/x - 1.0_dp
873 f = exp(-y*y)
874 fp = 2.0_dp*1.241314_dp*f*y* &
875 ((0.1781_dp*x2 + 0.4253785_dp)*x2 + 1.3732412_dp)*x2*x2*x2*x2
876 ELSE
877 f = 1.0_dp
878 fp = 0.0_dp
879 END IF
880
881 dvij = angstrom*(10.8_dp/2.9673_dp)*( &
882 (-13.353384_dp*544850.4_dp)*exp(-13.353384_dp*x) - fp + &
883 f*(((10.0_dp*0.1781_dp)*x2 + (8.0_dp*0.4253785_dp))*x2 + (6.0_dp*1.3732412_dp))* &
884 x2*x2*x2/x)/(r*kelvin)
885 END FUNCTION helium_d_vij
886
887! **************************************************************************************************
888!> \brief ...
889!> \param helium ...
890!> \param n ...
891!> \param i ...
892!> \return ...
893! **************************************************************************************************
894 FUNCTION helium_atom_action(helium, n, i) RESULT(res)
895
896 TYPE(helium_solvent_type), INTENT(INOUT) :: helium
897 INTEGER, INTENT(IN) :: n, i
898 REAL(kind=dp) :: res
899
900 INTEGER :: c, j
901 REAL(kind=dp) :: r(3), rp(3), s, t
902 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: work3
903
904 ALLOCATE (work3(SIZE(helium%uoffdiag, 1) + 1))
905 s = 0.0_dp
906 t = 0.0_dp
907 IF (n < helium%beads) THEN
908 DO c = 1, 3
909 r(c) = helium%pos(c, i, n) - helium%pos(c, i, n + 1)
910 END DO
911 CALL helium_pbc(helium, r)
912 t = r(1)*r(1) + r(2)*r(2) + r(3)*r(3)
913 DO j = 1, i - 1
914 DO c = 1, 3
915 r(c) = helium%pos(c, i, n) - helium%pos(c, j, n)
916 rp(c) = helium%pos(c, i, n + 1) - helium%pos(c, j, n + 1)
917 END DO
918 s = s + helium_eval_expansion(helium, r, rp, work3)
919 END DO
920 DO j = i + 1, helium%atoms
921 DO c = 1, 3
922 r(c) = helium%pos(c, i, n) - helium%pos(c, j, n)
923 rp(c) = helium%pos(c, i, n + 1) - helium%pos(c, j, n + 1)
924 END DO
925 s = s + helium_eval_expansion(helium, r, rp, work3)
926 END DO
927 ELSE
928 DO c = 1, 3
929 r(c) = helium%pos(c, i, n) - helium%pos(c, helium%permutation(i), 1)
930 END DO
931 CALL helium_pbc(helium, r)
932 t = r(1)*r(1) + r(2)*r(2) + r(3)*r(3)
933 DO j = 1, i - 1
934 DO c = 1, 3
935 r(c) = helium%pos(c, i, n) - helium%pos(c, j, n)
936 rp(c) = helium%pos(c, helium%permutation(i), 1) - helium%pos(c, helium%permutation(j), 1)
937 END DO
938 s = s + helium_eval_expansion(helium, r, rp, work3)
939 END DO
940 DO j = i + 1, helium%atoms
941 DO c = 1, 3
942 r(c) = helium%pos(c, i, n) - helium%pos(c, j, n)
943 rp(c) = helium%pos(c, helium%permutation(i), 1) - helium%pos(c, helium%permutation(j), 1)
944 END DO
945 s = s + helium_eval_expansion(helium, r, rp, work3)
946 END DO
947 END IF
948 t = t/(2.0_dp*helium%tau*helium%hb2m)
949 s = s*0.5_dp
950 res = s + t
951 DEALLOCATE (work3)
952
953 END FUNCTION helium_atom_action
954
955! **************************************************************************************************
956!> \brief ...
957!> \param helium ...
958!> \param n ...
959!> \return ...
960! **************************************************************************************************
961 FUNCTION helium_link_action(helium, n) RESULT(res)
962
963 TYPE(helium_solvent_type), INTENT(INOUT) :: helium
964 INTEGER, INTENT(IN) :: n
965 REAL(kind=dp) :: res
966
967 INTEGER :: c, i, j
968 REAL(kind=dp) :: r(3), rp(3), s, t
969 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: work3
970
971 ALLOCATE (work3(SIZE(helium%uoffdiag, 1) + 1))
972 s = 0.0_dp
973 t = 0.0_dp
974 IF (n < helium%beads) THEN
975 DO i = 1, helium%atoms
976 DO c = 1, 3
977 r(c) = helium%pos(c, i, n) - helium%pos(c, i, n + 1)
978 END DO
979 CALL helium_pbc(helium, r)
980 t = t + r(1)*r(1) + r(2)*r(2) + r(3)*r(3)
981 DO j = 1, i - 1
982 DO c = 1, 3
983 r(c) = helium%pos(c, i, n) - helium%pos(c, j, n)
984 rp(c) = helium%pos(c, i, n + 1) - helium%pos(c, j, n + 1)
985 END DO
986 s = s + helium_eval_expansion(helium, r, rp, work3)
987 END DO
988 END DO
989 ELSE
990 DO i = 1, helium%atoms
991 DO c = 1, 3
992 r(c) = helium%pos(c, i, n) - helium%pos(c, helium%permutation(i), 1)
993 END DO
994 CALL helium_pbc(helium, r)
995 t = t + r(1)*r(1) + r(2)*r(2) + r(3)*r(3)
996 DO j = 1, i - 1
997 DO c = 1, 3
998 r(c) = helium%pos(c, i, n) - helium%pos(c, j, n)
999 rp(c) = helium%pos(c, helium%permutation(i), 1) - helium%pos(c, helium%permutation(j), 1)
1000 END DO
1001 s = s + helium_eval_expansion(helium, r, rp, work3)
1002 END DO
1003 END DO
1004 END IF
1005 t = t/(2.0_dp*helium%tau*helium%hb2m)
1006 res = s + t
1007 DEALLOCATE (work3)
1008
1009 END FUNCTION helium_link_action
1010
1011! **************************************************************************************************
1012!> \brief ...
1013!> \param helium ...
1014!> \return ...
1015! **************************************************************************************************
1016 FUNCTION helium_total_action(helium) RESULT(res)
1017
1018 TYPE(helium_solvent_type), INTENT(INOUT) :: helium
1019 REAL(kind=dp) :: res
1020
1021 INTEGER :: i
1022 REAL(kind=dp) :: s
1023
1024 s = 0.0_dp
1025 DO i = 1, helium%beads
1026 s = s + helium_link_action(helium, i)
1027 END DO
1028 res = s
1029
1030 END FUNCTION helium_total_action
1031
1032! **************************************************************************************************
1033!> \brief ...
1034!> \param helium ...
1035!> \param part ...
1036!> \param ref_bead ...
1037!> \param delta_bead ...
1038!> \param d ...
1039! **************************************************************************************************
1040 SUBROUTINE helium_delta_pos(helium, part, ref_bead, delta_bead, d)
1041
1042 TYPE(helium_solvent_type), INTENT(INOUT) :: helium
1043 INTEGER, INTENT(IN) :: part, ref_bead, delta_bead
1044 REAL(kind=dp), DIMENSION(3), INTENT(OUT) :: d
1045
1046 INTEGER :: b, bead, db, nbead, np, p
1047 REAL(kind=dp), DIMENSION(3) :: r
1048
1049 b = helium%beads
1050
1051 d(:) = 0.0_dp
1052 IF (delta_bead > 0) THEN
1053 bead = ref_bead
1054 p = part
1055 db = delta_bead
1056 DO
1057 IF (db < 1) EXIT
1058 nbead = bead + 1
1059 np = p
1060 IF (nbead > b) THEN
1061 nbead = nbead - b
1062 np = helium%permutation(np)
1063 END IF
1064 r(:) = helium%pos(:, p, bead) - helium%pos(:, np, nbead)
1065 CALL helium_pbc(helium, r)
1066 d(:) = d(:) + r(:)
1067 bead = nbead
1068 p = np
1069 db = db - 1
1070 END DO
1071 ELSEIF (delta_bead < 0) THEN
1072 bead = ref_bead
1073 p = part
1074 db = delta_bead
1075 DO
1076 IF (db >= 0) EXIT
1077 nbead = bead - 1
1078 np = p
1079 IF (nbead < 1) THEN
1080 nbead = nbead + b
1081 np = helium%iperm(np)
1082 END IF
1083 r(:) = helium%pos(:, p, bead) - helium%pos(:, np, nbead)
1084 CALL helium_pbc(helium, r)
1085 d(:) = d(:) + r(:)
1086 bead = nbead
1087 p = np
1088 db = db + 1
1089 END DO
1090 END IF
1091 END SUBROUTINE helium_delta_pos
1092
1093#endif
1094
1095END MODULE helium_interactions
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
Independent helium subroutines shared with other modules.
subroutine, public helium_pbc(helium, r, enforce)
General PBC routine for helium.
real(kind=dp) function, public helium_eval_chain(helium, rchain, nchain, aij, vcoef, energy)
Calculate the pair-product action or energy by evaluating the power series expansion according to Eq....
real(kind=dp) function, public helium_eval_expansion(helium, r, rp, work, action)
Calculate the pair-product action or energy by evaluating the power series expansion according to Eq....
real(kind=dp) function, public helium_spline(spl, xx)
...
Methods that handle helium-solvent and helium-helium interactions.
subroutine, public helium_solute_e_f(pint_env, helium, energy)
Calculate total helium-solute interaction energy and forces.
real(kind=dp) function, public helium_total_pair_action(helium)
Computes the total pair action of the helium.
real(kind=dp) function, public helium_total_inter_action(pint_env, helium)
Computes the total interaction of the helium with the solute.
subroutine, public helium_intpot_scan(pint_env, helium_env)
Scan the helium-solute interaction energy within the periodic cell.
subroutine, public helium_bead_solute_e_f(pint_env, helium, helium_part_index, helium_slice_index, helium_r_opt, energy, force)
Calculate general helium-solute interaction energy (and forces) between one helium bead and the corre...
elemental real(kind=dp) function, public helium_vij(r)
Helium-helium pair interaction potential.
subroutine, public helium_calc_energy(helium, pint_env)
Calculate the helium energy (including helium-solute interaction)
real(kind=dp) function, public helium_total_link_action(helium)
Computes the total harmonic link action of the helium.
Methods dealing with Neural Network interaction potential.
Definition helium_nnp.F:13
subroutine, public helium_nnp_print(nnp, print_section, ind_he)
Print properties according to the requests in input file.
Definition helium_nnp.F:168
Data types representing superfluid helium.
integer, parameter, public e_id_potential
integer, parameter, public e_id_thermo
integer, parameter, public e_id_virial
integer, parameter, public e_id_interact
integer, parameter, public e_id_kinetic
integer, parameter, public e_id_total
Energy contributions - symbolic names for indexing energy arrays.
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public helium_solute_intpot_mwater
integer, parameter, public helium_solute_intpot_none
integer, parameter, public helium_sampling_worm
integer, parameter, public helium_solute_intpot_nnp
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
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
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.
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
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public kelvin
Definition physcon.F:165
real(kind=dp), parameter, public angstrom
Definition physcon.F:144
routines for handling splines_types
type of a logger, at the moment it contains just a print level starting at which level it should be l...
data structure for array of solvent helium environments
data structure for solvent helium
Main data type collecting all relevant data for neural network potentials.
environment for a path integral run
Definition pint_types.F:112
Data-structure that holds all needed information about a specific spline interpolation.