31 #include "../base/base_uses.f90"
36 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
37 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'helium_worm'
51 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
52 TYPE(pint_env_type),
INTENT(IN) :: pint_env
54 CHARACTER(len=default_string_length) :: stmp
55 INTEGER :: ac, iatom, ibead, icrawl, imc, imove, ncentracc, ncentratt, ncloseacc, ncloseatt, &
56 ncrawlbwdacc, ncrawlbwdatt, ncrawlfwdacc, ncrawlfwdatt, ncycle, nmc, nmoveheadacc, &
57 nmoveheadatt, nmovetailacc, nmovetailatt, nopenacc, nopenatt, npswapacc, nstagacc, &
58 nstagatt, nstat, nswapacc, nswapatt, ntot, staging_l
84 helium%proarea%inst(:) = 0.d0
85 helium%prarea2%inst(:) = 0.d0
86 helium%wnumber%inst(:) = 0.d0
87 helium%wnmber2%inst(:) = 0.d0
88 helium%mominer%inst(:) = 0.d0
89 IF (helium%solute_present) helium%force_avrg(:, :) = 0.0d0
90 helium%energy_avrg(:) = 0.0d0
91 helium%plength_avrg(:) = 0.0d0
92 IF (helium%worm_max_open_cycles > 0)
THEN
93 helium%savepos(:, :, :) = helium%pos(:, :, :)
94 helium%saveiperm(:) = helium%iperm(:)
95 helium%savepermutation(:) = helium%permutation(:)
100 IF (helium%worm_allow_open)
THEN
103 imove = helium%rng_stream_uniform%next(1, helium%worm_all_limit)
104 IF (helium%worm_is_closed)
THEN
105 IF ((imove >= helium%worm_centroid_min) .AND. (imove <= helium%worm_centroid_max))
THEN
107 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
108 CALL worm_centroid_move(pint_env, helium, &
109 iatom, helium%worm_centroid_drmax, ac)
110 ncentratt = ncentratt + 1
111 ncentracc = ncentracc + ac
114 ELSE IF ((imove >= helium%worm_centroid_max + 1) .AND. (imove <= helium%worm_open_close_min - 1))
THEN
116 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
117 ibead = helium%rng_stream_uniform%next(1, helium%beads)
118 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
119 CALL worm_staging_move(pint_env, helium, &
120 iatom, ibead, staging_l, ac)
121 nstagatt = nstagatt + 1
122 nstagacc = nstagacc + ac
123 ELSE IF ((imove >= helium%worm_open_close_min) .AND. (imove <= helium%worm_open_close_max))
THEN
125 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
126 ibead = helium%rng_stream_uniform%next(1, helium%beads)
127 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
128 CALL worm_open_move(pint_env, helium, &
129 iatom, ibead, staging_l, ac)
130 nopenatt = nopenatt + 1
131 nopenacc = nopenacc + ac
134 cpabort(
"Undefined move selected in helium worm sampling!")
137 IF ((imove >= helium%worm_centroid_min) .AND. (imove <= helium%worm_centroid_max))
THEN
139 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
140 CALL worm_centroid_move(pint_env, helium, &
141 iatom, helium%worm_centroid_drmax, ac)
142 ncentratt = ncentratt + 1
143 ncentracc = ncentracc + ac
144 ELSE IF ((imove >= helium%worm_staging_min) .AND. (imove <= helium%worm_staging_max))
THEN
146 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
147 ibead = helium%rng_stream_uniform%next(1, helium%beads)
148 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
149 CALL worm_staging_move(pint_env, helium, &
150 iatom, ibead, staging_l, ac)
151 nstagatt = nstagatt + 1
152 nstagacc = nstagacc + ac
153 ELSE IF ((imove >= helium%worm_fcrawl_min) .AND. (imove <= helium%worm_fcrawl_max))
THEN
155 DO icrawl = 1, helium%worm_repeat_crawl
156 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
157 CALL worm_crawl_move_forward(pint_env, helium, &
159 ncrawlfwdatt = ncrawlfwdatt + 1
160 ncrawlfwdacc = ncrawlfwdacc + ac
162 ELSE IF ((imove >= helium%worm_bcrawl_min) .AND. (imove <= helium%worm_bcrawl_max))
THEN
164 DO icrawl = 1, helium%worm_repeat_crawl
165 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
166 CALL worm_crawl_move_backward(pint_env, helium, &
168 ncrawlbwdatt = ncrawlbwdatt + 1
169 ncrawlbwdacc = ncrawlbwdacc + ac
171 ELSE IF ((imove >= helium%worm_head_min) .AND. (imove <= helium%worm_head_max))
THEN
173 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
174 CALL worm_head_move(pint_env, helium, &
176 nmoveheadatt = nmoveheadatt + 1
177 nmoveheadacc = nmoveheadacc + ac
178 ELSE IF ((imove >= helium%worm_tail_min) .AND. (imove <= helium%worm_tail_max))
THEN
180 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
181 CALL worm_tail_move(pint_env, helium, &
183 nmovetailatt = nmovetailatt + 1
184 nmovetailacc = nmovetailacc + ac
185 ELSE IF ((imove >= helium%worm_swap_min) .AND. (imove <= helium%worm_swap_max))
THEN
186 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
187 CALL worm_swap_move(pint_env, helium, &
188 helium%atoms, staging_l, ac)
189 npswapacc = npswapacc + ac
190 nswapacc = nswapacc + ac
191 nswapatt = nswapatt + 1
192 ELSE IF ((imove >= helium%worm_open_close_min) .AND. (imove <= helium%worm_open_close_max))
THEN
194 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
195 CALL worm_close_move(pint_env, helium, &
197 ncloseatt = ncloseatt + 1
198 ncloseacc = ncloseacc + ac
201 cpabort(
"Undefined move selected in helium worm sampling!")
206 IF (helium%worm_is_closed)
THEN
208 IF (helium%solute_present)
THEN
212 helium%force_avrg(:, :) = helium%force_avrg(:, :) + helium%force_inst(:, :)
219 IF (helium%worm_is_closed)
THEN
225 IF (helium%worm_max_open_cycles > 0 .AND. ncycle > helium%worm_max_open_cycles)
THEN
226 nmc = helium%iter_rot
228 helium%pos = helium%savepos
229 helium%work = helium%pos
230 helium%permutation = helium%savepermutation
231 helium%iperm = helium%saveiperm
232 cpwarn(
"Trapped in open state, reset helium to closed state from last MD step.")
234 nmc = max(helium%iter_rot/10, 10)
240 imove = helium%rng_stream_uniform%next(1, helium%worm_all_limit)
242 IF ((imove >= helium%worm_centroid_min) .AND. (imove <= helium%worm_centroid_max))
THEN
244 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
245 CALL worm_centroid_move(pint_env, helium, &
246 iatom, helium%worm_centroid_drmax, ac)
247 ncentratt = ncentratt + 1
248 ncentracc = ncentracc + ac
249 ELSE IF ((imove >= helium%worm_staging_min) .AND. (imove <= helium%worm_staging_max))
THEN
251 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
252 ibead = helium%rng_stream_uniform%next(1, helium%beads)
253 CALL worm_staging_move(pint_env, helium, &
254 iatom, ibead, helium%worm_staging_l, ac)
255 nstagatt = nstagatt + 1
256 nstagacc = nstagacc + ac
259 cpabort(
"Undefined move selected in helium worm sampling!")
265 IF (helium%solute_present)
THEN
269 helium%force_avrg(:, :) = helium%force_avrg(:, :) + helium%force_inst(:, :)
276 helium%num_accepted(1, 1) = ncentracc + nstagacc + nopenacc + ncloseacc + nswapacc + &
277 nmoveheadacc + nmovetailacc + ncrawlfwdacc + ncrawlbwdacc
278 helium%num_accepted(2, 1) = ncentratt + nstagatt + nopenatt + ncloseatt + nswapatt + &
279 nmoveheadatt + nmovetailatt + ncrawlfwdatt + ncrawlbwdatt
280 helium%worm_nstat = nstat
285 helium%energy_avrg(:) = helium%energy_inst(:)*real(helium%worm_nstat,
dp)
288 helium%plength_avrg(:) = helium%plength_inst(:)*real(helium%worm_nstat,
dp)
291 IF (helium%solute_present)
THEN
294 helium%force_avrg(:, :) = helium%force_avrg(:, :) + helium%force_inst(:, :)
298 IF (helium%worm_show_statistics)
THEN
299 WRITE (stmp, *)
'--------------------------------------------------'
301 WRITE (stmp,
'(A10,F15.5,2I10)')
'Opening: ', &
302 REAL(nopenacc,
dp)/
REAL(MAX(1, nopenatt), dp), &
305 WRITE (stmp,
'(A10,F15.5,2I10)')
'Closing: ', &
306 REAL(ncloseacc,
dp)/
REAL(MAX(1, ncloseatt), dp), &
309 WRITE (stmp,
'(A10,F15.5,2I10)')
'Move Head: ', &
310 REAL(nmoveheadacc,
dp)/
REAL(MAX(1, nmoveheadatt), dp), &
311 nmoveheadacc, nmoveheadatt
313 WRITE (stmp,
'(A10,F15.5,2I10)')
'Move Tail: ', &
314 REAL(nmovetailacc,
dp)/
REAL(MAX(1, nmovetailatt), dp), &
315 nmovetailacc, nmovetailatt
317 WRITE (stmp,
'(A10,F15.5,2I10)')
'Crawl FWD: ', &
318 REAL(ncrawlfwdacc,
dp)/
REAL(MAX(1, ncrawlfwdatt), dp), &
319 ncrawlfwdacc, ncrawlfwdatt
321 WRITE (stmp,
'(A10,F15.5,2I10)')
'Crawl BWD: ', &
322 REAL(ncrawlbwdacc,
dp)/
REAL(MAX(1, ncrawlbwdatt), dp), &
323 ncrawlbwdacc, ncrawlbwdatt
325 WRITE (stmp,
'(A10,F15.5,2I10)')
'Staging: ', &
326 REAL(nstagacc,
dp)/
REAL(MAX(1, nstagatt), dp), &
329 WRITE (stmp,
'(A10,F15.5,2I10)')
'Centroid: ', &
330 REAL(ncentracc,
dp)/
REAL(MAX(1, ncentratt), dp), &
333 WRITE (stmp,
'(A10,F15.5,2I10)')
'Select: ', &
334 REAL(npswapacc,
dp)/
REAL(MAX(1, nswapatt), dp), &
337 WRITE (stmp,
'(A10,F15.5,2I10)')
'Swapping: ', &
338 REAL(nswapacc,
dp)/
REAL(MAX(1, nswapatt), dp), &
341 WRITE (stmp, *)
"Open State Probability: ", real(ntot - nstat,
dp)/real(max(1, ntot),
dp), ntot - nstat, ntot
343 WRITE (stmp, *)
"Closed State Probability: ", real(nstat,
dp)/real(max(1, ntot),
dp), nstat, ntot
360 SUBROUTINE worm_centroid_move(pint_env, helium, iatom, drmax, ac)
362 TYPE(pint_env_type),
INTENT(IN) :: pint_env
363 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
364 INTEGER,
INTENT(IN) :: iatom
365 REAL(kind=
dp),
INTENT(IN) :: drmax
366 INTEGER,
INTENT(OUT) :: ac
368 INTEGER :: ia, ib, ic, jatom
369 LOGICAL :: should_reject, worm_in_moved_cycle
370 REAL(kind=
dp) :: rtmp, rtmpo, sdiff, snew, sold
371 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
374 rtmp = helium%rng_stream_uniform%next()
375 dr(ic) = (2.0_dp*rtmp - 1.0_dp)*drmax
378 IF (helium%worm_is_closed)
THEN
379 worm_in_moved_cycle = .false.
381 DO ib = 1, helium%beads
382 helium%work(:, iatom, ib) = helium%work(:, iatom, ib) + dr(:)
385 jatom = helium%permutation(iatom)
386 DO WHILE (jatom /= iatom)
387 DO ib = 1, helium%beads
388 helium%work(:, jatom, ib) = helium%work(:, jatom, ib) + dr(:)
391 jatom = helium%permutation(jatom)
394 worm_in_moved_cycle = (helium%worm_atom_idx == iatom)
397 DO ib = 1, helium%beads
398 helium%work(:, iatom, ib) = helium%work(:, iatom, ib) + dr(:)
401 jatom = helium%permutation(iatom)
402 DO WHILE (jatom /= iatom)
403 DO ib = 1, helium%beads
404 helium%work(:, jatom, ib) = helium%work(:, jatom, ib) + dr(:)
406 worm_in_moved_cycle = worm_in_moved_cycle .OR. (helium%worm_atom_idx == jatom)
408 jatom = helium%permutation(jatom)
411 IF (worm_in_moved_cycle)
THEN
412 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:) + dr(:)
416 sold = worm_centroid_move_action(helium, helium%pos, iatom, &
417 helium%worm_xtra_bead, worm_in_moved_cycle)
419 snew = worm_centroid_move_action(helium, helium%work, iatom, &
420 helium%worm_xtra_bead_work, worm_in_moved_cycle)
422 IF (helium%solute_present)
THEN
423 sold = sold + worm_centroid_move_inter_action(pint_env, helium, helium%pos, iatom, &
424 helium%worm_xtra_bead, worm_in_moved_cycle)
425 snew = snew + worm_centroid_move_inter_action(pint_env, helium, helium%work, iatom, &
426 helium%worm_xtra_bead_work, worm_in_moved_cycle)
432 should_reject = .false.
433 IF (sdiff < -100.0_dp)
THEN
434 should_reject = .true.
436 rtmp = helium%rng_stream_uniform%next()
437 IF (exp(sdiff) < rtmp)
THEN
438 should_reject = .true.
441 IF (should_reject)
THEN
444 DO ib = 1, helium%beads
445 helium%work(:, iatom, ib) = helium%pos(:, iatom, ib)
448 jatom = helium%permutation(iatom)
449 DO WHILE (jatom /= iatom)
450 DO ib = 1, helium%beads
451 helium%work(:, jatom, ib) = helium%pos(:, jatom, ib)
454 jatom = helium%permutation(jatom)
456 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
466 IF (.NOT. helium%periodic)
THEN
467 IF (helium%solute_present)
THEN
468 new_com(:) = helium%center(:)
469 old_com(:) = new_com(:)
472 DO ia = 1, helium%atoms
473 DO ib = 1, helium%beads
474 new_com(:) = new_com(:) + helium%work(:, ia, ib)
477 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
480 DO ia = 1, helium%atoms
481 DO ib = 1, helium%beads
482 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
485 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
487 should_reject = .false.
488 atom:
DO ia = 1, helium%atoms
490 DO ib = 1, helium%beads
491 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
493 dr(:) = dr(:)/real(helium%beads,
dp)
494 rtmp = dot_product(dr, dr)
495 IF (rtmp >= helium%droplet_radius**2)
THEN
497 DO ib = 1, helium%beads
498 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
500 dro(:) = dro(:)/real(helium%beads,
dp)
501 rtmpo = dot_product(dro, dro)
503 IF (rtmpo < rtmp)
THEN
505 should_reject = .true.
510 IF (should_reject)
THEN
513 DO ib = 1, helium%beads
514 helium%work(:, iatom, ib) = helium%pos(:, iatom, ib)
517 jatom = helium%permutation(iatom)
518 DO WHILE (jatom /= iatom)
519 DO ib = 1, helium%beads
520 helium%work(:, jatom, ib) = helium%pos(:, jatom, ib)
523 jatom = helium%permutation(jatom)
525 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
534 DO ib = 1, helium%beads
535 helium%pos(:, iatom, ib) = helium%work(:, iatom, ib)
538 jatom = helium%permutation(iatom)
539 DO WHILE (jatom /= iatom)
540 DO ib = 1, helium%beads
541 helium%pos(:, jatom, ib) = helium%work(:, jatom, ib)
544 jatom = helium%permutation(jatom)
546 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
548 END SUBROUTINE worm_centroid_move
560 REAL(kind=
dp)
FUNCTION worm_centroid_move_action(helium, pos, iatom, xtrapos, winc) &
563 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
564 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
566 INTEGER,
INTENT(IN) :: iatom
567 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xtrapos
568 LOGICAL,
INTENT(IN) :: winc
570 INTEGER :: ia, ib, jatom, katom, opatom, patom, &
573 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work2, work3
574 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: work
575 REAL(kind=
dp),
DIMENSION(3) :: r, rp
577 ALLOCATE (work(3, helium%beads + 1), work2(helium%beads + 1), work3(
SIZE(helium%uoffdiag, 1) + 1))
585 DO ia = 1, helium%atoms
586 IF (ia == jatom) cycle
588 katom = helium%permutation(jatom)
589 DO WHILE (katom /= jatom)
590 IF (katom == ia)
THEN
594 katom = helium%permutation(katom)
598 DO ib = 1, helium%beads
599 work(:, ib) = pos(:, ia, ib) - pos(:, jatom, ib)
601 work(:, helium%beads + 1) = pos(:, helium%permutation(ia), 1) - &
602 pos(:, helium%permutation(jatom), 1)
603 partaction = partaction +
helium_eval_chain(helium, work, helium%beads + 1, work2, work3)
606 jatom = helium%permutation(iatom)
607 DO WHILE (jatom /= iatom)
608 DO ia = 1, helium%atoms
609 IF (ia == jatom) cycle
611 katom = helium%permutation(jatom)
612 DO WHILE (katom /= jatom)
613 IF (katom == ia)
THEN
617 katom = helium%permutation(katom)
621 DO ib = 1, helium%beads
622 work(:, ib) = pos(:, ia, ib) - pos(:, jatom, ib)
624 work(:, helium%beads + 1) = pos(:, helium%permutation(ia), 1) - &
625 pos(:, helium%permutation(jatom), 1)
626 partaction = partaction +
helium_eval_chain(helium, work, helium%beads + 1, work2, work3)
628 jatom = helium%permutation(jatom)
631 IF (.NOT. helium%worm_is_closed)
THEN
632 wbead = helium%worm_bead_idx
634 IF (helium%worm_bead_idx == 1)
THEN
636 patom = helium%iperm(helium%worm_atom_idx)
638 DO ia = 1, helium%atoms
639 IF (ia == helium%worm_atom_idx) cycle
641 katom = helium%permutation(helium%worm_atom_idx)
642 DO WHILE (katom /= helium%worm_atom_idx)
643 IF (katom == ia)
THEN
647 katom = helium%permutation(katom)
652 opatom = helium%iperm(ia)
655 r(:) = pos(:, helium%worm_atom_idx, 1) - pos(:, ia, 1)
656 rp(:) = pos(:, patom, helium%beads) - pos(:, opatom, helium%beads)
660 r(:) = xtrapos(:) - pos(:, ia, 1)
666 DO ia = 1, helium%atoms
667 IF (ia == helium%worm_atom_idx) cycle
669 katom = helium%permutation(helium%worm_atom_idx)
670 DO WHILE (katom /= helium%worm_atom_idx)
671 IF (katom == ia)
THEN
675 katom = helium%permutation(katom)
680 r(:) = pos(:, helium%worm_atom_idx, wbead) - pos(:, ia, wbead)
681 rp(:) = pos(:, helium%worm_atom_idx, wbead - 1) - pos(:, ia, wbead - 1)
685 r(:) = xtrapos(:) - pos(:, ia, wbead)
690 IF (helium%worm_bead_idx == 1)
THEN
692 patom = helium%iperm(helium%worm_atom_idx)
693 opatom = helium%iperm(iatom)
695 r(:) = pos(:, helium%worm_atom_idx, 1) - pos(:, iatom, 1)
696 rp(:) = pos(:, patom, helium%beads) - pos(:, opatom, helium%beads)
700 r(:) = xtrapos(:) - pos(:, iatom, 1)
703 ia = helium%permutation(iatom)
704 DO WHILE (ia /= iatom)
705 opatom = helium%iperm(ia)
707 r(:) = pos(:, helium%worm_atom_idx, 1) - pos(:, ia, 1)
708 rp(:) = pos(:, patom, helium%beads) - pos(:, opatom, helium%beads)
712 r(:) = xtrapos(:) - pos(:, ia, 1)
714 ia = helium%permutation(ia)
719 r(:) = pos(:, helium%worm_atom_idx, wbead) - pos(:, iatom, wbead)
720 rp(:) = pos(:, helium%worm_atom_idx, wbead - 1) - pos(:, iatom, wbead - 1)
724 r(:) = xtrapos(:) - pos(:, iatom, wbead)
727 ia = helium%permutation(iatom)
728 DO WHILE (ia /= iatom)
730 r(:) = pos(:, helium%worm_atom_idx, wbead) - pos(:, ia, wbead)
731 rp(:) = pos(:, helium%worm_atom_idx, wbead - 1) - pos(:, ia, wbead - 1)
735 r(:) = xtrapos(:) - pos(:, ia, wbead)
737 ia = helium%permutation(ia)
742 DEALLOCATE (work, work2, work3)
744 END FUNCTION worm_centroid_move_action
757 REAL(kind=
dp)
FUNCTION worm_centroid_move_inter_action(pint_env, helium, pos, iatom, xtrapos, winc) &
760 TYPE(pint_env_type),
INTENT(IN) :: pint_env
761 TYPE(helium_solvent_type),
INTENT(IN) :: helium
762 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
764 INTEGER,
INTENT(IN) :: iatom
765 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xtrapos
766 LOGICAL,
INTENT(IN) :: winc
768 INTEGER :: jatom, jbead
769 REAL(kind=
dp) :: energy
777 IF (jatom == helium%worm_atom_idx)
THEN
779 DO jbead = 1, helium%worm_bead_idx - 1
781 jatom, jbead, pos(:, jatom, jbead), energy=energy)
782 partaction = partaction + energy
785 jbead = helium%worm_bead_idx
788 jatom, jbead, pos(:, jatom, jbead), energy=energy)
789 partaction = partaction + 0.5_dp*energy
792 jatom, jbead, xtrapos, energy=energy)
793 partaction = partaction + 0.5_dp*energy
795 DO jbead = helium%worm_bead_idx + 1, helium%beads
797 jatom, jbead, pos(:, jatom, jbead), energy=energy)
798 partaction = partaction + energy
801 DO jbead = 1, helium%beads
803 jatom, jbead, pos(:, jatom, jbead), energy=energy)
804 partaction = partaction + energy
807 jatom = helium%permutation(iatom)
808 DO WHILE (jatom /= iatom)
809 IF (jatom == helium%worm_atom_idx)
THEN
811 DO jbead = 1, helium%worm_bead_idx - 1
813 jatom, jbead, pos(:, jatom, jbead), energy=energy)
814 partaction = partaction + energy
817 jbead = helium%worm_bead_idx
820 jatom, jbead, pos(:, jatom, jbead), energy=energy)
821 partaction = partaction + 0.5_dp*energy
824 jatom, jbead, xtrapos, energy=energy)
825 partaction = partaction + 0.5_dp*energy
827 DO jbead = helium%worm_bead_idx + 1, helium%beads
829 jatom, jbead, pos(:, jatom, jbead), energy=energy)
830 partaction = partaction + energy
833 DO jbead = 1, helium%beads
835 jatom, jbead, pos(:, jatom, jbead), energy=energy)
836 partaction = partaction + energy
839 jatom = helium%permutation(jatom)
845 DO jbead = 1, helium%beads
847 jatom, jbead, pos(:, jatom, jbead), energy=energy)
848 partaction = partaction + energy
850 jatom = helium%permutation(iatom)
851 DO WHILE (jatom /= iatom)
852 DO jbead = 1, helium%beads
854 jatom, jbead, pos(:, jatom, jbead), energy=energy)
855 partaction = partaction + energy
857 jatom = helium%permutation(jatom)
861 partaction = partaction*helium%tau
863 END FUNCTION worm_centroid_move_inter_action
874 SUBROUTINE path_construct(helium, ri, rj, l, new_path)
877 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
878 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: ri, rj
879 INTEGER,
INTENT(IN) :: l
880 REAL(kind=
dp),
DIMENSION(3, l),
INTENT(OUT) :: new_path
882 INTEGER :: idim, istage
883 REAL(kind=
dp) :: imass, invstagemass, rk, weight
884 REAL(kind=
dp),
DIMENSION(3) :: re, rs
886 imass = 1.0_dp/helium%he_mass_au
889 re(:) = rj(:) - rs(:)
891 re(:) = re(:) + rs(:)
896 weight = 1.0_dp/(rk + 1.0_dp)
898 invstagemass = rk*weight*imass
901 new_path(idim, 1) = helium%rng_stream_gaussian%next(variance=helium%tau*invstagemass)
903 new_path(:, 1) = new_path(:, 1) + weight*(re(:) + rk*rs(:))
907 rk = real(l - istage + 1,
dp)
908 weight = 1.0_dp/(rk + 1.0_dp)
910 invstagemass = rk*weight*imass
913 new_path(idim, istage) = helium%rng_stream_gaussian%next(variance=helium%tau*invstagemass)
915 new_path(:, istage) = new_path(:, istage) + weight*(rk*new_path(:, istage - 1) + re(:))
918 END SUBROUTINE path_construct
930 SUBROUTINE worm_staging_move(pint_env, helium, startatom, startbead, l, ac)
932 TYPE(pint_env_type),
INTENT(IN) :: pint_env
933 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
934 INTEGER,
INTENT(IN) :: startatom, startbead, l
935 INTEGER,
INTENT(OUT) :: ac
937 INTEGER :: endatom, endbead, ia, ib, ibead, jbead
938 LOGICAL :: should_reject, worm_overlap
939 REAL(kind=
dp) :: rtmp, rtmpo, sdiff, snew, sold
940 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
941 REAL(kind=
dp),
DIMENSION(3, l) :: newsection
944 endbead = startbead + l + 1
946 IF (endbead > helium%beads)
THEN
947 endatom = helium%permutation(startatom)
948 endbead = endbead - helium%beads
954 IF (helium%worm_is_closed)
THEN
955 worm_overlap = .false.
958 worm_overlap = ((startbead < endbead) .AND. &
959 (helium%worm_bead_idx > startbead) .AND. &
960 (helium%worm_bead_idx <= endbead)) &
962 ((startbead > endbead) .AND. &
963 ((helium%worm_bead_idx > startbead) .OR. &
964 (helium%worm_bead_idx <= endbead)))
965 IF (worm_overlap)
THEN
967 IF (((helium%worm_atom_idx == startatom) .AND. (helium%worm_bead_idx >= startbead)) .OR. &
968 ((helium%worm_atom_idx == endatom) .AND. (helium%worm_bead_idx <= endbead)))
THEN
975 IF (worm_overlap)
THEN
976 sold = worm_path_action_worm_corrected(helium, helium%pos, &
977 startatom, startbead, endatom, endbead, &
978 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
980 sold = worm_path_action(helium, helium%pos, &
981 startatom, startbead, endatom, endbead)
984 IF (helium%solute_present)
THEN
987 sold = sold + worm_path_inter_action(pint_env, helium, helium%pos, &
988 startatom, startbead, endatom, endbead)
992 CALL path_construct(helium, &
993 helium%pos(:, startatom, startbead), &
994 helium%pos(:, endatom, endbead), l, &
1000 DO ibead = startbead + 1, min(helium%beads, startbead + l)
1001 helium%work(:, startatom, ibead) = newsection(:, jbead)
1005 IF (helium%beads < startbead + l)
THEN
1006 DO ibead = 1, endbead - 1
1007 helium%work(:, endatom, ibead) = newsection(:, jbead)
1013 IF (worm_overlap)
THEN
1014 snew = worm_path_action_worm_corrected(helium, helium%work, &
1015 startatom, startbead, endatom, endbead, &
1016 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1018 snew = worm_path_action(helium, helium%work, &
1019 startatom, startbead, endatom, endbead)
1022 IF (helium%solute_present)
THEN
1025 snew = snew + worm_path_inter_action(pint_env, helium, helium%work, &
1026 startatom, startbead, endatom, endbead)
1032 should_reject = .false.
1033 IF (sdiff < -100.0_dp)
THEN
1034 should_reject = .true.
1036 rtmp = helium%rng_stream_uniform%next()
1037 IF (exp(sdiff) < rtmp)
THEN
1038 should_reject = .true.
1041 IF (should_reject)
THEN
1045 DO ibead = startbead + 1, min(helium%beads, startbead + l)
1046 helium%work(:, startatom, ibead) = helium%pos(:, startatom, ibead)
1050 IF (helium%beads < startbead + l)
THEN
1051 DO ibead = 1, endbead - 1
1052 helium%work(:, endatom, ibead) = helium%pos(:, endatom, ibead)
1065 IF (.NOT. helium%periodic)
THEN
1066 IF (helium%solute_present)
THEN
1067 new_com(:) = helium%center(:)
1068 old_com(:) = new_com(:)
1071 DO ia = 1, helium%atoms
1072 DO ib = 1, helium%beads
1073 new_com(:) = new_com(:) + helium%work(:, ia, ib)
1076 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
1079 DO ia = 1, helium%atoms
1080 DO ib = 1, helium%beads
1081 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
1084 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
1086 should_reject = .false.
1087 atom:
DO ia = 1, helium%atoms
1089 DO ib = 1, helium%beads
1090 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
1092 dr(:) = dr(:)/real(helium%beads,
dp)
1093 rtmp = dot_product(dr, dr)
1094 IF (rtmp >= helium%droplet_radius**2)
THEN
1096 DO ib = 1, helium%beads
1097 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
1099 dro(:) = dro(:)/real(helium%beads,
dp)
1100 rtmpo = dot_product(dro, dro)
1102 IF (rtmpo < rtmp)
THEN
1104 should_reject = .true.
1109 IF (should_reject)
THEN
1113 DO ibead = startbead + 1, min(helium%beads, startbead + l)
1114 helium%work(:, startatom, ibead) = helium%pos(:, startatom, ibead)
1118 IF (helium%beads < startbead + l)
THEN
1119 DO ibead = 1, endbead - 1
1120 helium%work(:, endatom, ibead) = helium%pos(:, endatom, ibead)
1133 DO ibead = startbead + 1, min(helium%beads, startbead + l)
1134 helium%pos(:, startatom, ibead) = helium%work(:, startatom, ibead)
1138 IF (helium%beads < startbead + l)
THEN
1139 DO ibead = 1, endbead - 1
1140 helium%pos(:, endatom, ibead) = helium%work(:, endatom, ibead)
1145 END SUBROUTINE worm_staging_move
1157 SUBROUTINE worm_open_move(pint_env, helium, endatom, endbead, l, ac)
1159 TYPE(pint_env_type),
INTENT(IN) :: pint_env
1160 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
1161 INTEGER,
INTENT(IN) :: endatom, endbead, l
1162 INTEGER,
INTENT(OUT) :: ac
1164 INTEGER :: ia, ib, idim, kbead, startatom, startbead
1165 LOGICAL :: should_reject
1166 REAL(kind=
dp) :: distsq, mass, rtmp, rtmpo, sdiff, snew, &
1168 REAL(kind=
dp),
DIMENSION(3) :: distvec, dr, dro, new_com, old_com
1170 mass = helium%he_mass_au
1173 IF (l < endbead)
THEN
1176 startbead = endbead - l
1180 startatom = helium%iperm(endatom)
1181 startbead = endbead + helium%beads - l
1183 sold = worm_path_action(helium, helium%pos, &
1184 startatom, startbead, endatom, endbead)
1186 IF (helium%solute_present)
THEN
1190 sold = sold + worm_path_inter_action_head(pint_env, helium, helium%pos, &
1191 startatom, startbead, &
1192 helium%pos(:, endatom, endbead), endatom, endbead)
1195 helium%worm_is_closed = .false.
1196 helium%worm_atom_idx_work = endatom
1197 helium%worm_bead_idx_work = endbead
1200 IF (startbead < endbead)
THEN
1203 DO kbead = startbead + 1, endbead - 1
1205 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1206 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1211 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1212 helium%worm_xtra_bead_work(idim) = helium%work(idim, startatom, endbead - 1) + xr
1214 ELSE IF (endbead /= 1)
THEN
1217 DO kbead = startbead + 1, helium%beads
1219 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1220 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1225 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1226 helium%work(idim, endatom, 1) = helium%work(idim, startatom, helium%beads) + xr
1229 DO kbead = 2, endbead - 1
1231 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1232 helium%work(idim, endatom, kbead) = helium%work(idim, endatom, kbead - 1) + xr
1236 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1237 helium%worm_xtra_bead_work(idim) = helium%work(idim, endatom, endbead - 1) + xr
1242 DO kbead = startbead + 1, helium%beads
1244 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1245 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1250 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1251 helium%worm_xtra_bead_work(idim) = helium%work(idim, startatom, helium%beads) + xr
1255 snew = worm_path_action_worm_corrected(helium, helium%work, &
1256 startatom, startbead, endatom, endbead, &
1257 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1259 IF (helium%solute_present)
THEN
1260 snew = snew + worm_path_inter_action_head(pint_env, helium, helium%work, &
1261 startatom, startbead, &
1262 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1267 distvec(:) = helium%pos(:, startatom, startbead) - helium%pos(:, endatom, endbead)
1269 distsq = dot_product(distvec, distvec)
1273 sdiff = sdiff + distsq/(2.0_dp*helium%hb2m*real(l,
dp)*helium%tau)
1274 sdiff = sdiff + 1.5_dp*log(real(l,
dp)*helium%tau)
1275 sdiff = sdiff + helium%worm_ln_openclose_scale
1277 should_reject = .false.
1278 IF (sdiff < -100.0_dp)
THEN
1279 should_reject = .true.
1281 rtmp = helium%rng_stream_uniform%next()
1282 IF (exp(sdiff) < rtmp)
THEN
1283 should_reject = .true.
1286 IF (should_reject)
THEN
1290 IF (startbead < endbead)
THEN
1292 DO kbead = startbead + 1, endbead - 1
1293 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1298 DO kbead = startbead + 1, helium%beads
1299 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1302 DO kbead = 1, endbead - 1
1303 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1306 helium%worm_is_closed = .true.
1316 IF (.NOT. helium%periodic)
THEN
1317 IF (helium%solute_present)
THEN
1318 new_com(:) = helium%center(:)
1319 old_com(:) = new_com(:)
1322 DO ia = 1, helium%atoms
1323 DO ib = 1, helium%beads
1324 new_com(:) = new_com(:) + helium%work(:, ia, ib)
1327 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
1330 DO ia = 1, helium%atoms
1331 DO ib = 1, helium%beads
1332 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
1335 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
1337 should_reject = .false.
1338 atom:
DO ia = 1, helium%atoms
1340 DO ib = 1, helium%beads
1341 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
1343 dr(:) = dr(:)/real(helium%beads,
dp)
1344 rtmp = dot_product(dr, dr)
1345 IF (rtmp >= helium%droplet_radius**2)
THEN
1347 DO ib = 1, helium%beads
1348 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
1350 dro(:) = dro(:)/real(helium%beads,
dp)
1351 rtmpo = dot_product(dro, dro)
1353 IF (rtmpo < rtmp)
THEN
1355 should_reject = .true.
1360 IF (should_reject)
THEN
1363 IF (startbead < endbead)
THEN
1365 DO kbead = startbead + 1, endbead - 1
1366 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1371 DO kbead = startbead + 1, helium%beads
1372 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1375 DO kbead = 1, endbead - 1
1376 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1379 helium%worm_is_closed = .true.
1390 IF (startbead < endbead)
THEN
1392 DO kbead = startbead + 1, endbead - 1
1393 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1398 DO kbead = startbead + 1, helium%beads
1399 helium%pos(:, startatom, kbead) = helium%work(:, startatom, kbead)
1402 DO kbead = 1, endbead - 1
1403 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1406 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
1407 helium%worm_atom_idx = helium%worm_atom_idx_work
1408 helium%worm_bead_idx = helium%worm_bead_idx_work
1410 END SUBROUTINE worm_open_move
1420 SUBROUTINE worm_close_move(pint_env, helium, l, ac)
1422 TYPE(pint_env_type),
INTENT(IN) :: pint_env
1423 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
1424 INTEGER,
INTENT(IN) :: l
1425 INTEGER,
INTENT(OUT) :: ac
1427 INTEGER :: endatom, endbead, ia, ib, jbead, kbead, &
1428 startatom, startbead
1429 LOGICAL :: should_reject
1430 REAL(kind=
dp) :: distsq, mass, rtmp, rtmpo, sdiff, snew, &
1432 REAL(kind=
dp),
DIMENSION(3) :: distvec, dr, dro, new_com, old_com
1433 REAL(kind=
dp),
DIMENSION(3, l-1) :: newsection
1435 mass = helium%he_mass_au
1437 endatom = helium%worm_atom_idx
1438 endbead = helium%worm_bead_idx
1440 IF (l < endbead)
THEN
1443 startbead = endbead - l
1447 startatom = helium%iperm(endatom)
1448 startbead = endbead + helium%beads - l
1450 sold = worm_path_action_worm_corrected(helium, helium%pos, &
1451 startatom, startbead, endatom, endbead, &
1452 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
1454 IF (helium%solute_present)
THEN
1455 sold = sold + worm_path_inter_action_head(pint_env, helium, helium%pos, &
1456 startatom, startbead, &
1457 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
1462 CALL path_construct(helium, &
1463 helium%pos(:, startatom, startbead), &
1464 helium%pos(:, endatom, endbead), l - 1, &
1469 IF (startbead < endbead)
THEN
1471 DO kbead = startbead + 1, endbead - 1
1472 helium%work(:, endatom, kbead) = newsection(:, jbead)
1478 DO kbead = startbead + 1, helium%beads
1479 helium%work(:, startatom, kbead) = newsection(:, jbead)
1483 DO kbead = 1, endbead - 1
1484 helium%work(:, endatom, kbead) = newsection(:, jbead)
1489 helium%worm_is_closed = .true.
1491 snew = worm_path_action(helium, helium%work, &
1492 startatom, startbead, endatom, endbead)
1494 IF (helium%solute_present)
THEN
1498 snew = snew + worm_path_inter_action_head(pint_env, helium, helium%work, &
1499 startatom, startbead, &
1500 helium%work(:, endatom, endbead), endatom, endbead)
1505 distvec(:) = helium%pos(:, startatom, startbead) - helium%pos(:, endatom, endbead)
1507 distsq = dot_product(distvec, distvec)
1511 sdiff = sdiff - distsq/(2.0_dp*helium%hb2m*real(l,
dp)*helium%tau)
1512 sdiff = sdiff - 1.5_dp*log(real(l,
dp)*helium%tau)
1513 sdiff = sdiff - helium%worm_ln_openclose_scale
1515 should_reject = .false.
1516 IF (sdiff < -100.0_dp)
THEN
1517 should_reject = .true.
1519 rtmp = helium%rng_stream_uniform%next()
1520 IF (exp(sdiff) < rtmp)
THEN
1521 should_reject = .true.
1524 IF (should_reject)
THEN
1528 IF (startbead < endbead)
THEN
1530 DO kbead = startbead + 1, endbead - 1
1531 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1536 DO kbead = startbead + 1, helium%beads
1537 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1540 DO kbead = 1, endbead - 1
1541 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1544 helium%worm_is_closed = .false.
1554 IF (.NOT. helium%periodic)
THEN
1555 IF (helium%solute_present)
THEN
1556 new_com(:) = helium%center(:)
1557 old_com(:) = new_com(:)
1560 DO ia = 1, helium%atoms
1561 DO ib = 1, helium%beads
1562 new_com(:) = new_com(:) + helium%work(:, ia, ib)
1565 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
1568 DO ia = 1, helium%atoms
1569 DO ib = 1, helium%beads
1570 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
1573 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
1575 should_reject = .false.
1576 atom:
DO ia = 1, helium%atoms
1578 DO ib = 1, helium%beads
1579 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
1581 dr(:) = dr(:)/real(helium%beads,
dp)
1582 rtmp = dot_product(dr, dr)
1583 IF (rtmp >= helium%droplet_radius**2)
THEN
1585 DO ib = 1, helium%beads
1586 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
1588 dro(:) = dro(:)/real(helium%beads,
dp)
1589 rtmpo = dot_product(dro, dro)
1591 IF (rtmpo < rtmp)
THEN
1593 should_reject = .true.
1598 IF (should_reject)
THEN
1601 IF (startbead < endbead)
THEN
1603 DO kbead = startbead + 1, endbead - 1
1604 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1609 DO kbead = startbead + 1, helium%beads
1610 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1613 DO kbead = 1, endbead - 1
1614 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1617 helium%worm_is_closed = .false.
1626 IF (startbead < endbead)
THEN
1628 DO kbead = startbead + 1, endbead - 1
1629 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1634 DO kbead = startbead + 1, helium%beads
1635 helium%pos(:, startatom, kbead) = helium%work(:, startatom, kbead)
1638 DO kbead = 1, endbead - 1
1639 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1643 END SUBROUTINE worm_close_move
1653 SUBROUTINE worm_head_move(pint_env, helium, l, ac)
1655 TYPE(pint_env_type),
INTENT(IN) :: pint_env
1656 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
1657 INTEGER,
INTENT(IN) :: l
1658 INTEGER,
INTENT(OUT) :: ac
1660 INTEGER :: endatom, endbead, ia, ib, idim, kbead, &
1661 startatom, startbead
1662 LOGICAL :: should_reject
1663 REAL(kind=
dp) :: mass, rtmp, rtmpo, sdiff, snew, sold, xr
1664 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
1666 mass = helium%he_mass_au
1669 endatom = helium%worm_atom_idx
1670 endbead = helium%worm_bead_idx
1671 IF (l < endbead)
THEN
1674 startbead = endbead - l
1678 startatom = helium%iperm(endatom)
1679 startbead = endbead + helium%beads - l
1682 sold = worm_path_action_worm_corrected(helium, helium%pos, &
1683 startatom, startbead, endatom, endbead, &
1684 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
1686 IF (helium%solute_present)
THEN
1687 sold = sold + worm_path_inter_action_head(pint_env, helium, helium%pos, &
1688 startatom, startbead, &
1689 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
1693 IF (startbead < endbead)
THEN
1696 DO kbead = startbead + 1, endbead - 1
1698 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1699 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1704 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1705 helium%worm_xtra_bead_work(idim) = helium%work(idim, startatom, endbead - 1) + xr
1707 ELSE IF (endbead /= 1)
THEN
1710 DO kbead = startbead + 1, helium%beads
1712 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1713 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1718 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1719 helium%work(idim, endatom, 1) = helium%work(idim, startatom, helium%beads) + xr
1722 DO kbead = 2, endbead - 1
1724 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1725 helium%work(idim, endatom, kbead) = helium%work(idim, endatom, kbead - 1) + xr
1729 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1730 helium%worm_xtra_bead_work(idim) = helium%work(idim, endatom, endbead - 1) + xr
1735 DO kbead = startbead + 1, helium%beads
1737 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1738 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1743 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1744 helium%worm_xtra_bead_work(idim) = helium%work(idim, startatom, helium%beads) + xr
1748 snew = worm_path_action_worm_corrected(helium, helium%work, &
1749 startatom, startbead, endatom, endbead, &
1750 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1752 IF (helium%solute_present)
THEN
1753 snew = snew + worm_path_inter_action_head(pint_env, helium, helium%work, &
1754 startatom, startbead, &
1755 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1763 should_reject = .false.
1764 IF (sdiff < -100.0_dp)
THEN
1765 should_reject = .true.
1767 rtmp = helium%rng_stream_uniform%next()
1768 IF (exp(sdiff) < rtmp)
THEN
1769 should_reject = .true.
1772 IF (should_reject)
THEN
1776 IF (startbead < endbead)
THEN
1778 DO kbead = startbead + 1, endbead - 1
1779 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1784 DO kbead = startbead + 1, helium%beads
1785 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1788 DO kbead = 1, endbead - 1
1789 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1792 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
1802 IF (.NOT. helium%periodic)
THEN
1803 IF (helium%solute_present)
THEN
1804 new_com(:) = helium%center(:)
1805 old_com(:) = new_com(:)
1808 DO ia = 1, helium%atoms
1809 DO ib = 1, helium%beads
1810 new_com(:) = new_com(:) + helium%work(:, ia, ib)
1813 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
1816 DO ia = 1, helium%atoms
1817 DO ib = 1, helium%beads
1818 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
1821 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
1823 should_reject = .false.
1824 atom:
DO ia = 1, helium%atoms
1826 DO ib = 1, helium%beads
1827 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
1829 dr(:) = dr(:)/real(helium%beads,
dp)
1830 rtmp = dot_product(dr, dr)
1831 IF (rtmp >= helium%droplet_radius**2)
THEN
1833 DO ib = 1, helium%beads
1834 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
1836 dro(:) = dro(:)/real(helium%beads,
dp)
1837 rtmpo = dot_product(dro, dro)
1839 IF (rtmpo < rtmp)
THEN
1841 should_reject = .true.
1846 IF (should_reject)
THEN
1849 IF (startbead < endbead)
THEN
1851 DO kbead = startbead + 1, endbead - 1
1852 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1857 DO kbead = startbead + 1, helium%beads
1858 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1861 DO kbead = 1, endbead - 1
1862 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1865 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
1874 IF (startbead < endbead)
THEN
1876 DO kbead = startbead + 1, endbead - 1
1877 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1882 DO kbead = startbead + 1, helium%beads
1883 helium%pos(:, startatom, kbead) = helium%work(:, startatom, kbead)
1886 DO kbead = 1, endbead - 1
1887 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1890 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
1892 END SUBROUTINE worm_head_move
1902 SUBROUTINE worm_tail_move(pint_env, helium, l, ac)
1904 TYPE(pint_env_type),
INTENT(IN) :: pint_env
1905 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
1906 INTEGER,
INTENT(IN) :: l
1907 INTEGER,
INTENT(OUT) :: ac
1909 INTEGER :: endatom, endbead, ia, ib, idim, kbead, &
1910 startatom, startbead
1911 LOGICAL :: should_reject
1912 REAL(kind=
dp) :: mass, rtmp, rtmpo, sdiff, snew, sold, xr
1913 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
1915 mass = helium%he_mass_au
1918 startatom = helium%worm_atom_idx
1919 startbead = helium%worm_bead_idx
1920 endbead = startbead + l
1922 IF (endbead <= helium%beads)
THEN
1928 endatom = helium%permutation(startatom)
1929 endbead = endbead - helium%beads
1933 sold = worm_path_action(helium, helium%pos, &
1934 startatom, startbead, endatom, endbead)
1936 IF (helium%solute_present)
THEN
1937 sold = sold + worm_path_inter_action_tail(pint_env, helium, helium%pos, &
1939 helium%worm_atom_idx, helium%worm_bead_idx)
1943 IF (startbead < endbead)
THEN
1946 DO kbead = endbead - 1, startbead, -1
1948 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1949 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead + 1) + xr
1955 DO kbead = endbead - 1, 1, -1
1957 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1958 helium%work(idim, endatom, kbead) = helium%work(idim, endatom, kbead + 1) + xr
1964 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1965 helium%work(idim, startatom, helium%beads) = helium%work(idim, endatom, 1) + xr
1969 DO kbead = helium%beads - 1, startbead, -1
1971 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1972 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead + 1) + xr
1978 snew = worm_path_action(helium, helium%work, &
1979 startatom, startbead, endatom, endbead)
1981 IF (helium%solute_present)
THEN
1982 snew = snew + worm_path_inter_action_tail(pint_env, helium, helium%work, &
1984 helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1992 should_reject = .false.
1993 IF (sdiff < -100.0_dp)
THEN
1994 should_reject = .true.
1996 rtmp = helium%rng_stream_uniform%next()
1997 IF (exp(sdiff) < rtmp)
THEN
1998 should_reject = .true.
2001 IF (should_reject)
THEN
2005 IF (startbead < endbead)
THEN
2007 DO kbead = startbead, endbead - 1
2008 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
2013 DO kbead = startbead, helium%beads
2014 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
2017 DO kbead = 1, endbead - 1
2018 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
2021 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2031 IF (.NOT. helium%periodic)
THEN
2032 IF (helium%solute_present)
THEN
2033 new_com(:) = helium%center(:)
2034 old_com(:) = new_com(:)
2037 DO ia = 1, helium%atoms
2038 DO ib = 1, helium%beads
2039 new_com(:) = new_com(:) + helium%work(:, ia, ib)
2042 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
2045 DO ia = 1, helium%atoms
2046 DO ib = 1, helium%beads
2047 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
2050 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
2052 should_reject = .false.
2053 atom:
DO ia = 1, helium%atoms
2055 DO ib = 1, helium%beads
2056 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
2058 dr(:) = dr(:)/real(helium%beads,
dp)
2059 rtmp = dot_product(dr, dr)
2060 IF (rtmp >= helium%droplet_radius**2)
THEN
2062 DO ib = 1, helium%beads
2063 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
2065 dro(:) = dro(:)/real(helium%beads,
dp)
2066 rtmpo = dot_product(dro, dro)
2068 IF (rtmpo < rtmp)
THEN
2070 should_reject = .true.
2075 IF (should_reject)
THEN
2078 IF (startbead < endbead)
THEN
2080 DO kbead = startbead, endbead - 1
2081 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
2086 DO kbead = startbead, helium%beads
2087 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
2090 DO kbead = 1, endbead - 1
2091 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
2094 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2103 IF (startbead < endbead)
THEN
2105 DO kbead = startbead, endbead - 1
2106 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
2111 DO kbead = startbead, helium%beads
2112 helium%pos(:, startatom, kbead) = helium%work(:, startatom, kbead)
2115 DO kbead = 1, endbead - 1
2116 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
2120 END SUBROUTINE worm_tail_move
2130 SUBROUTINE worm_crawl_move_forward(pint_env, helium, l, ac)
2132 TYPE(pint_env_type),
INTENT(IN) :: pint_env
2133 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
2134 INTEGER,
INTENT(IN) :: l
2135 INTEGER,
INTENT(OUT) :: ac
2137 INTEGER :: ia, ib, idim, kbead
2138 LOGICAL :: should_reject
2139 REAL(kind=
dp) :: mass, newtailpot, oldheadpot, &
2140 oldtailpot, rtmp, rtmpo, sdiff, snew, &
2142 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
2144 mass = helium%he_mass_au
2147 helium%worm_bead_idx_work = helium%worm_bead_idx + l
2148 IF (helium%worm_bead_idx_work > helium%beads)
THEN
2149 helium%worm_bead_idx_work = helium%worm_bead_idx_work - helium%beads
2150 helium%worm_atom_idx_work = helium%permutation(helium%worm_atom_idx)
2152 helium%worm_atom_idx_work = helium%worm_atom_idx
2157 sold = worm_path_action(helium, helium%pos, &
2158 helium%worm_atom_idx, helium%worm_bead_idx, &
2159 helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2160 IF (helium%solute_present)
THEN
2163 sold = sold + worm_path_inter_action(pint_env, helium, helium%pos, &
2164 helium%worm_atom_idx, helium%worm_bead_idx, &
2165 helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2170 helium%worm_atom_idx, helium%worm_bead_idx, &
2171 helium%pos(:, helium%worm_atom_idx, helium%worm_bead_idx), &
2173 oldtailpot = oldtailpot*helium%tau
2177 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2178 helium%pos(:, helium%worm_atom_idx_work, helium%worm_bead_idx_work), &
2180 newtailpot = newtailpot*helium%tau
2184 helium%worm_atom_idx, helium%worm_bead_idx, &
2185 helium%worm_xtra_bead, &
2187 oldheadpot = oldheadpot*helium%tau
2191 sold = sold + 0.5_dp*(oldtailpot + oldheadpot) + newtailpot
2195 helium%work(:, helium%worm_atom_idx, helium%worm_bead_idx) = helium%worm_xtra_bead
2198 IF (helium%worm_bead_idx < helium%worm_bead_idx_work)
THEN
2201 DO kbead = helium%worm_bead_idx + 1, helium%worm_bead_idx_work - 1
2203 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2204 helium%work(idim, helium%worm_atom_idx, kbead) = helium%work(idim, helium%worm_atom_idx, kbead - 1) + xr
2209 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2210 helium%worm_xtra_bead_work(idim) = helium%work(idim, helium%worm_atom_idx, helium%worm_bead_idx_work - 1) + xr
2212 ELSE IF (helium%worm_bead_idx_work /= 1)
THEN
2215 DO kbead = helium%worm_bead_idx + 1, helium%beads
2217 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2218 helium%work(idim, helium%worm_atom_idx, kbead) = helium%work(idim, helium%worm_atom_idx, kbead - 1) + xr
2223 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2224 helium%work(idim, helium%worm_atom_idx_work, 1) = helium%work(idim, helium%worm_atom_idx, helium%beads) + xr
2227 DO kbead = 2, helium%worm_bead_idx_work - 1
2229 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2230 helium%work(idim, helium%worm_atom_idx_work, kbead) = helium%work(idim, helium%worm_atom_idx_work, kbead - 1) + xr
2234 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2235 helium%worm_xtra_bead_work(idim) = helium%work(idim, helium%worm_atom_idx_work, helium%worm_bead_idx_work - 1) + xr
2240 DO kbead = helium%worm_bead_idx + 1, helium%beads
2242 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2243 helium%work(idim, helium%worm_atom_idx, kbead) = helium%work(idim, helium%worm_atom_idx, kbead - 1) + xr
2248 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2249 helium%worm_xtra_bead_work(idim) = helium%work(idim, helium%worm_atom_idx, helium%beads) + xr
2253 snew = worm_path_action_worm_corrected(helium, helium%work, &
2254 helium%worm_atom_idx, helium%worm_bead_idx, &
2255 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2256 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2258 IF (helium%solute_present)
THEN
2259 snew = snew + worm_path_inter_action_head(pint_env, helium, helium%work, &
2260 helium%worm_atom_idx, helium%worm_bead_idx, &
2261 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2262 snew = snew + 0.5_dp*newtailpot + oldheadpot
2270 should_reject = .false.
2271 IF (sdiff < -100.0_dp)
THEN
2272 should_reject = .true.
2274 rtmp = helium%rng_stream_uniform%next()
2275 IF (exp(sdiff) < rtmp)
THEN
2276 should_reject = .true.
2279 IF (should_reject)
THEN
2283 IF (helium%worm_bead_idx < helium%worm_bead_idx_work)
THEN
2285 DO kbead = helium%worm_bead_idx, helium%worm_bead_idx_work - 1
2286 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2291 DO kbead = helium%worm_bead_idx, helium%beads
2292 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2295 DO kbead = 1, helium%worm_bead_idx_work - 1
2296 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2299 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2300 helium%worm_bead_idx_work = helium%worm_bead_idx
2301 helium%worm_atom_idx_work = helium%worm_atom_idx
2311 IF (.NOT. helium%periodic)
THEN
2312 IF (helium%solute_present)
THEN
2313 new_com(:) = helium%center(:)
2314 old_com(:) = new_com(:)
2317 DO ia = 1, helium%atoms
2318 DO ib = 1, helium%beads
2319 new_com(:) = new_com(:) + helium%work(:, ia, ib)
2322 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
2325 DO ia = 1, helium%atoms
2326 DO ib = 1, helium%beads
2327 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
2330 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
2332 should_reject = .false.
2333 atom:
DO ia = 1, helium%atoms
2335 DO ib = 1, helium%beads
2336 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
2338 dr(:) = dr(:)/real(helium%beads,
dp)
2339 rtmp = dot_product(dr, dr)
2340 IF (rtmp >= helium%droplet_radius**2)
THEN
2342 DO ib = 1, helium%beads
2343 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
2345 dro(:) = dro(:)/real(helium%beads,
dp)
2346 rtmpo = dot_product(dro, dro)
2348 IF (rtmpo < rtmp)
THEN
2350 should_reject = .true.
2355 IF (should_reject)
THEN
2358 IF (helium%worm_bead_idx < helium%worm_bead_idx_work)
THEN
2360 DO kbead = helium%worm_bead_idx, helium%worm_bead_idx_work - 1
2361 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2366 DO kbead = helium%worm_bead_idx, helium%beads
2367 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2370 DO kbead = 1, helium%worm_bead_idx_work - 1
2371 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2374 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2375 helium%worm_bead_idx_work = helium%worm_bead_idx
2376 helium%worm_atom_idx_work = helium%worm_atom_idx
2385 IF (helium%worm_bead_idx < helium%worm_bead_idx_work)
THEN
2387 DO kbead = helium%worm_bead_idx, helium%worm_bead_idx_work - 1
2388 helium%pos(:, helium%worm_atom_idx_work, kbead) = helium%work(:, helium%worm_atom_idx_work, kbead)
2393 DO kbead = helium%worm_bead_idx, helium%beads
2394 helium%pos(:, helium%worm_atom_idx, kbead) = helium%work(:, helium%worm_atom_idx, kbead)
2397 DO kbead = 1, helium%worm_bead_idx_work - 1
2398 helium%pos(:, helium%worm_atom_idx_work, kbead) = helium%work(:, helium%worm_atom_idx_work, kbead)
2401 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
2402 helium%worm_bead_idx = helium%worm_bead_idx_work
2403 helium%worm_atom_idx = helium%worm_atom_idx_work
2405 END SUBROUTINE worm_crawl_move_forward
2415 SUBROUTINE worm_crawl_move_backward(pint_env, helium, l, ac)
2417 TYPE(pint_env_type),
INTENT(IN) :: pint_env
2418 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
2419 INTEGER,
INTENT(IN) :: l
2420 INTEGER,
INTENT(OUT) :: ac
2422 INTEGER :: ia, ib, idim, kbead
2423 LOGICAL :: should_reject
2424 REAL(kind=
dp) :: mass, newheadpot, oldheadpot, &
2425 oldtailpot, rtmp, rtmpo, sdiff, snew, &
2427 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
2429 mass = helium%he_mass_au
2432 helium%worm_bead_idx_work = helium%worm_bead_idx - l
2433 IF (helium%worm_bead_idx_work < 1)
THEN
2434 helium%worm_bead_idx_work = helium%worm_bead_idx_work + helium%beads
2435 helium%worm_atom_idx_work = helium%iperm(helium%worm_atom_idx)
2437 helium%worm_atom_idx_work = helium%worm_atom_idx
2442 sold = worm_path_action_worm_corrected(helium, helium%work, &
2443 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2444 helium%worm_atom_idx, helium%worm_bead_idx, &
2445 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
2447 IF (helium%solute_present)
THEN
2450 sold = sold + worm_path_inter_action(pint_env, helium, helium%pos, &
2451 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2452 helium%worm_atom_idx, helium%worm_bead_idx)
2457 helium%worm_atom_idx, helium%worm_bead_idx, &
2458 helium%pos(:, helium%worm_atom_idx, helium%worm_bead_idx), &
2460 oldtailpot = oldtailpot*helium%tau
2464 helium%worm_atom_idx, helium%worm_bead_idx, &
2465 helium%worm_xtra_bead, &
2467 oldheadpot = oldheadpot*helium%tau
2471 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2472 helium%pos(:, helium%worm_atom_idx_work, helium%worm_bead_idx_work), &
2474 newheadpot = newheadpot*helium%tau
2478 sold = sold + 0.5_dp*(oldtailpot + oldheadpot) + newheadpot
2482 helium%worm_xtra_bead_work = helium%pos(:, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2485 IF (helium%worm_bead_idx_work < helium%worm_bead_idx)
THEN
2488 DO kbead = helium%worm_bead_idx - 1, helium%worm_bead_idx_work, -1
2490 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2491 helium%work(idim, helium%worm_atom_idx, kbead) = helium%work(idim, helium%worm_atom_idx, kbead + 1) + xr
2498 DO kbead = helium%worm_bead_idx - 1, 1, -1
2500 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2501 helium%work(idim, helium%worm_atom_idx, kbead) = helium%work(idim, helium%worm_atom_idx, kbead + 1) + xr
2507 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2508 helium%work(idim, helium%worm_atom_idx_work, helium%beads) = helium%work(idim, helium%worm_atom_idx, 1) + xr
2512 DO kbead = helium%beads - 1, helium%worm_bead_idx_work, -1
2514 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2515 helium%work(idim, helium%worm_atom_idx_work, kbead) = helium%work(idim, helium%worm_atom_idx_work, kbead + 1) + xr
2520 snew = worm_path_action(helium, helium%work, &
2521 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2522 helium%worm_atom_idx, helium%worm_bead_idx)
2524 IF (helium%solute_present)
THEN
2525 snew = snew + worm_path_inter_action_tail(pint_env, helium, helium%work, &
2526 helium%worm_atom_idx, helium%worm_bead_idx, &
2527 helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2528 snew = snew + 0.5_dp*newheadpot + oldtailpot
2536 should_reject = .false.
2537 IF (sdiff < -100.0_dp)
THEN
2538 should_reject = .true.
2540 rtmp = helium%rng_stream_uniform%next()
2541 IF (exp(sdiff) < rtmp)
THEN
2542 should_reject = .true.
2545 IF (should_reject)
THEN
2549 IF (helium%worm_bead_idx_work < helium%worm_bead_idx)
THEN
2551 DO kbead = helium%worm_bead_idx_work, helium%worm_bead_idx - 1
2552 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2557 DO kbead = helium%worm_bead_idx_work, helium%beads
2558 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2561 DO kbead = 1, helium%worm_bead_idx - 1
2562 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2565 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2566 helium%worm_bead_idx_work = helium%worm_bead_idx
2567 helium%worm_atom_idx_work = helium%worm_atom_idx
2577 IF (.NOT. helium%periodic)
THEN
2578 IF (helium%solute_present)
THEN
2579 new_com(:) = helium%center(:)
2580 old_com(:) = new_com(:)
2583 DO ia = 1, helium%atoms
2584 DO ib = 1, helium%beads
2585 new_com(:) = new_com(:) + helium%work(:, ia, ib)
2588 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
2591 DO ia = 1, helium%atoms
2592 DO ib = 1, helium%beads
2593 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
2596 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
2598 should_reject = .false.
2599 atom:
DO ia = 1, helium%atoms
2601 DO ib = 1, helium%beads
2602 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
2604 dr(:) = dr(:)/real(helium%beads,
dp)
2605 rtmp = dot_product(dr, dr)
2606 IF (rtmp >= helium%droplet_radius**2)
THEN
2608 DO ib = 1, helium%beads
2609 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
2611 dro(:) = dro(:)/real(helium%beads,
dp)
2612 rtmpo = dot_product(dro, dro)
2614 IF (rtmpo < rtmp)
THEN
2616 should_reject = .true.
2621 IF (should_reject)
THEN
2626 IF (helium%worm_bead_idx_work < helium%worm_bead_idx)
THEN
2628 DO kbead = helium%worm_bead_idx_work, helium%worm_bead_idx - 1
2629 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2634 DO kbead = helium%worm_bead_idx_work, helium%beads
2635 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2638 DO kbead = 1, helium%worm_bead_idx - 1
2639 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2642 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2643 helium%worm_bead_idx_work = helium%worm_bead_idx
2644 helium%worm_atom_idx_work = helium%worm_atom_idx
2654 IF (helium%worm_bead_idx_work < helium%worm_bead_idx)
THEN
2656 DO kbead = helium%worm_bead_idx_work, helium%worm_bead_idx - 1
2657 helium%pos(:, helium%worm_atom_idx, kbead) = helium%work(:, helium%worm_atom_idx, kbead)
2662 DO kbead = helium%worm_bead_idx_work, helium%beads
2663 helium%pos(:, helium%worm_atom_idx_work, kbead) = helium%work(:, helium%worm_atom_idx_work, kbead)
2666 DO kbead = 1, helium%worm_bead_idx - 1
2667 helium%pos(:, helium%worm_atom_idx, kbead) = helium%work(:, helium%worm_atom_idx, kbead)
2670 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
2671 helium%worm_bead_idx = helium%worm_bead_idx_work
2672 helium%worm_atom_idx = helium%worm_atom_idx_work
2674 END SUBROUTINE worm_crawl_move_backward
2685 REAL(kind=
dp)
FUNCTION free_density_matrix(helium, startpos, endpos, l)
RESULT(rho)
2687 TYPE(helium_solvent_type),
INTENT(IN) :: helium
2688 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: startpos, endpos
2689 INTEGER,
INTENT(IN) :: l
2691 REAL(kind=
dp) :: distsq, prefac
2692 REAL(kind=
dp),
DIMENSION(3) :: dvec
2694 dvec(:) = startpos(:) - endpos(:)
2696 distsq = dot_product(dvec, dvec)
2698 prefac = 0.5_dp/(helium%hb2m*real(l,
dp)*helium%tau)
2699 rho = -prefac*distsq
2701 rho = rho*(sqrt(prefac/
pi))**3
2703 END FUNCTION free_density_matrix
2714 SUBROUTINE worm_swap_move(pint_env, helium, natoms, l, ac)
2716 TYPE(pint_env_type),
INTENT(IN) :: pint_env
2717 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
2718 INTEGER,
INTENT(IN) :: natoms, l
2719 INTEGER,
INTENT(OUT) :: ac
2721 INTEGER :: bendatom, bstartatom, endbead, &
2722 excludeatom, fendatom, fstartatom, ia, &
2723 iatom, ib, ibead, jbead, kbead, &
2725 LOGICAL :: should_reject
2726 REAL(kind=
dp) :: backwarddensmatsum, forwarddensmatsum, &
2727 mass, newheadpotential, &
2728 oldheadpotential, rtmp, rtmpo, sdiff, &
2730 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
2731 REAL(kind=
dp),
DIMENSION(3, l) :: newsection
2732 REAL(kind=
dp),
DIMENSION(natoms) :: backwarddensmat, forwarddensmat
2735 startbead = helium%worm_bead_idx
2736 endbead = helium%worm_bead_idx + l + 1
2737 fstartatom = helium%worm_atom_idx
2738 excludeatom = fstartatom
2741 IF (endbead > helium%beads)
THEN
2742 endbead = endbead - helium%beads
2744 excludeatom = helium%permutation(excludeatom)
2746 DO iatom = 1, excludeatom - 1
2747 forwarddensmat(iatom) = free_density_matrix(helium, helium%worm_xtra_bead(:), &
2748 helium%pos(:, iatom, endbead), l + 1)
2750 forwarddensmat(excludeatom) = 0.0_dp
2751 DO iatom = excludeatom + 1, natoms
2752 forwarddensmat(iatom) = free_density_matrix(helium, helium%worm_xtra_bead(:), &
2753 helium%pos(:, iatom, endbead), l + 1)
2755 forwarddensmatsum = sum(forwarddensmat)
2756 IF (forwarddensmatsum == 0.0_dp)
THEN
2762 rtmp = helium%rng_stream_uniform%next()*forwarddensmatsum
2764 DO WHILE (rtmp >= forwarddensmat(fendatom))
2765 rtmp = rtmp - forwarddensmat(fendatom)
2766 fendatom = fendatom + 1
2769 fendatom = min(fendatom, natoms)
2770 IF (fendatom == excludeatom)
THEN
2776 IF (endbead > startbead)
THEN
2777 bstartatom = fendatom
2779 bstartatom = helium%iperm(fendatom)
2783 DO iatom = 1, excludeatom - 1
2784 backwarddensmat(iatom) = free_density_matrix(helium, &
2785 helium%pos(:, bstartatom, startbead), &
2786 helium%pos(:, iatom, endbead), l + 1)
2788 backwarddensmat(excludeatom) = 0.0_dp
2789 DO iatom = excludeatom + 1, natoms
2790 backwarddensmat(iatom) = free_density_matrix(helium, &
2791 helium%pos(:, bstartatom, startbead), &
2792 helium%pos(:, iatom, endbead), l + 1)
2795 backwarddensmatsum = sum(backwarddensmat)
2797 mass = helium%he_mass_au
2800 sold = worm_path_action(helium, helium%pos, &
2801 bstartatom, startbead, fendatom, endbead)
2803 IF (helium%solute_present)
THEN
2806 sold = sold + worm_path_inter_action(pint_env, helium, helium%pos, &
2807 bstartatom, startbead, fendatom, endbead)
2810 fstartatom, startbead, helium%worm_xtra_bead, &
2811 energy=oldheadpotential)
2812 oldheadpotential = oldheadpotential*helium%tau
2815 bstartatom, startbead, helium%pos(:, bstartatom, startbead), &
2816 energy=newheadpotential)
2817 newheadpotential = newheadpotential*helium%tau
2819 sold = sold + 0.5_dp*oldheadpotential + newheadpotential
2824 CALL path_construct(helium, &
2825 helium%worm_xtra_bead(:), &
2826 helium%pos(:, fendatom, endbead), l, &
2832 IF (startbead < endbead)
THEN
2834 DO kbead = startbead + 1, endbead - 1
2835 helium%work(:, fstartatom, kbead) = newsection(:, jbead)
2841 DO kbead = startbead + 1, helium%beads
2842 helium%work(:, fstartatom, kbead) = newsection(:, jbead)
2846 DO ibead = 1, endbead - 1
2847 helium%work(:, fendatom, ibead) = newsection(:, jbead)
2853 helium%work(:, helium%worm_atom_idx, helium%worm_bead_idx) = helium%worm_xtra_bead(:)
2854 helium%worm_xtra_bead_work(:) = helium%pos(:, bstartatom, startbead)
2857 DO ib = startbead, helium%beads
2858 helium%work(:, bstartatom, ib) = helium%pos(:, fstartatom, ib)
2861 IF (endbead > startbead)
THEN
2862 DO ib = endbead, helium%beads
2863 helium%work(:, fstartatom, ib) = helium%pos(:, bstartatom, ib)
2868 tmpi = helium%permutation(bstartatom)
2869 helium%permutation(bstartatom) = helium%permutation(fstartatom)
2870 helium%permutation(fstartatom) = tmpi
2872 DO ib = 1,
SIZE(helium%permutation)
2873 helium%iperm(helium%permutation(ib)) = ib
2875 helium%worm_atom_idx_work = bstartatom
2878 IF (endbead > startbead)
THEN
2879 snew = worm_path_action(helium, helium%work, &
2880 fstartatom, startbead, fstartatom, endbead)
2881 IF (helium%solute_present)
THEN
2884 snew = snew + worm_path_inter_action(pint_env, helium, helium%work, &
2885 fstartatom, startbead, fstartatom, endbead)
2888 snew = snew + oldheadpotential + 0.5_dp*newheadpotential
2891 snew = worm_path_action(helium, helium%work, &
2892 fstartatom, startbead, helium%permutation(fstartatom), endbead)
2893 IF (helium%solute_present)
THEN
2896 snew = snew + worm_path_inter_action(pint_env, helium, helium%work, &
2897 fstartatom, startbead, helium%permutation(fstartatom), endbead)
2900 snew = snew + oldheadpotential + 0.5_dp*newheadpotential
2906 sdiff = sdiff + log(forwarddensmatsum/backwarddensmatsum)
2908 should_reject = .false.
2909 IF (sdiff < -100.0_dp)
THEN
2910 should_reject = .true.
2912 rtmp = helium%rng_stream_uniform%next()
2913 IF (exp(sdiff) < rtmp)
THEN
2914 should_reject = .true.
2917 IF (should_reject)
THEN
2920 DO kbead = startbead, helium%beads
2921 helium%work(:, bstartatom, kbead) = helium%pos(:, bstartatom, kbead)
2923 DO kbead = startbead, helium%beads
2924 helium%work(:, fstartatom, kbead) = helium%pos(:, fstartatom, kbead)
2926 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2927 helium%worm_atom_idx_work = helium%worm_atom_idx
2928 IF (startbead > endbead)
THEN
2929 DO kbead = 1, endbead
2930 helium%work(:, fendatom, kbead) = helium%pos(:, fendatom, kbead)
2934 tmpi = helium%permutation(bstartatom)
2935 helium%permutation(bstartatom) = helium%permutation(fstartatom)
2936 helium%permutation(fstartatom) = tmpi
2938 DO ib = 1,
SIZE(helium%permutation)
2939 helium%iperm(helium%permutation(ib)) = ib
2950 IF (.NOT. helium%periodic)
THEN
2951 IF (helium%solute_present)
THEN
2952 new_com(:) = helium%center(:)
2953 old_com(:) = new_com(:)
2956 DO ia = 1, helium%atoms
2957 DO ib = 1, helium%beads
2958 new_com(:) = new_com(:) + helium%work(:, ia, ib)
2961 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
2964 DO ia = 1, helium%atoms
2965 DO ib = 1, helium%beads
2966 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
2969 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
2971 should_reject = .false.
2972 atom:
DO ia = 1, helium%atoms
2974 DO ib = 1, helium%beads
2975 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
2977 dr(:) = dr(:)/real(helium%beads,
dp)
2978 rtmp = dot_product(dr, dr)
2979 IF (rtmp >= helium%droplet_radius**2)
THEN
2981 DO ib = 1, helium%beads
2982 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
2984 dro(:) = dro(:)/real(helium%beads,
dp)
2985 rtmpo = dot_product(dro, dro)
2987 IF (rtmpo < rtmp)
THEN
2989 should_reject = .true.
2994 IF (should_reject)
THEN
2996 DO kbead = startbead, helium%beads
2997 helium%work(:, bstartatom, kbead) = helium%pos(:, bstartatom, kbead)
2999 DO kbead = startbead, helium%beads
3000 helium%work(:, fstartatom, kbead) = helium%pos(:, fstartatom, kbead)
3002 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
3003 helium%worm_atom_idx_work = helium%worm_atom_idx
3004 IF (startbead > endbead)
THEN
3005 DO kbead = 1, endbead
3006 helium%work(:, fendatom, kbead) = helium%pos(:, fendatom, kbead)
3011 tmpi = helium%permutation(bstartatom)
3012 helium%permutation(bstartatom) = helium%permutation(fstartatom)
3013 helium%permutation(fstartatom) = tmpi
3015 DO ib = 1,
SIZE(helium%permutation)
3016 helium%iperm(helium%permutation(ib)) = ib
3025 DO kbead = startbead, helium%beads
3026 helium%pos(:, bstartatom, kbead) = helium%work(:, bstartatom, kbead)
3028 DO kbead = startbead, helium%beads
3029 helium%pos(:, fstartatom, kbead) = helium%work(:, fstartatom, kbead)
3031 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
3032 helium%worm_atom_idx = helium%worm_atom_idx_work
3033 IF (startbead > endbead)
THEN
3034 DO kbead = 1, endbead
3035 helium%pos(:, fendatom, kbead) = helium%work(:, fendatom, kbead)
3039 END SUBROUTINE worm_swap_move
3052 REAL(kind=
dp)
FUNCTION worm_path_action(helium, pos, &
3053 startatom, startbead, endatom, endbead)
RESULT(partaction)
3055 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
3056 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
3058 INTEGER,
INTENT(IN) :: startatom, startbead, endatom, endbead
3060 INTEGER :: iatom, ibead
3061 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work2, work3
3062 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: work
3064 ALLOCATE (work(3, helium%beads + 1), work2(helium%beads + 1), work3(
SIZE(helium%uoffdiag, 1) + 1))
3068 IF (startbead < endbead)
THEN
3071 DO iatom = 1, helium%atoms
3073 IF (iatom == startatom) cycle
3076 DO ibead = startbead, endbead
3077 work(:, ibead + 1 - startbead) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3079 partaction = partaction +
helium_eval_chain(helium, work, endbead - startbead + 1, work2, work3)
3084 DO iatom = 1, helium%atoms
3086 IF (iatom == startatom) cycle
3089 DO ibead = startbead, helium%beads
3090 work(:, ibead + 1 - startbead) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3093 work(:, helium%beads + 2 - startbead) = pos(:, helium%permutation(iatom), 1) - pos(:, endatom, 1)
3094 partaction = partaction +
helium_eval_chain(helium, work, helium%beads - startbead + 2, work2, work3)
3098 DO iatom = 1, helium%atoms
3100 IF (iatom == endatom) cycle
3102 IF (endbead > 1)
THEN
3103 DO ibead = 1, endbead
3104 work(:, ibead) = pos(:, iatom, ibead) - pos(:, endatom, ibead)
3106 partaction = partaction +
helium_eval_chain(helium, work, endbead, work2, work3)
3111 DEALLOCATE (work, work2, work3)
3113 END FUNCTION worm_path_action
3129 REAL(kind=
dp)
FUNCTION worm_path_action_worm_corrected(helium, pos, &
3130 startatom, startbead, endatom, endbead, xtrapos, worm_atom_idx, worm_bead_idx)
RESULT(partaction)
3132 TYPE(helium_solvent_type),
INTENT(INOUT) :: helium
3133 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
3135 INTEGER,
INTENT(IN) :: startatom, startbead, endatom, endbead
3136 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xtrapos
3137 INTEGER,
INTENT(IN) :: worm_atom_idx, worm_bead_idx
3139 INTEGER :: iatom, ibead
3140 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work2, work3
3141 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: work
3142 REAL(kind=
dp),
DIMENSION(3) :: r, rp
3144 ALLOCATE (work(3, helium%beads + 1), work2(helium%beads + 1), work3(
SIZE(helium%uoffdiag, 1) + 1))
3148 IF (startbead < endbead)
THEN
3151 DO iatom = 1, helium%atoms
3153 IF (iatom == startatom) cycle
3156 IF (worm_bead_idx - startbead > 1)
THEN
3157 DO ibead = startbead, worm_bead_idx - 1
3158 work(:, ibead + 1 - startbead) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3160 partaction = partaction +
helium_eval_chain(helium, work, worm_bead_idx - startbead, work2, work3)
3163 IF (endbead > worm_bead_idx)
THEN
3164 DO ibead = worm_bead_idx, endbead
3165 work(:, ibead + 1 - worm_bead_idx) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3167 partaction = partaction +
helium_eval_chain(helium, work, endbead - worm_bead_idx + 1, work2, work3)
3171 IF (worm_atom_idx /= startatom)
THEN
3172 DO iatom = 1, helium%atoms
3173 IF (iatom == startatom) cycle
3174 IF (iatom == worm_atom_idx) cycle
3175 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, startatom, worm_bead_idx - 1)
3176 rp(:) = pos(:, iatom, worm_bead_idx) - pos(:, startatom, worm_bead_idx)
3180 r(:) = pos(:, startatom, worm_bead_idx - 1) - pos(:, worm_atom_idx, worm_bead_idx - 1)
3181 rp(:) = pos(:, startatom, worm_bead_idx) - xtrapos(:)
3185 DO iatom = 1, helium%atoms
3186 IF (iatom == startatom) cycle
3187 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, startatom, worm_bead_idx - 1)
3188 rp(:) = pos(:, iatom, worm_bead_idx) - xtrapos(:)
3195 IF (worm_bead_idx > startbead)
THEN
3197 DO iatom = 1, helium%atoms
3199 IF (iatom == startatom) cycle
3202 IF (worm_bead_idx - startbead > 1)
THEN
3203 DO ibead = startbead, worm_bead_idx - 1
3204 work(:, ibead + 1 - startbead) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3206 partaction = partaction +
helium_eval_chain(helium, work, worm_bead_idx - startbead, work2, work3)
3210 DO ibead = worm_bead_idx, helium%beads
3211 work(:, ibead + 1 - worm_bead_idx) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3214 work(:, helium%beads - worm_bead_idx + 2) = pos(:, helium%permutation(iatom), 1) - &
3215 pos(:, helium%permutation(startatom), 1)
3216 partaction = partaction +
helium_eval_chain(helium, work, helium%beads - worm_bead_idx + 2, work2, work3)
3221 DO iatom = 1, helium%atoms
3223 IF (iatom == endatom) cycle
3225 IF (endbead > 1)
THEN
3226 DO ibead = 1, endbead
3227 work(:, ibead) = pos(:, iatom, ibead) - pos(:, endatom, ibead)
3229 partaction = partaction +
helium_eval_chain(helium, work, endbead, work2, work3)
3233 IF (worm_atom_idx /= startatom)
THEN
3234 DO iatom = 1, helium%atoms
3235 IF (iatom == startatom) cycle
3236 IF (iatom == worm_atom_idx) cycle
3237 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, startatom, worm_bead_idx - 1)
3238 rp(:) = pos(:, iatom, worm_bead_idx) - pos(:, startatom, worm_bead_idx)
3242 r(:) = pos(:, startatom, worm_bead_idx - 1) - pos(:, worm_atom_idx, worm_bead_idx - 1)
3243 rp(:) = pos(:, startatom, worm_bead_idx) - xtrapos(:)
3247 DO iatom = 1, helium%atoms
3248 IF (iatom == startatom) cycle
3249 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, startatom, worm_bead_idx - 1)
3250 rp(:) = pos(:, iatom, worm_bead_idx) - xtrapos(:)
3255 IF (worm_bead_idx /= 1)
THEN
3256 DO iatom = 1, helium%atoms
3258 IF (iatom == startatom) cycle
3261 DO ibead = startbead, helium%beads
3262 work(:, ibead + 1 - startbead) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3265 work(:, helium%beads - startbead + 2) = pos(:, helium%permutation(iatom), 1) - pos(:, helium%permutation(startatom), 1)
3266 partaction = partaction +
helium_eval_chain(helium, work, helium%beads - startbead + 2, work2, work3)
3270 DO iatom = 1, helium%atoms
3272 IF (iatom == endatom) cycle
3274 IF (worm_bead_idx > 2)
THEN
3275 DO ibead = 1, worm_bead_idx - 1
3276 work(:, ibead) = pos(:, iatom, ibead) - pos(:, endatom, ibead)
3278 partaction = partaction +
helium_eval_chain(helium, work, worm_bead_idx - 1, work2, work3)
3281 IF (endbead > worm_bead_idx)
THEN
3282 DO ibead = worm_bead_idx, endbead
3283 work(:, ibead - worm_bead_idx + 1) = pos(:, iatom, ibead) - pos(:, endatom, ibead)
3285 partaction = partaction +
helium_eval_chain(helium, work, endbead - worm_bead_idx + 1, work2, work3)
3289 IF (worm_atom_idx /= endatom)
THEN
3290 DO iatom = 1, helium%atoms
3291 IF (iatom == endatom) cycle
3292 IF (iatom == worm_atom_idx) cycle
3293 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, endatom, worm_bead_idx - 1)
3294 rp(:) = pos(:, iatom, worm_bead_idx) - pos(:, endatom, worm_bead_idx)
3298 r(:) = pos(:, endatom, worm_bead_idx - 1) - pos(:, worm_atom_idx, worm_bead_idx - 1)
3299 rp(:) = pos(:, endatom, worm_bead_idx) - xtrapos(:)
3303 DO iatom = 1, helium%atoms
3304 IF (iatom == endatom) cycle
3305 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, endatom, worm_bead_idx - 1)
3306 rp(:) = pos(:, iatom, worm_bead_idx) - xtrapos(:)
3312 DO iatom = 1, helium%atoms
3314 IF (iatom == startatom) cycle
3317 IF (helium%beads > startbead)
THEN
3318 DO ibead = startbead, helium%beads
3319 work(:, ibead - startbead + 1) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3321 partaction = partaction +
helium_eval_chain(helium, work, helium%beads - startbead + 1, work2, work3)
3326 DO iatom = 1, helium%atoms
3327 IF (endbead > 1)
THEN
3328 DO ibead = 1, endbead
3329 work(:, ibead) = pos(:, iatom, ibead) - pos(:, endatom, ibead)
3331 partaction = partaction +
helium_eval_chain(helium, work, endbead, work2, work3)
3335 IF (worm_atom_idx /= endatom)
THEN
3336 DO iatom = 1, helium%atoms
3337 IF (iatom == endatom) cycle
3338 IF (iatom == worm_atom_idx) cycle
3339 r(:) = pos(:, helium%iperm(iatom), helium%beads) - pos(:, startatom, helium%beads)
3340 rp(:) = pos(:, iatom, 1) - pos(:, endatom, 1)
3344 r(:) = pos(:, startatom, helium%beads) - pos(:, helium%iperm(worm_atom_idx), helium%beads)
3345 rp(:) = pos(:, endatom, 1) - xtrapos(:)
3349 DO iatom = 1, helium%atoms
3350 IF (iatom == endatom) cycle
3351 r(:) = pos(:, helium%iperm(iatom), helium%beads) - pos(:, startatom, helium%beads)
3352 rp(:) = pos(:, iatom, 1) - xtrapos(:)
3359 DEALLOCATE (work, work2, work3)
3361 END FUNCTION worm_path_action_worm_corrected
3375 REAL(kind=
dp)
FUNCTION worm_path_inter_action(pint_env, helium, pos, &
3376 startatom, startbead, endatom, endbead)
RESULT(partaction)
3378 TYPE(pint_env_type),
INTENT(IN) :: pint_env
3379 TYPE(helium_solvent_type),
INTENT(IN) :: helium
3380 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
3382 INTEGER,
INTENT(IN) :: startatom, startbead, endatom, endbead
3385 REAL(kind=
dp) :: energy
3392 IF (startbead < endbead)
THEN
3396 DO ibead = startbead + 1, endbead - 1
3398 startatom, ibead, pos(:, startatom, ibead), energy=energy)
3399 partaction = partaction + energy
3406 DO ibead = startbead + 1, helium%beads
3408 startatom, ibead, pos(:, startatom, ibead), energy=energy)
3409 partaction = partaction + energy
3412 DO ibead = 1, endbead - 1
3414 endatom, ibead, pos(:, endatom, ibead), energy=energy)
3415 partaction = partaction + energy
3419 partaction = partaction*helium%tau
3421 END FUNCTION worm_path_inter_action
3436 REAL(kind=
dp)
FUNCTION worm_path_inter_action_head(pint_env, helium, pos, &
3437 startatom, startbead, xtrapos, worm_atom_idx, worm_bead_idx)
RESULT(partaction)
3439 TYPE(pint_env_type),
INTENT(IN) :: pint_env
3440 TYPE(helium_solvent_type),
INTENT(IN) :: helium
3441 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
3443 INTEGER,
INTENT(IN) :: startatom, startbead
3444 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xtrapos
3445 INTEGER,
INTENT(IN) :: worm_atom_idx, worm_bead_idx
3448 REAL(kind=
dp) :: energy
3454 IF (startbead < worm_bead_idx)
THEN
3455 DO ibead = startbead + 1, worm_bead_idx - 1
3457 startatom, ibead, pos(:, startatom, ibead), energy=energy)
3458 partaction = partaction + energy
3461 startatom, ibead, xtrapos, energy=energy)
3462 partaction = partaction + 0.5_dp*energy
3464 DO ibead = startbead + 1, helium%beads
3466 startatom, ibead, pos(:, startatom, ibead), energy=energy)
3467 partaction = partaction + energy
3469 DO ibead = 1, worm_bead_idx - 1
3471 worm_atom_idx, ibead, pos(:, worm_atom_idx, ibead), energy=energy)
3472 partaction = partaction + energy
3475 worm_atom_idx, ibead, xtrapos, energy=energy)
3476 partaction = partaction + 0.5_dp*energy
3479 partaction = partaction*helium%tau
3481 END FUNCTION worm_path_inter_action_head
3495 REAL(kind=
dp)
FUNCTION worm_path_inter_action_tail(pint_env, helium, pos, &
3496 endatom, endbead, worm_atom_idx, worm_bead_idx)
RESULT(partaction)
3498 TYPE(pint_env_type),
INTENT(IN) :: pint_env
3499 TYPE(helium_solvent_type),
INTENT(IN) :: helium
3500 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
3502 INTEGER,
INTENT(IN) :: endatom, endbead, worm_atom_idx, &
3506 REAL(kind=
dp) :: energy
3512 IF (worm_bead_idx < endbead)
THEN
3514 worm_atom_idx, worm_bead_idx, pos(:, worm_atom_idx, worm_bead_idx), energy=energy)
3515 partaction = partaction + 0.5_dp*energy
3516 DO ibead = worm_bead_idx + 1, endbead - 1
3518 endatom, ibead, pos(:, endatom, ibead), energy=energy)
3519 partaction = partaction + energy
3523 worm_atom_idx, worm_bead_idx, pos(:, worm_atom_idx, worm_bead_idx), energy=energy)
3524 partaction = partaction + 0.5_dp*energy
3525 DO ibead = worm_bead_idx + 1, helium%beads
3527 worm_atom_idx, ibead, pos(:, worm_atom_idx, ibead), energy=energy)
3528 partaction = partaction + energy
3530 DO ibead = 1, endbead - 1
3532 endatom, ibead, pos(:, endatom, ibead), energy=energy)
3533 partaction = partaction + energy
3537 partaction = partaction*helium%tau
3539 END FUNCTION worm_path_inter_action_tail
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....
pure subroutine, public helium_calc_plength(helium)
Calculate probability distribution of the permutation lengths.
pure subroutine, public helium_update_coord_system(helium, pint_env)
Set coordinate system, e.g. for RHO calculations.
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.
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...
subroutine, public helium_calc_energy(helium, pint_env)
Calculate the helium energy (including helium-solute interaction)
I/O subroutines for helium.
subroutine, public helium_write_line(line)
Writes out a line of text to the default output unit.
Data types representing superfluid helium.
Methods dealing with the canonical worm alogrithm.
subroutine, public helium_sample_worm(helium, pint_env)
Main worm sampling routine.
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi