31#include "../base/base_uses.f90"
36 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
37 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'helium_worm'
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(:)
99 helium%work = helium%pos
101 nmc = helium%iter_rot
103 IF (helium%worm_allow_open)
THEN
106 imove = helium%rng_stream_uniform%next(1, helium%worm_all_limit)
107 IF (helium%worm_is_closed)
THEN
108 IF ((imove >= helium%worm_centroid_min) .AND. (imove <= helium%worm_centroid_max))
THEN
110 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
111 CALL worm_centroid_move(pint_env, helium, &
112 iatom, helium%worm_centroid_drmax, ac)
113 ncentratt = ncentratt + 1
114 ncentracc = ncentracc + ac
117 ELSE IF ((imove >= helium%worm_centroid_max + 1) .AND. (imove <= helium%worm_open_close_min - 1))
THEN
119 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
120 ibead = helium%rng_stream_uniform%next(1, helium%beads)
121 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
122 CALL worm_staging_move(pint_env, helium, &
123 iatom, ibead, staging_l, ac)
124 nstagatt = nstagatt + 1
125 nstagacc = nstagacc + ac
126 ELSE IF ((imove >= helium%worm_open_close_min) .AND. (imove <= helium%worm_open_close_max))
THEN
128 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
129 ibead = helium%rng_stream_uniform%next(1, helium%beads)
130 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
131 CALL worm_open_move(pint_env, helium, &
132 iatom, ibead, staging_l, ac)
133 nopenatt = nopenatt + 1
134 nopenacc = nopenacc + ac
137 cpabort(
"Undefined move selected in helium worm sampling!")
140 IF ((imove >= helium%worm_centroid_min) .AND. (imove <= helium%worm_centroid_max))
THEN
142 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
143 CALL worm_centroid_move(pint_env, helium, &
144 iatom, helium%worm_centroid_drmax, ac)
145 ncentratt = ncentratt + 1
146 ncentracc = ncentracc + ac
147 ELSE IF ((imove >= helium%worm_staging_min) .AND. (imove <= helium%worm_staging_max))
THEN
149 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
150 ibead = helium%rng_stream_uniform%next(1, helium%beads)
151 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
152 CALL worm_staging_move(pint_env, helium, &
153 iatom, ibead, staging_l, ac)
154 nstagatt = nstagatt + 1
155 nstagacc = nstagacc + ac
156 ELSE IF ((imove >= helium%worm_fcrawl_min) .AND. (imove <= helium%worm_fcrawl_max))
THEN
158 DO icrawl = 1, helium%worm_repeat_crawl
159 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
160 CALL worm_crawl_move_forward(pint_env, helium, &
162 ncrawlfwdatt = ncrawlfwdatt + 1
163 ncrawlfwdacc = ncrawlfwdacc + ac
165 ELSE IF ((imove >= helium%worm_bcrawl_min) .AND. (imove <= helium%worm_bcrawl_max))
THEN
167 DO icrawl = 1, helium%worm_repeat_crawl
168 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
169 CALL worm_crawl_move_backward(pint_env, helium, &
171 ncrawlbwdatt = ncrawlbwdatt + 1
172 ncrawlbwdacc = ncrawlbwdacc + ac
174 ELSE IF ((imove >= helium%worm_head_min) .AND. (imove <= helium%worm_head_max))
THEN
176 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
177 CALL worm_head_move(pint_env, helium, &
179 nmoveheadatt = nmoveheadatt + 1
180 nmoveheadacc = nmoveheadacc + ac
181 ELSE IF ((imove >= helium%worm_tail_min) .AND. (imove <= helium%worm_tail_max))
THEN
183 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
184 CALL worm_tail_move(pint_env, helium, &
186 nmovetailatt = nmovetailatt + 1
187 nmovetailacc = nmovetailacc + ac
188 ELSE IF ((imove >= helium%worm_swap_min) .AND. (imove <= helium%worm_swap_max))
THEN
189 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
190 CALL worm_swap_move(pint_env, helium, &
191 helium%atoms, staging_l, ac)
192 npswapacc = npswapacc + ac
193 nswapacc = nswapacc + ac
194 nswapatt = nswapatt + 1
195 ELSE IF ((imove >= helium%worm_open_close_min) .AND. (imove <= helium%worm_open_close_max))
THEN
197 staging_l = helium%rng_stream_uniform%next(2, helium%worm_staging_l)
198 CALL worm_close_move(pint_env, helium, &
200 ncloseatt = ncloseatt + 1
201 ncloseacc = ncloseacc + ac
204 cpabort(
"Undefined move selected in helium worm sampling!")
209 IF (helium%worm_is_closed)
THEN
211 IF (helium%solute_present)
THEN
215 helium%force_avrg(:, :) = helium%force_avrg(:, :) + helium%force_inst(:, :)
222 IF (helium%worm_is_closed)
THEN
228 IF (helium%worm_max_open_cycles > 0 .AND. ncycle > helium%worm_max_open_cycles)
THEN
229 nmc = helium%iter_rot
231 helium%pos = helium%savepos
232 helium%work = helium%pos
233 helium%permutation = helium%savepermutation
234 helium%iperm = helium%saveiperm
235 cpwarn(
"Trapped in open state, reset helium to closed state from last MD step.")
237 nmc = max(helium%iter_rot/10, 10)
243 imove = helium%rng_stream_uniform%next(1, helium%worm_all_limit)
245 IF ((imove >= helium%worm_centroid_min) .AND. (imove <= helium%worm_centroid_max))
THEN
247 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
248 CALL worm_centroid_move(pint_env, helium, &
249 iatom, helium%worm_centroid_drmax, ac)
250 ncentratt = ncentratt + 1
251 ncentracc = ncentracc + ac
252 ELSE IF ((imove >= helium%worm_staging_min) .AND. (imove <= helium%worm_staging_max))
THEN
254 iatom = helium%rng_stream_uniform%next(1, helium%atoms)
255 ibead = helium%rng_stream_uniform%next(1, helium%beads)
256 CALL worm_staging_move(pint_env, helium, &
257 iatom, ibead, helium%worm_staging_l, ac)
258 nstagatt = nstagatt + 1
259 nstagacc = nstagacc + ac
262 cpabort(
"Undefined move selected in helium worm sampling!")
268 IF (helium%solute_present)
THEN
272 helium%force_avrg(:, :) = helium%force_avrg(:, :) + helium%force_inst(:, :)
279 helium%num_accepted(1, 1) = ncentracc + nstagacc + nopenacc + ncloseacc + nswapacc + &
280 nmoveheadacc + nmovetailacc + ncrawlfwdacc + ncrawlbwdacc
281 helium%num_accepted(2, 1) = ncentratt + nstagatt + nopenatt + ncloseatt + nswapatt + &
282 nmoveheadatt + nmovetailatt + ncrawlfwdatt + ncrawlbwdatt
283 helium%worm_nstat = nstat
288 helium%energy_avrg(:) = helium%energy_inst(:)*real(helium%worm_nstat,
dp)
291 helium%plength_avrg(:) = helium%plength_inst(:)*real(helium%worm_nstat,
dp)
294 IF (helium%solute_present)
THEN
297 helium%force_avrg(:, :) = helium%force_avrg(:, :) + helium%force_inst(:, :)
301 IF (helium%worm_show_statistics)
THEN
302 WRITE (stmp, *)
'--------------------------------------------------'
304 WRITE (stmp,
'(A10,F15.5,2I10)')
'Opening: ', &
305 REAL(nopenacc,
dp)/
REAL(MAX(1, nopenatt), dp), &
308 WRITE (stmp,
'(A10,F15.5,2I10)')
'Closing: ', &
309 REAL(ncloseacc,
dp)/
REAL(MAX(1, ncloseatt), dp), &
312 WRITE (stmp,
'(A10,F15.5,2I10)')
'Move Head: ', &
313 REAL(nmoveheadacc,
dp)/
REAL(MAX(1, nmoveheadatt), dp), &
314 nmoveheadacc, nmoveheadatt
316 WRITE (stmp,
'(A10,F15.5,2I10)')
'Move Tail: ', &
317 REAL(nmovetailacc,
dp)/
REAL(MAX(1, nmovetailatt), dp), &
318 nmovetailacc, nmovetailatt
320 WRITE (stmp,
'(A10,F15.5,2I10)')
'Crawl FWD: ', &
321 REAL(ncrawlfwdacc,
dp)/
REAL(MAX(1, ncrawlfwdatt), dp), &
322 ncrawlfwdacc, ncrawlfwdatt
324 WRITE (stmp,
'(A10,F15.5,2I10)')
'Crawl BWD: ', &
325 REAL(ncrawlbwdacc,
dp)/
REAL(MAX(1, ncrawlbwdatt), dp), &
326 ncrawlbwdacc, ncrawlbwdatt
328 WRITE (stmp,
'(A10,F15.5,2I10)')
'Staging: ', &
329 REAL(nstagacc,
dp)/
REAL(MAX(1, nstagatt), dp), &
332 WRITE (stmp,
'(A10,F15.5,2I10)')
'Centroid: ', &
333 REAL(ncentracc,
dp)/
REAL(MAX(1, ncentratt), dp), &
336 WRITE (stmp,
'(A10,F15.5,2I10)')
'Select: ', &
337 REAL(npswapacc,
dp)/
REAL(MAX(1, nswapatt), dp), &
340 WRITE (stmp,
'(A10,F15.5,2I10)')
'Swapping: ', &
341 REAL(nswapacc,
dp)/
REAL(MAX(1, nswapatt), dp), &
344 WRITE (stmp, *)
"Open State Probability: ", real(ntot - nstat,
dp)/real(max(1, ntot),
dp), ntot - nstat, ntot
346 WRITE (stmp, *)
"Closed State Probability: ", real(nstat,
dp)/real(max(1, ntot),
dp), nstat, ntot
363 SUBROUTINE worm_centroid_move(pint_env, helium, iatom, drmax, ac)
367 INTEGER,
INTENT(IN) :: iatom
368 REAL(kind=
dp),
INTENT(IN) :: drmax
369 INTEGER,
INTENT(OUT) :: ac
371 INTEGER :: ia, ib, ic, jatom
372 LOGICAL :: should_reject, worm_in_moved_cycle
373 REAL(kind=
dp) :: rtmp, rtmpo, sdiff, snew, sold
374 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
377 rtmp = helium%rng_stream_uniform%next()
378 dr(ic) = (2.0_dp*rtmp - 1.0_dp)*drmax
381 IF (helium%worm_is_closed)
THEN
382 worm_in_moved_cycle = .false.
384 DO ib = 1, helium%beads
385 helium%work(:, iatom, ib) = helium%work(:, iatom, ib) + dr(:)
388 jatom = helium%permutation(iatom)
389 DO WHILE (jatom /= iatom)
390 DO ib = 1, helium%beads
391 helium%work(:, jatom, ib) = helium%work(:, jatom, ib) + dr(:)
394 jatom = helium%permutation(jatom)
397 worm_in_moved_cycle = (helium%worm_atom_idx == iatom)
400 DO ib = 1, helium%beads
401 helium%work(:, iatom, ib) = helium%work(:, iatom, ib) + dr(:)
404 jatom = helium%permutation(iatom)
405 DO WHILE (jatom /= iatom)
406 DO ib = 1, helium%beads
407 helium%work(:, jatom, ib) = helium%work(:, jatom, ib) + dr(:)
409 worm_in_moved_cycle = worm_in_moved_cycle .OR. (helium%worm_atom_idx == jatom)
411 jatom = helium%permutation(jatom)
414 IF (worm_in_moved_cycle)
THEN
415 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:) + dr(:)
419 sold = worm_centroid_move_action(helium, helium%pos, iatom, &
420 helium%worm_xtra_bead, worm_in_moved_cycle)
422 snew = worm_centroid_move_action(helium, helium%work, iatom, &
423 helium%worm_xtra_bead_work, worm_in_moved_cycle)
425 IF (helium%solute_present)
THEN
426 sold = sold + worm_centroid_move_inter_action(pint_env, helium, helium%pos, iatom, &
427 helium%worm_xtra_bead, worm_in_moved_cycle)
428 snew = snew + worm_centroid_move_inter_action(pint_env, helium, helium%work, iatom, &
429 helium%worm_xtra_bead_work, worm_in_moved_cycle)
435 should_reject = .false.
436 IF (sdiff < -100.0_dp)
THEN
437 should_reject = .true.
439 rtmp = helium%rng_stream_uniform%next()
440 IF (exp(sdiff) < rtmp)
THEN
441 should_reject = .true.
444 IF (should_reject)
THEN
447 DO ib = 1, helium%beads
448 helium%work(:, iatom, ib) = helium%pos(:, iatom, ib)
451 jatom = helium%permutation(iatom)
452 DO WHILE (jatom /= iatom)
453 DO ib = 1, helium%beads
454 helium%work(:, jatom, ib) = helium%pos(:, jatom, ib)
457 jatom = helium%permutation(jatom)
459 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
469 IF (.NOT. helium%periodic)
THEN
470 IF (helium%solute_present)
THEN
471 new_com(:) = helium%center(:)
472 old_com(:) = new_com(:)
475 DO ia = 1, helium%atoms
476 DO ib = 1, helium%beads
477 new_com(:) = new_com(:) + helium%work(:, ia, ib)
480 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
483 DO ia = 1, helium%atoms
484 DO ib = 1, helium%beads
485 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
488 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
490 should_reject = .false.
491 atom:
DO ia = 1, helium%atoms
493 DO ib = 1, helium%beads
494 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
496 dr(:) = dr(:)/real(helium%beads,
dp)
497 rtmp = dot_product(dr, dr)
498 IF (rtmp >= helium%droplet_radius**2)
THEN
500 DO ib = 1, helium%beads
501 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
503 dro(:) = dro(:)/real(helium%beads,
dp)
504 rtmpo = dot_product(dro, dro)
506 IF (rtmpo < rtmp)
THEN
508 should_reject = .true.
513 IF (should_reject)
THEN
516 DO ib = 1, helium%beads
517 helium%work(:, iatom, ib) = helium%pos(:, iatom, ib)
520 jatom = helium%permutation(iatom)
521 DO WHILE (jatom /= iatom)
522 DO ib = 1, helium%beads
523 helium%work(:, jatom, ib) = helium%pos(:, jatom, ib)
526 jatom = helium%permutation(jatom)
528 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
537 DO ib = 1, helium%beads
538 helium%pos(:, iatom, ib) = helium%work(:, iatom, ib)
541 jatom = helium%permutation(iatom)
542 DO WHILE (jatom /= iatom)
543 DO ib = 1, helium%beads
544 helium%pos(:, jatom, ib) = helium%work(:, jatom, ib)
547 jatom = helium%permutation(jatom)
549 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
551 END SUBROUTINE worm_centroid_move
563 REAL(kind=
dp)
FUNCTION worm_centroid_move_action(helium, pos, iatom, xtrapos, winc) &
567 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
569 INTEGER,
INTENT(IN) :: iatom
570 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xtrapos
571 LOGICAL,
INTENT(IN) :: winc
573 INTEGER :: ia, ib, jatom, katom, opatom, patom, &
576 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work2, work3
577 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: work
578 REAL(kind=
dp),
DIMENSION(3) :: r, rp
580 ALLOCATE (work(3, helium%beads + 1), work2(helium%beads + 1), work3(
SIZE(helium%uoffdiag, 1) + 1))
588 DO ia = 1, helium%atoms
589 IF (ia == jatom) cycle
591 katom = helium%permutation(jatom)
592 DO WHILE (katom /= jatom)
593 IF (katom == ia)
THEN
597 katom = helium%permutation(katom)
601 DO ib = 1, helium%beads
602 work(:, ib) = pos(:, ia, ib) - pos(:, jatom, ib)
604 work(:, helium%beads + 1) = pos(:, helium%permutation(ia), 1) - &
605 pos(:, helium%permutation(jatom), 1)
606 partaction = partaction +
helium_eval_chain(helium, work, helium%beads + 1, work2, work3)
609 jatom = helium%permutation(iatom)
610 DO WHILE (jatom /= iatom)
611 DO ia = 1, helium%atoms
612 IF (ia == jatom) cycle
614 katom = helium%permutation(jatom)
615 DO WHILE (katom /= jatom)
616 IF (katom == ia)
THEN
620 katom = helium%permutation(katom)
624 DO ib = 1, helium%beads
625 work(:, ib) = pos(:, ia, ib) - pos(:, jatom, ib)
627 work(:, helium%beads + 1) = pos(:, helium%permutation(ia), 1) - &
628 pos(:, helium%permutation(jatom), 1)
629 partaction = partaction +
helium_eval_chain(helium, work, helium%beads + 1, work2, work3)
631 jatom = helium%permutation(jatom)
634 IF (.NOT. helium%worm_is_closed)
THEN
635 wbead = helium%worm_bead_idx
637 IF (helium%worm_bead_idx == 1)
THEN
639 patom = helium%iperm(helium%worm_atom_idx)
641 DO ia = 1, helium%atoms
642 IF (ia == helium%worm_atom_idx) cycle
644 katom = helium%permutation(helium%worm_atom_idx)
645 DO WHILE (katom /= helium%worm_atom_idx)
646 IF (katom == ia)
THEN
650 katom = helium%permutation(katom)
655 opatom = helium%iperm(ia)
658 r(:) = pos(:, helium%worm_atom_idx, 1) - pos(:, ia, 1)
659 rp(:) = pos(:, patom, helium%beads) - pos(:, opatom, helium%beads)
663 r(:) = xtrapos(:) - pos(:, ia, 1)
669 DO ia = 1, helium%atoms
670 IF (ia == helium%worm_atom_idx) cycle
672 katom = helium%permutation(helium%worm_atom_idx)
673 DO WHILE (katom /= helium%worm_atom_idx)
674 IF (katom == ia)
THEN
678 katom = helium%permutation(katom)
683 r(:) = pos(:, helium%worm_atom_idx, wbead) - pos(:, ia, wbead)
684 rp(:) = pos(:, helium%worm_atom_idx, wbead - 1) - pos(:, ia, wbead - 1)
688 r(:) = xtrapos(:) - pos(:, ia, wbead)
693 IF (helium%worm_bead_idx == 1)
THEN
695 patom = helium%iperm(helium%worm_atom_idx)
696 opatom = helium%iperm(iatom)
698 r(:) = pos(:, helium%worm_atom_idx, 1) - pos(:, iatom, 1)
699 rp(:) = pos(:, patom, helium%beads) - pos(:, opatom, helium%beads)
703 r(:) = xtrapos(:) - pos(:, iatom, 1)
706 ia = helium%permutation(iatom)
707 DO WHILE (ia /= iatom)
708 opatom = helium%iperm(ia)
710 r(:) = pos(:, helium%worm_atom_idx, 1) - pos(:, ia, 1)
711 rp(:) = pos(:, patom, helium%beads) - pos(:, opatom, helium%beads)
715 r(:) = xtrapos(:) - pos(:, ia, 1)
717 ia = helium%permutation(ia)
722 r(:) = pos(:, helium%worm_atom_idx, wbead) - pos(:, iatom, wbead)
723 rp(:) = pos(:, helium%worm_atom_idx, wbead - 1) - pos(:, iatom, wbead - 1)
727 r(:) = xtrapos(:) - pos(:, iatom, wbead)
730 ia = helium%permutation(iatom)
731 DO WHILE (ia /= iatom)
733 r(:) = pos(:, helium%worm_atom_idx, wbead) - pos(:, ia, wbead)
734 rp(:) = pos(:, helium%worm_atom_idx, wbead - 1) - pos(:, ia, wbead - 1)
738 r(:) = xtrapos(:) - pos(:, ia, wbead)
740 ia = helium%permutation(ia)
745 DEALLOCATE (work, work2, work3)
747 END FUNCTION worm_centroid_move_action
760 REAL(kind=
dp)
FUNCTION worm_centroid_move_inter_action(pint_env, helium, pos, iatom, xtrapos, winc) &
765 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
767 INTEGER,
INTENT(IN) :: iatom
768 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xtrapos
769 LOGICAL,
INTENT(IN) :: winc
771 INTEGER :: jatom, jbead
772 REAL(kind=
dp) :: energy
780 IF (jatom == helium%worm_atom_idx)
THEN
782 DO jbead = 1, helium%worm_bead_idx - 1
784 jatom, jbead, pos(:, jatom, jbead), energy=energy)
785 partaction = partaction + energy
788 jbead = helium%worm_bead_idx
791 jatom, jbead, pos(:, jatom, jbead), energy=energy)
792 partaction = partaction + 0.5_dp*energy
795 jatom, jbead, xtrapos, energy=energy)
796 partaction = partaction + 0.5_dp*energy
798 DO jbead = helium%worm_bead_idx + 1, helium%beads
800 jatom, jbead, pos(:, jatom, jbead), energy=energy)
801 partaction = partaction + energy
804 DO jbead = 1, helium%beads
806 jatom, jbead, pos(:, jatom, jbead), energy=energy)
807 partaction = partaction + energy
810 jatom = helium%permutation(iatom)
811 DO WHILE (jatom /= iatom)
812 IF (jatom == helium%worm_atom_idx)
THEN
814 DO jbead = 1, helium%worm_bead_idx - 1
816 jatom, jbead, pos(:, jatom, jbead), energy=energy)
817 partaction = partaction + energy
820 jbead = helium%worm_bead_idx
823 jatom, jbead, pos(:, jatom, jbead), energy=energy)
824 partaction = partaction + 0.5_dp*energy
827 jatom, jbead, xtrapos, energy=energy)
828 partaction = partaction + 0.5_dp*energy
830 DO jbead = helium%worm_bead_idx + 1, helium%beads
832 jatom, jbead, pos(:, jatom, jbead), energy=energy)
833 partaction = partaction + energy
836 DO jbead = 1, helium%beads
838 jatom, jbead, pos(:, jatom, jbead), energy=energy)
839 partaction = partaction + energy
842 jatom = helium%permutation(jatom)
848 DO jbead = 1, helium%beads
850 jatom, jbead, pos(:, jatom, jbead), energy=energy)
851 partaction = partaction + energy
853 jatom = helium%permutation(iatom)
854 DO WHILE (jatom /= iatom)
855 DO jbead = 1, helium%beads
857 jatom, jbead, pos(:, jatom, jbead), energy=energy)
858 partaction = partaction + energy
860 jatom = helium%permutation(jatom)
864 partaction = partaction*helium%tau
866 END FUNCTION worm_centroid_move_inter_action
877 SUBROUTINE path_construct(helium, ri, rj, l, new_path)
881 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: ri, rj
882 INTEGER,
INTENT(IN) :: l
883 REAL(kind=
dp),
DIMENSION(3, l),
INTENT(OUT) :: new_path
885 INTEGER :: idim, istage
886 REAL(kind=
dp) :: imass, invstagemass, rk, weight
887 REAL(kind=
dp),
DIMENSION(3) :: re, rs
889 imass = 1.0_dp/helium%he_mass_au
892 re(:) = rj(:) - rs(:)
894 re(:) = re(:) + rs(:)
899 weight = 1.0_dp/(rk + 1.0_dp)
901 invstagemass = rk*weight*imass
904 new_path(idim, 1) = helium%rng_stream_gaussian%next(variance=helium%tau*invstagemass)
906 new_path(:, 1) = new_path(:, 1) + weight*(re(:) + rk*rs(:))
910 rk = real(l - istage + 1,
dp)
911 weight = 1.0_dp/(rk + 1.0_dp)
913 invstagemass = rk*weight*imass
916 new_path(idim, istage) = helium%rng_stream_gaussian%next(variance=helium%tau*invstagemass)
918 new_path(:, istage) = new_path(:, istage) + weight*(rk*new_path(:, istage - 1) + re(:))
921 END SUBROUTINE path_construct
933 SUBROUTINE worm_staging_move(pint_env, helium, startatom, startbead, l, ac)
937 INTEGER,
INTENT(IN) :: startatom, startbead, l
938 INTEGER,
INTENT(OUT) :: ac
940 INTEGER :: endatom, endbead, ia, ib, ibead, jbead
941 LOGICAL :: should_reject, worm_overlap
942 REAL(kind=
dp) :: rtmp, rtmpo, sdiff, snew, sold
943 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
944 REAL(kind=
dp),
DIMENSION(3, l) :: newsection
947 endbead = startbead + l + 1
949 IF (endbead > helium%beads)
THEN
950 endatom = helium%permutation(startatom)
951 endbead = endbead - helium%beads
957 IF (helium%worm_is_closed)
THEN
958 worm_overlap = .false.
961 worm_overlap = ((startbead < endbead) .AND. &
962 (helium%worm_bead_idx > startbead) .AND. &
963 (helium%worm_bead_idx <= endbead)) &
965 ((startbead > endbead) .AND. &
966 ((helium%worm_bead_idx > startbead) .OR. &
967 (helium%worm_bead_idx <= endbead)))
968 IF (worm_overlap)
THEN
970 IF (((helium%worm_atom_idx == startatom) .AND. (helium%worm_bead_idx >= startbead)) .OR. &
971 ((helium%worm_atom_idx == endatom) .AND. (helium%worm_bead_idx <= endbead)))
THEN
978 IF (worm_overlap)
THEN
979 sold = worm_path_action_worm_corrected(helium, helium%pos, &
980 startatom, startbead, endatom, endbead, &
981 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
983 sold = worm_path_action(helium, helium%pos, &
984 startatom, startbead, endatom, endbead)
987 IF (helium%solute_present)
THEN
990 sold = sold + worm_path_inter_action(pint_env, helium, helium%pos, &
991 startatom, startbead, endatom, endbead)
995 CALL path_construct(helium, &
996 helium%pos(:, startatom, startbead), &
997 helium%pos(:, endatom, endbead), l, &
1003 DO ibead = startbead + 1, min(helium%beads, startbead + l)
1004 helium%work(:, startatom, ibead) = newsection(:, jbead)
1008 IF (helium%beads < startbead + l)
THEN
1009 DO ibead = 1, endbead - 1
1010 helium%work(:, endatom, ibead) = newsection(:, jbead)
1016 IF (worm_overlap)
THEN
1017 snew = worm_path_action_worm_corrected(helium, helium%work, &
1018 startatom, startbead, endatom, endbead, &
1019 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1021 snew = worm_path_action(helium, helium%work, &
1022 startatom, startbead, endatom, endbead)
1025 IF (helium%solute_present)
THEN
1028 snew = snew + worm_path_inter_action(pint_env, helium, helium%work, &
1029 startatom, startbead, endatom, endbead)
1035 should_reject = .false.
1036 IF (sdiff < -100.0_dp)
THEN
1037 should_reject = .true.
1039 rtmp = helium%rng_stream_uniform%next()
1040 IF (exp(sdiff) < rtmp)
THEN
1041 should_reject = .true.
1044 IF (should_reject)
THEN
1048 DO ibead = startbead + 1, min(helium%beads, startbead + l)
1049 helium%work(:, startatom, ibead) = helium%pos(:, startatom, ibead)
1053 IF (helium%beads < startbead + l)
THEN
1054 DO ibead = 1, endbead - 1
1055 helium%work(:, endatom, ibead) = helium%pos(:, endatom, ibead)
1068 IF (.NOT. helium%periodic)
THEN
1069 IF (helium%solute_present)
THEN
1070 new_com(:) = helium%center(:)
1071 old_com(:) = new_com(:)
1074 DO ia = 1, helium%atoms
1075 DO ib = 1, helium%beads
1076 new_com(:) = new_com(:) + helium%work(:, ia, ib)
1079 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
1082 DO ia = 1, helium%atoms
1083 DO ib = 1, helium%beads
1084 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
1087 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
1089 should_reject = .false.
1090 atom:
DO ia = 1, helium%atoms
1092 DO ib = 1, helium%beads
1093 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
1095 dr(:) = dr(:)/real(helium%beads,
dp)
1096 rtmp = dot_product(dr, dr)
1097 IF (rtmp >= helium%droplet_radius**2)
THEN
1099 DO ib = 1, helium%beads
1100 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
1102 dro(:) = dro(:)/real(helium%beads,
dp)
1103 rtmpo = dot_product(dro, dro)
1105 IF (rtmpo < rtmp)
THEN
1107 should_reject = .true.
1112 IF (should_reject)
THEN
1116 DO ibead = startbead + 1, min(helium%beads, startbead + l)
1117 helium%work(:, startatom, ibead) = helium%pos(:, startatom, ibead)
1121 IF (helium%beads < startbead + l)
THEN
1122 DO ibead = 1, endbead - 1
1123 helium%work(:, endatom, ibead) = helium%pos(:, endatom, ibead)
1136 DO ibead = startbead + 1, min(helium%beads, startbead + l)
1137 helium%pos(:, startatom, ibead) = helium%work(:, startatom, ibead)
1141 IF (helium%beads < startbead + l)
THEN
1142 DO ibead = 1, endbead - 1
1143 helium%pos(:, endatom, ibead) = helium%work(:, endatom, ibead)
1148 END SUBROUTINE worm_staging_move
1160 SUBROUTINE worm_open_move(pint_env, helium, endatom, endbead, l, ac)
1164 INTEGER,
INTENT(IN) :: endatom, endbead, l
1165 INTEGER,
INTENT(OUT) :: ac
1167 INTEGER :: ia, ib, idim, kbead, startatom, startbead
1168 LOGICAL :: should_reject
1169 REAL(kind=
dp) :: distsq, mass, rtmp, rtmpo, sdiff, snew, &
1171 REAL(kind=
dp),
DIMENSION(3) :: distvec, dr, dro, new_com, old_com
1173 mass = helium%he_mass_au
1176 IF (l < endbead)
THEN
1179 startbead = endbead - l
1183 startatom = helium%iperm(endatom)
1184 startbead = endbead + helium%beads - l
1186 sold = worm_path_action(helium, helium%pos, &
1187 startatom, startbead, endatom, endbead)
1189 IF (helium%solute_present)
THEN
1193 sold = sold + worm_path_inter_action_head(pint_env, helium, helium%pos, &
1194 startatom, startbead, &
1195 helium%pos(:, endatom, endbead), endatom, endbead)
1198 helium%worm_is_closed = .false.
1199 helium%worm_atom_idx_work = endatom
1200 helium%worm_bead_idx_work = endbead
1203 IF (startbead < endbead)
THEN
1206 DO kbead = startbead + 1, endbead - 1
1208 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1209 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1214 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1215 helium%worm_xtra_bead_work(idim) = helium%work(idim, startatom, endbead - 1) + xr
1217 ELSE IF (endbead /= 1)
THEN
1220 DO kbead = startbead + 1, helium%beads
1222 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1223 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1228 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1229 helium%work(idim, endatom, 1) = helium%work(idim, startatom, helium%beads) + xr
1232 DO kbead = 2, endbead - 1
1234 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1235 helium%work(idim, endatom, kbead) = helium%work(idim, endatom, kbead - 1) + xr
1239 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1240 helium%worm_xtra_bead_work(idim) = helium%work(idim, endatom, endbead - 1) + xr
1245 DO kbead = startbead + 1, helium%beads
1247 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1248 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1253 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1254 helium%worm_xtra_bead_work(idim) = helium%work(idim, startatom, helium%beads) + xr
1258 snew = worm_path_action_worm_corrected(helium, helium%work, &
1259 startatom, startbead, endatom, endbead, &
1260 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1262 IF (helium%solute_present)
THEN
1263 snew = snew + worm_path_inter_action_head(pint_env, helium, helium%work, &
1264 startatom, startbead, &
1265 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1270 distvec(:) = helium%pos(:, startatom, startbead) - helium%pos(:, endatom, endbead)
1272 distsq = dot_product(distvec, distvec)
1276 sdiff = sdiff + distsq/(2.0_dp*helium%hb2m*real(l,
dp)*helium%tau)
1277 sdiff = sdiff + 1.5_dp*log(real(l,
dp)*helium%tau)
1278 sdiff = sdiff + helium%worm_ln_openclose_scale
1280 should_reject = .false.
1281 IF (sdiff < -100.0_dp)
THEN
1282 should_reject = .true.
1284 rtmp = helium%rng_stream_uniform%next()
1285 IF (exp(sdiff) < rtmp)
THEN
1286 should_reject = .true.
1289 IF (should_reject)
THEN
1293 IF (startbead < endbead)
THEN
1295 DO kbead = startbead + 1, endbead - 1
1296 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1301 DO kbead = startbead + 1, helium%beads
1302 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1305 DO kbead = 1, endbead - 1
1306 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1309 helium%worm_is_closed = .true.
1319 IF (.NOT. helium%periodic)
THEN
1320 IF (helium%solute_present)
THEN
1321 new_com(:) = helium%center(:)
1322 old_com(:) = new_com(:)
1325 DO ia = 1, helium%atoms
1326 DO ib = 1, helium%beads
1327 new_com(:) = new_com(:) + helium%work(:, ia, ib)
1330 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
1333 DO ia = 1, helium%atoms
1334 DO ib = 1, helium%beads
1335 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
1338 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
1340 should_reject = .false.
1341 atom:
DO ia = 1, helium%atoms
1343 DO ib = 1, helium%beads
1344 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
1346 dr(:) = dr(:)/real(helium%beads,
dp)
1347 rtmp = dot_product(dr, dr)
1348 IF (rtmp >= helium%droplet_radius**2)
THEN
1350 DO ib = 1, helium%beads
1351 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
1353 dro(:) = dro(:)/real(helium%beads,
dp)
1354 rtmpo = dot_product(dro, dro)
1356 IF (rtmpo < rtmp)
THEN
1358 should_reject = .true.
1363 IF (should_reject)
THEN
1366 IF (startbead < endbead)
THEN
1368 DO kbead = startbead + 1, endbead - 1
1369 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1374 DO kbead = startbead + 1, helium%beads
1375 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1378 DO kbead = 1, endbead - 1
1379 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1382 helium%worm_is_closed = .true.
1393 IF (startbead < endbead)
THEN
1395 DO kbead = startbead + 1, endbead - 1
1396 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1401 DO kbead = startbead + 1, helium%beads
1402 helium%pos(:, startatom, kbead) = helium%work(:, startatom, kbead)
1405 DO kbead = 1, endbead - 1
1406 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1409 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
1410 helium%worm_atom_idx = helium%worm_atom_idx_work
1411 helium%worm_bead_idx = helium%worm_bead_idx_work
1413 END SUBROUTINE worm_open_move
1423 SUBROUTINE worm_close_move(pint_env, helium, l, ac)
1427 INTEGER,
INTENT(IN) :: l
1428 INTEGER,
INTENT(OUT) :: ac
1430 INTEGER :: endatom, endbead, ia, ib, jbead, kbead, &
1431 startatom, startbead
1432 LOGICAL :: should_reject
1433 REAL(kind=
dp) :: distsq, mass, rtmp, rtmpo, sdiff, snew, &
1435 REAL(kind=
dp),
DIMENSION(3) :: distvec, dr, dro, new_com, old_com
1436 REAL(kind=
dp),
DIMENSION(3, l-1) :: newsection
1438 mass = helium%he_mass_au
1440 endatom = helium%worm_atom_idx
1441 endbead = helium%worm_bead_idx
1443 IF (l < endbead)
THEN
1446 startbead = endbead - l
1450 startatom = helium%iperm(endatom)
1451 startbead = endbead + helium%beads - l
1453 sold = worm_path_action_worm_corrected(helium, helium%pos, &
1454 startatom, startbead, endatom, endbead, &
1455 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
1457 IF (helium%solute_present)
THEN
1458 sold = sold + worm_path_inter_action_head(pint_env, helium, helium%pos, &
1459 startatom, startbead, &
1460 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
1465 CALL path_construct(helium, &
1466 helium%pos(:, startatom, startbead), &
1467 helium%pos(:, endatom, endbead), l - 1, &
1472 IF (startbead < endbead)
THEN
1474 DO kbead = startbead + 1, endbead - 1
1475 helium%work(:, endatom, kbead) = newsection(:, jbead)
1481 DO kbead = startbead + 1, helium%beads
1482 helium%work(:, startatom, kbead) = newsection(:, jbead)
1486 DO kbead = 1, endbead - 1
1487 helium%work(:, endatom, kbead) = newsection(:, jbead)
1492 helium%worm_is_closed = .true.
1494 snew = worm_path_action(helium, helium%work, &
1495 startatom, startbead, endatom, endbead)
1497 IF (helium%solute_present)
THEN
1501 snew = snew + worm_path_inter_action_head(pint_env, helium, helium%work, &
1502 startatom, startbead, &
1503 helium%work(:, endatom, endbead), endatom, endbead)
1508 distvec(:) = helium%pos(:, startatom, startbead) - helium%pos(:, endatom, endbead)
1510 distsq = dot_product(distvec, distvec)
1514 sdiff = sdiff - distsq/(2.0_dp*helium%hb2m*real(l,
dp)*helium%tau)
1515 sdiff = sdiff - 1.5_dp*log(real(l,
dp)*helium%tau)
1516 sdiff = sdiff - helium%worm_ln_openclose_scale
1518 should_reject = .false.
1519 IF (sdiff < -100.0_dp)
THEN
1520 should_reject = .true.
1522 rtmp = helium%rng_stream_uniform%next()
1523 IF (exp(sdiff) < rtmp)
THEN
1524 should_reject = .true.
1527 IF (should_reject)
THEN
1531 IF (startbead < endbead)
THEN
1533 DO kbead = startbead + 1, endbead - 1
1534 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1539 DO kbead = startbead + 1, helium%beads
1540 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1543 DO kbead = 1, endbead - 1
1544 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1547 helium%worm_is_closed = .false.
1557 IF (.NOT. helium%periodic)
THEN
1558 IF (helium%solute_present)
THEN
1559 new_com(:) = helium%center(:)
1560 old_com(:) = new_com(:)
1563 DO ia = 1, helium%atoms
1564 DO ib = 1, helium%beads
1565 new_com(:) = new_com(:) + helium%work(:, ia, ib)
1568 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
1571 DO ia = 1, helium%atoms
1572 DO ib = 1, helium%beads
1573 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
1576 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
1578 should_reject = .false.
1579 atom:
DO ia = 1, helium%atoms
1581 DO ib = 1, helium%beads
1582 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
1584 dr(:) = dr(:)/real(helium%beads,
dp)
1585 rtmp = dot_product(dr, dr)
1586 IF (rtmp >= helium%droplet_radius**2)
THEN
1588 DO ib = 1, helium%beads
1589 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
1591 dro(:) = dro(:)/real(helium%beads,
dp)
1592 rtmpo = dot_product(dro, dro)
1594 IF (rtmpo < rtmp)
THEN
1596 should_reject = .true.
1601 IF (should_reject)
THEN
1604 IF (startbead < endbead)
THEN
1606 DO kbead = startbead + 1, endbead - 1
1607 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1612 DO kbead = startbead + 1, helium%beads
1613 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1616 DO kbead = 1, endbead - 1
1617 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1620 helium%worm_is_closed = .false.
1629 IF (startbead < endbead)
THEN
1631 DO kbead = startbead + 1, endbead - 1
1632 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1637 DO kbead = startbead + 1, helium%beads
1638 helium%pos(:, startatom, kbead) = helium%work(:, startatom, kbead)
1641 DO kbead = 1, endbead - 1
1642 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1646 END SUBROUTINE worm_close_move
1656 SUBROUTINE worm_head_move(pint_env, helium, l, ac)
1660 INTEGER,
INTENT(IN) :: l
1661 INTEGER,
INTENT(OUT) :: ac
1663 INTEGER :: endatom, endbead, ia, ib, idim, kbead, &
1664 startatom, startbead
1665 LOGICAL :: should_reject
1666 REAL(kind=
dp) :: mass, rtmp, rtmpo, sdiff, snew, sold, xr
1667 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
1669 mass = helium%he_mass_au
1672 endatom = helium%worm_atom_idx
1673 endbead = helium%worm_bead_idx
1674 IF (l < endbead)
THEN
1677 startbead = endbead - l
1681 startatom = helium%iperm(endatom)
1682 startbead = endbead + helium%beads - l
1685 sold = worm_path_action_worm_corrected(helium, helium%pos, &
1686 startatom, startbead, endatom, endbead, &
1687 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
1689 IF (helium%solute_present)
THEN
1690 sold = sold + worm_path_inter_action_head(pint_env, helium, helium%pos, &
1691 startatom, startbead, &
1692 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
1696 IF (startbead < endbead)
THEN
1699 DO kbead = startbead + 1, endbead - 1
1701 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1702 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1707 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1708 helium%worm_xtra_bead_work(idim) = helium%work(idim, startatom, endbead - 1) + xr
1710 ELSE IF (endbead /= 1)
THEN
1713 DO kbead = startbead + 1, helium%beads
1715 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1716 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1721 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1722 helium%work(idim, endatom, 1) = helium%work(idim, startatom, helium%beads) + xr
1725 DO kbead = 2, endbead - 1
1727 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1728 helium%work(idim, endatom, kbead) = helium%work(idim, endatom, kbead - 1) + xr
1732 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1733 helium%worm_xtra_bead_work(idim) = helium%work(idim, endatom, endbead - 1) + xr
1738 DO kbead = startbead + 1, helium%beads
1740 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1741 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead - 1) + xr
1746 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1747 helium%worm_xtra_bead_work(idim) = helium%work(idim, startatom, helium%beads) + xr
1751 snew = worm_path_action_worm_corrected(helium, helium%work, &
1752 startatom, startbead, endatom, endbead, &
1753 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1755 IF (helium%solute_present)
THEN
1756 snew = snew + worm_path_inter_action_head(pint_env, helium, helium%work, &
1757 startatom, startbead, &
1758 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1766 should_reject = .false.
1767 IF (sdiff < -100.0_dp)
THEN
1768 should_reject = .true.
1770 rtmp = helium%rng_stream_uniform%next()
1771 IF (exp(sdiff) < rtmp)
THEN
1772 should_reject = .true.
1775 IF (should_reject)
THEN
1779 IF (startbead < endbead)
THEN
1781 DO kbead = startbead + 1, endbead - 1
1782 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1787 DO kbead = startbead + 1, helium%beads
1788 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1791 DO kbead = 1, endbead - 1
1792 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1795 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
1805 IF (.NOT. helium%periodic)
THEN
1806 IF (helium%solute_present)
THEN
1807 new_com(:) = helium%center(:)
1808 old_com(:) = new_com(:)
1811 DO ia = 1, helium%atoms
1812 DO ib = 1, helium%beads
1813 new_com(:) = new_com(:) + helium%work(:, ia, ib)
1816 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
1819 DO ia = 1, helium%atoms
1820 DO ib = 1, helium%beads
1821 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
1824 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
1826 should_reject = .false.
1827 atom:
DO ia = 1, helium%atoms
1829 DO ib = 1, helium%beads
1830 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
1832 dr(:) = dr(:)/real(helium%beads,
dp)
1833 rtmp = dot_product(dr, dr)
1834 IF (rtmp >= helium%droplet_radius**2)
THEN
1836 DO ib = 1, helium%beads
1837 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
1839 dro(:) = dro(:)/real(helium%beads,
dp)
1840 rtmpo = dot_product(dro, dro)
1842 IF (rtmpo < rtmp)
THEN
1844 should_reject = .true.
1849 IF (should_reject)
THEN
1852 IF (startbead < endbead)
THEN
1854 DO kbead = startbead + 1, endbead - 1
1855 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1860 DO kbead = startbead + 1, helium%beads
1861 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
1864 DO kbead = 1, endbead - 1
1865 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
1868 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
1877 IF (startbead < endbead)
THEN
1879 DO kbead = startbead + 1, endbead - 1
1880 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1885 DO kbead = startbead + 1, helium%beads
1886 helium%pos(:, startatom, kbead) = helium%work(:, startatom, kbead)
1889 DO kbead = 1, endbead - 1
1890 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
1893 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
1895 END SUBROUTINE worm_head_move
1905 SUBROUTINE worm_tail_move(pint_env, helium, l, ac)
1909 INTEGER,
INTENT(IN) :: l
1910 INTEGER,
INTENT(OUT) :: ac
1912 INTEGER :: endatom, endbead, ia, ib, idim, kbead, &
1913 startatom, startbead
1914 LOGICAL :: should_reject
1915 REAL(kind=
dp) :: mass, rtmp, rtmpo, sdiff, snew, sold, xr
1916 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
1918 mass = helium%he_mass_au
1921 startatom = helium%worm_atom_idx
1922 startbead = helium%worm_bead_idx
1923 endbead = startbead + l
1925 IF (endbead <= helium%beads)
THEN
1931 endatom = helium%permutation(startatom)
1932 endbead = endbead - helium%beads
1936 sold = worm_path_action(helium, helium%pos, &
1937 startatom, startbead, endatom, endbead)
1939 IF (helium%solute_present)
THEN
1940 sold = sold + worm_path_inter_action_tail(pint_env, helium, helium%pos, &
1942 helium%worm_atom_idx, helium%worm_bead_idx)
1946 IF (startbead < endbead)
THEN
1949 DO kbead = endbead - 1, startbead, -1
1951 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1952 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead + 1) + xr
1958 DO kbead = endbead - 1, 1, -1
1960 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1961 helium%work(idim, endatom, kbead) = helium%work(idim, endatom, kbead + 1) + xr
1967 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1968 helium%work(idim, startatom, helium%beads) = helium%work(idim, endatom, 1) + xr
1972 DO kbead = helium%beads - 1, startbead, -1
1974 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
1975 helium%work(idim, startatom, kbead) = helium%work(idim, startatom, kbead + 1) + xr
1981 snew = worm_path_action(helium, helium%work, &
1982 startatom, startbead, endatom, endbead)
1984 IF (helium%solute_present)
THEN
1985 snew = snew + worm_path_inter_action_tail(pint_env, helium, helium%work, &
1987 helium%worm_atom_idx_work, helium%worm_bead_idx_work)
1995 should_reject = .false.
1996 IF (sdiff < -100.0_dp)
THEN
1997 should_reject = .true.
1999 rtmp = helium%rng_stream_uniform%next()
2000 IF (exp(sdiff) < rtmp)
THEN
2001 should_reject = .true.
2004 IF (should_reject)
THEN
2008 IF (startbead < endbead)
THEN
2010 DO kbead = startbead, endbead - 1
2011 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
2016 DO kbead = startbead, helium%beads
2017 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
2020 DO kbead = 1, endbead - 1
2021 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
2024 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2034 IF (.NOT. helium%periodic)
THEN
2035 IF (helium%solute_present)
THEN
2036 new_com(:) = helium%center(:)
2037 old_com(:) = new_com(:)
2040 DO ia = 1, helium%atoms
2041 DO ib = 1, helium%beads
2042 new_com(:) = new_com(:) + helium%work(:, ia, ib)
2045 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
2048 DO ia = 1, helium%atoms
2049 DO ib = 1, helium%beads
2050 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
2053 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
2055 should_reject = .false.
2056 atom:
DO ia = 1, helium%atoms
2058 DO ib = 1, helium%beads
2059 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
2061 dr(:) = dr(:)/real(helium%beads,
dp)
2062 rtmp = dot_product(dr, dr)
2063 IF (rtmp >= helium%droplet_radius**2)
THEN
2065 DO ib = 1, helium%beads
2066 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
2068 dro(:) = dro(:)/real(helium%beads,
dp)
2069 rtmpo = dot_product(dro, dro)
2071 IF (rtmpo < rtmp)
THEN
2073 should_reject = .true.
2078 IF (should_reject)
THEN
2081 IF (startbead < endbead)
THEN
2083 DO kbead = startbead, endbead - 1
2084 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
2089 DO kbead = startbead, helium%beads
2090 helium%work(:, startatom, kbead) = helium%pos(:, startatom, kbead)
2093 DO kbead = 1, endbead - 1
2094 helium%work(:, endatom, kbead) = helium%pos(:, endatom, kbead)
2097 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2106 IF (startbead < endbead)
THEN
2108 DO kbead = startbead, endbead - 1
2109 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
2114 DO kbead = startbead, helium%beads
2115 helium%pos(:, startatom, kbead) = helium%work(:, startatom, kbead)
2118 DO kbead = 1, endbead - 1
2119 helium%pos(:, endatom, kbead) = helium%work(:, endatom, kbead)
2123 END SUBROUTINE worm_tail_move
2133 SUBROUTINE worm_crawl_move_forward(pint_env, helium, l, ac)
2137 INTEGER,
INTENT(IN) :: l
2138 INTEGER,
INTENT(OUT) :: ac
2140 INTEGER :: ia, ib, idim, kbead
2141 LOGICAL :: should_reject
2142 REAL(kind=
dp) :: mass, newtailpot, oldheadpot, &
2143 oldtailpot, rtmp, rtmpo, sdiff, snew, &
2145 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
2147 mass = helium%he_mass_au
2150 helium%worm_bead_idx_work = helium%worm_bead_idx + l
2151 IF (helium%worm_bead_idx_work > helium%beads)
THEN
2152 helium%worm_bead_idx_work = helium%worm_bead_idx_work - helium%beads
2153 helium%worm_atom_idx_work = helium%permutation(helium%worm_atom_idx)
2155 helium%worm_atom_idx_work = helium%worm_atom_idx
2160 sold = worm_path_action(helium, helium%pos, &
2161 helium%worm_atom_idx, helium%worm_bead_idx, &
2162 helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2163 IF (helium%solute_present)
THEN
2166 sold = sold + worm_path_inter_action(pint_env, helium, helium%pos, &
2167 helium%worm_atom_idx, helium%worm_bead_idx, &
2168 helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2173 helium%worm_atom_idx, helium%worm_bead_idx, &
2174 helium%pos(:, helium%worm_atom_idx, helium%worm_bead_idx), &
2176 oldtailpot = oldtailpot*helium%tau
2180 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2181 helium%pos(:, helium%worm_atom_idx_work, helium%worm_bead_idx_work), &
2183 newtailpot = newtailpot*helium%tau
2187 helium%worm_atom_idx, helium%worm_bead_idx, &
2188 helium%worm_xtra_bead, &
2190 oldheadpot = oldheadpot*helium%tau
2194 sold = sold + 0.5_dp*(oldtailpot + oldheadpot) + newtailpot
2198 helium%work(:, helium%worm_atom_idx, helium%worm_bead_idx) = helium%worm_xtra_bead
2201 IF (helium%worm_bead_idx < helium%worm_bead_idx_work)
THEN
2204 DO kbead = helium%worm_bead_idx + 1, helium%worm_bead_idx_work - 1
2206 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2207 helium%work(idim, helium%worm_atom_idx, kbead) = helium%work(idim, helium%worm_atom_idx, kbead - 1) + xr
2212 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2213 helium%worm_xtra_bead_work(idim) = helium%work(idim, helium%worm_atom_idx, helium%worm_bead_idx_work - 1) + xr
2215 ELSE IF (helium%worm_bead_idx_work /= 1)
THEN
2218 DO kbead = helium%worm_bead_idx + 1, helium%beads
2220 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2221 helium%work(idim, helium%worm_atom_idx, kbead) = helium%work(idim, helium%worm_atom_idx, kbead - 1) + xr
2226 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2227 helium%work(idim, helium%worm_atom_idx_work, 1) = helium%work(idim, helium%worm_atom_idx, helium%beads) + xr
2230 DO kbead = 2, helium%worm_bead_idx_work - 1
2232 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2233 helium%work(idim, helium%worm_atom_idx_work, kbead) = helium%work(idim, helium%worm_atom_idx_work, kbead - 1) + xr
2237 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2238 helium%worm_xtra_bead_work(idim) = helium%work(idim, helium%worm_atom_idx_work, helium%worm_bead_idx_work - 1) + xr
2243 DO kbead = helium%worm_bead_idx + 1, helium%beads
2245 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2246 helium%work(idim, helium%worm_atom_idx, kbead) = helium%work(idim, helium%worm_atom_idx, kbead - 1) + xr
2251 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2252 helium%worm_xtra_bead_work(idim) = helium%work(idim, helium%worm_atom_idx, helium%beads) + xr
2256 snew = worm_path_action_worm_corrected(helium, helium%work, &
2257 helium%worm_atom_idx, helium%worm_bead_idx, &
2258 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2259 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2261 IF (helium%solute_present)
THEN
2262 snew = snew + worm_path_inter_action_head(pint_env, helium, helium%work, &
2263 helium%worm_atom_idx, helium%worm_bead_idx, &
2264 helium%worm_xtra_bead_work, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2265 snew = snew + 0.5_dp*newtailpot + oldheadpot
2273 should_reject = .false.
2274 IF (sdiff < -100.0_dp)
THEN
2275 should_reject = .true.
2277 rtmp = helium%rng_stream_uniform%next()
2278 IF (exp(sdiff) < rtmp)
THEN
2279 should_reject = .true.
2282 IF (should_reject)
THEN
2286 IF (helium%worm_bead_idx < helium%worm_bead_idx_work)
THEN
2288 DO kbead = helium%worm_bead_idx, helium%worm_bead_idx_work - 1
2289 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2294 DO kbead = helium%worm_bead_idx, helium%beads
2295 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2298 DO kbead = 1, helium%worm_bead_idx_work - 1
2299 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2302 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2303 helium%worm_bead_idx_work = helium%worm_bead_idx
2304 helium%worm_atom_idx_work = helium%worm_atom_idx
2314 IF (.NOT. helium%periodic)
THEN
2315 IF (helium%solute_present)
THEN
2316 new_com(:) = helium%center(:)
2317 old_com(:) = new_com(:)
2320 DO ia = 1, helium%atoms
2321 DO ib = 1, helium%beads
2322 new_com(:) = new_com(:) + helium%work(:, ia, ib)
2325 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
2328 DO ia = 1, helium%atoms
2329 DO ib = 1, helium%beads
2330 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
2333 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
2335 should_reject = .false.
2336 atom:
DO ia = 1, helium%atoms
2338 DO ib = 1, helium%beads
2339 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
2341 dr(:) = dr(:)/real(helium%beads,
dp)
2342 rtmp = dot_product(dr, dr)
2343 IF (rtmp >= helium%droplet_radius**2)
THEN
2345 DO ib = 1, helium%beads
2346 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
2348 dro(:) = dro(:)/real(helium%beads,
dp)
2349 rtmpo = dot_product(dro, dro)
2351 IF (rtmpo < rtmp)
THEN
2353 should_reject = .true.
2358 IF (should_reject)
THEN
2361 IF (helium%worm_bead_idx < helium%worm_bead_idx_work)
THEN
2363 DO kbead = helium%worm_bead_idx, helium%worm_bead_idx_work - 1
2364 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2369 DO kbead = helium%worm_bead_idx, helium%beads
2370 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2373 DO kbead = 1, helium%worm_bead_idx_work - 1
2374 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2377 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2378 helium%worm_bead_idx_work = helium%worm_bead_idx
2379 helium%worm_atom_idx_work = helium%worm_atom_idx
2388 IF (helium%worm_bead_idx < helium%worm_bead_idx_work)
THEN
2390 DO kbead = helium%worm_bead_idx, helium%worm_bead_idx_work - 1
2391 helium%pos(:, helium%worm_atom_idx_work, kbead) = helium%work(:, helium%worm_atom_idx_work, kbead)
2396 DO kbead = helium%worm_bead_idx, helium%beads
2397 helium%pos(:, helium%worm_atom_idx, kbead) = helium%work(:, helium%worm_atom_idx, kbead)
2400 DO kbead = 1, helium%worm_bead_idx_work - 1
2401 helium%pos(:, helium%worm_atom_idx_work, kbead) = helium%work(:, helium%worm_atom_idx_work, kbead)
2404 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
2405 helium%worm_bead_idx = helium%worm_bead_idx_work
2406 helium%worm_atom_idx = helium%worm_atom_idx_work
2408 END SUBROUTINE worm_crawl_move_forward
2418 SUBROUTINE worm_crawl_move_backward(pint_env, helium, l, ac)
2422 INTEGER,
INTENT(IN) :: l
2423 INTEGER,
INTENT(OUT) :: ac
2425 INTEGER :: ia, ib, idim, kbead
2426 LOGICAL :: should_reject
2427 REAL(kind=
dp) :: mass, newheadpot, oldheadpot, &
2428 oldtailpot, rtmp, rtmpo, sdiff, snew, &
2430 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
2432 mass = helium%he_mass_au
2435 helium%worm_bead_idx_work = helium%worm_bead_idx - l
2436 IF (helium%worm_bead_idx_work < 1)
THEN
2437 helium%worm_bead_idx_work = helium%worm_bead_idx_work + helium%beads
2438 helium%worm_atom_idx_work = helium%iperm(helium%worm_atom_idx)
2440 helium%worm_atom_idx_work = helium%worm_atom_idx
2445 sold = worm_path_action_worm_corrected(helium, helium%work, &
2446 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2447 helium%worm_atom_idx, helium%worm_bead_idx, &
2448 helium%worm_xtra_bead, helium%worm_atom_idx, helium%worm_bead_idx)
2450 IF (helium%solute_present)
THEN
2453 sold = sold + worm_path_inter_action(pint_env, helium, helium%pos, &
2454 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2455 helium%worm_atom_idx, helium%worm_bead_idx)
2460 helium%worm_atom_idx, helium%worm_bead_idx, &
2461 helium%pos(:, helium%worm_atom_idx, helium%worm_bead_idx), &
2463 oldtailpot = oldtailpot*helium%tau
2467 helium%worm_atom_idx, helium%worm_bead_idx, &
2468 helium%worm_xtra_bead, &
2470 oldheadpot = oldheadpot*helium%tau
2474 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2475 helium%pos(:, helium%worm_atom_idx_work, helium%worm_bead_idx_work), &
2477 newheadpot = newheadpot*helium%tau
2481 sold = sold + 0.5_dp*(oldtailpot + oldheadpot) + newheadpot
2485 helium%worm_xtra_bead_work = helium%pos(:, helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2488 IF (helium%worm_bead_idx_work < helium%worm_bead_idx)
THEN
2491 DO kbead = helium%worm_bead_idx - 1, helium%worm_bead_idx_work, -1
2493 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2494 helium%work(idim, helium%worm_atom_idx, kbead) = helium%work(idim, helium%worm_atom_idx, kbead + 1) + xr
2501 DO kbead = helium%worm_bead_idx - 1, 1, -1
2503 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2504 helium%work(idim, helium%worm_atom_idx, kbead) = helium%work(idim, helium%worm_atom_idx, kbead + 1) + xr
2510 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2511 helium%work(idim, helium%worm_atom_idx_work, helium%beads) = helium%work(idim, helium%worm_atom_idx, 1) + xr
2515 DO kbead = helium%beads - 1, helium%worm_bead_idx_work, -1
2517 xr = helium%rng_stream_gaussian%next(variance=helium%hb2m*helium%tau)
2518 helium%work(idim, helium%worm_atom_idx_work, kbead) = helium%work(idim, helium%worm_atom_idx_work, kbead + 1) + xr
2523 snew = worm_path_action(helium, helium%work, &
2524 helium%worm_atom_idx_work, helium%worm_bead_idx_work, &
2525 helium%worm_atom_idx, helium%worm_bead_idx)
2527 IF (helium%solute_present)
THEN
2528 snew = snew + worm_path_inter_action_tail(pint_env, helium, helium%work, &
2529 helium%worm_atom_idx, helium%worm_bead_idx, &
2530 helium%worm_atom_idx_work, helium%worm_bead_idx_work)
2531 snew = snew + 0.5_dp*newheadpot + oldtailpot
2539 should_reject = .false.
2540 IF (sdiff < -100.0_dp)
THEN
2541 should_reject = .true.
2543 rtmp = helium%rng_stream_uniform%next()
2544 IF (exp(sdiff) < rtmp)
THEN
2545 should_reject = .true.
2548 IF (should_reject)
THEN
2552 IF (helium%worm_bead_idx_work < helium%worm_bead_idx)
THEN
2554 DO kbead = helium%worm_bead_idx_work, helium%worm_bead_idx - 1
2555 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2560 DO kbead = helium%worm_bead_idx_work, helium%beads
2561 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2564 DO kbead = 1, helium%worm_bead_idx - 1
2565 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2568 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2569 helium%worm_bead_idx_work = helium%worm_bead_idx
2570 helium%worm_atom_idx_work = helium%worm_atom_idx
2580 IF (.NOT. helium%periodic)
THEN
2581 IF (helium%solute_present)
THEN
2582 new_com(:) = helium%center(:)
2583 old_com(:) = new_com(:)
2586 DO ia = 1, helium%atoms
2587 DO ib = 1, helium%beads
2588 new_com(:) = new_com(:) + helium%work(:, ia, ib)
2591 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
2594 DO ia = 1, helium%atoms
2595 DO ib = 1, helium%beads
2596 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
2599 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
2601 should_reject = .false.
2602 atom:
DO ia = 1, helium%atoms
2604 DO ib = 1, helium%beads
2605 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
2607 dr(:) = dr(:)/real(helium%beads,
dp)
2608 rtmp = dot_product(dr, dr)
2609 IF (rtmp >= helium%droplet_radius**2)
THEN
2611 DO ib = 1, helium%beads
2612 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
2614 dro(:) = dro(:)/real(helium%beads,
dp)
2615 rtmpo = dot_product(dro, dro)
2617 IF (rtmpo < rtmp)
THEN
2619 should_reject = .true.
2624 IF (should_reject)
THEN
2629 IF (helium%worm_bead_idx_work < helium%worm_bead_idx)
THEN
2631 DO kbead = helium%worm_bead_idx_work, helium%worm_bead_idx - 1
2632 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2637 DO kbead = helium%worm_bead_idx_work, helium%beads
2638 helium%work(:, helium%worm_atom_idx_work, kbead) = helium%pos(:, helium%worm_atom_idx_work, kbead)
2641 DO kbead = 1, helium%worm_bead_idx - 1
2642 helium%work(:, helium%worm_atom_idx, kbead) = helium%pos(:, helium%worm_atom_idx, kbead)
2645 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2646 helium%worm_bead_idx_work = helium%worm_bead_idx
2647 helium%worm_atom_idx_work = helium%worm_atom_idx
2657 IF (helium%worm_bead_idx_work < helium%worm_bead_idx)
THEN
2659 DO kbead = helium%worm_bead_idx_work, helium%worm_bead_idx - 1
2660 helium%pos(:, helium%worm_atom_idx, kbead) = helium%work(:, helium%worm_atom_idx, kbead)
2665 DO kbead = helium%worm_bead_idx_work, helium%beads
2666 helium%pos(:, helium%worm_atom_idx_work, kbead) = helium%work(:, helium%worm_atom_idx_work, kbead)
2669 DO kbead = 1, helium%worm_bead_idx - 1
2670 helium%pos(:, helium%worm_atom_idx, kbead) = helium%work(:, helium%worm_atom_idx, kbead)
2673 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
2674 helium%worm_bead_idx = helium%worm_bead_idx_work
2675 helium%worm_atom_idx = helium%worm_atom_idx_work
2677 END SUBROUTINE worm_crawl_move_backward
2688 REAL(kind=
dp)
FUNCTION free_density_matrix(helium, startpos, endpos, l)
RESULT(rho)
2691 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: startpos, endpos
2692 INTEGER,
INTENT(IN) :: l
2694 REAL(kind=
dp) :: distsq, prefac
2695 REAL(kind=
dp),
DIMENSION(3) :: dvec
2697 dvec(:) = startpos(:) - endpos(:)
2699 distsq = dot_product(dvec, dvec)
2701 prefac = 0.5_dp/(helium%hb2m*real(l,
dp)*helium%tau)
2702 rho = -prefac*distsq
2704 rho = rho*(sqrt(prefac/
pi))**3
2706 END FUNCTION free_density_matrix
2717 SUBROUTINE worm_swap_move(pint_env, helium, natoms, l, ac)
2721 INTEGER,
INTENT(IN) :: natoms, l
2722 INTEGER,
INTENT(OUT) :: ac
2724 INTEGER :: bendatom, bstartatom, endbead, &
2725 excludeatom, fendatom, fstartatom, ia, &
2726 iatom, ib, ibead, jbead, kbead, &
2728 LOGICAL :: should_reject
2729 REAL(kind=
dp) :: backwarddensmatsum, forwarddensmatsum, &
2730 mass, newheadpotential, &
2731 oldheadpotential, rtmp, rtmpo, sdiff, &
2733 REAL(kind=
dp),
DIMENSION(3) :: dr, dro, new_com, old_com
2734 REAL(kind=
dp),
DIMENSION(3, l) :: newsection
2735 REAL(kind=
dp),
DIMENSION(natoms) :: backwarddensmat, forwarddensmat
2738 startbead = helium%worm_bead_idx
2739 endbead = helium%worm_bead_idx + l + 1
2740 fstartatom = helium%worm_atom_idx
2741 excludeatom = fstartatom
2744 IF (endbead > helium%beads)
THEN
2745 endbead = endbead - helium%beads
2747 excludeatom = helium%permutation(excludeatom)
2749 DO iatom = 1, excludeatom - 1
2750 forwarddensmat(iatom) = free_density_matrix(helium, helium%worm_xtra_bead(:), &
2751 helium%pos(:, iatom, endbead), l + 1)
2753 forwarddensmat(excludeatom) = 0.0_dp
2754 DO iatom = excludeatom + 1, natoms
2755 forwarddensmat(iatom) = free_density_matrix(helium, helium%worm_xtra_bead(:), &
2756 helium%pos(:, iatom, endbead), l + 1)
2758 forwarddensmatsum = sum(forwarddensmat)
2759 IF (forwarddensmatsum == 0.0_dp)
THEN
2765 rtmp = helium%rng_stream_uniform%next()*forwarddensmatsum
2767 DO WHILE (rtmp >= forwarddensmat(fendatom))
2768 rtmp = rtmp - forwarddensmat(fendatom)
2769 fendatom = fendatom + 1
2772 fendatom = min(fendatom, natoms)
2773 IF (fendatom == excludeatom)
THEN
2779 IF (endbead > startbead)
THEN
2780 bstartatom = fendatom
2782 bstartatom = helium%iperm(fendatom)
2786 DO iatom = 1, excludeatom - 1
2787 backwarddensmat(iatom) = free_density_matrix(helium, &
2788 helium%pos(:, bstartatom, startbead), &
2789 helium%pos(:, iatom, endbead), l + 1)
2791 backwarddensmat(excludeatom) = 0.0_dp
2792 DO iatom = excludeatom + 1, natoms
2793 backwarddensmat(iatom) = free_density_matrix(helium, &
2794 helium%pos(:, bstartatom, startbead), &
2795 helium%pos(:, iatom, endbead), l + 1)
2798 backwarddensmatsum = sum(backwarddensmat)
2800 mass = helium%he_mass_au
2803 sold = worm_path_action(helium, helium%pos, &
2804 bstartatom, startbead, fendatom, endbead)
2806 IF (helium%solute_present)
THEN
2809 sold = sold + worm_path_inter_action(pint_env, helium, helium%pos, &
2810 bstartatom, startbead, fendatom, endbead)
2813 fstartatom, startbead, helium%worm_xtra_bead, &
2814 energy=oldheadpotential)
2815 oldheadpotential = oldheadpotential*helium%tau
2818 bstartatom, startbead, helium%pos(:, bstartatom, startbead), &
2819 energy=newheadpotential)
2820 newheadpotential = newheadpotential*helium%tau
2822 sold = sold + 0.5_dp*oldheadpotential + newheadpotential
2827 CALL path_construct(helium, &
2828 helium%worm_xtra_bead(:), &
2829 helium%pos(:, fendatom, endbead), l, &
2835 IF (startbead < endbead)
THEN
2837 DO kbead = startbead + 1, endbead - 1
2838 helium%work(:, fstartatom, kbead) = newsection(:, jbead)
2844 DO kbead = startbead + 1, helium%beads
2845 helium%work(:, fstartatom, kbead) = newsection(:, jbead)
2849 DO ibead = 1, endbead - 1
2850 helium%work(:, fendatom, ibead) = newsection(:, jbead)
2856 helium%work(:, helium%worm_atom_idx, helium%worm_bead_idx) = helium%worm_xtra_bead(:)
2857 helium%worm_xtra_bead_work(:) = helium%pos(:, bstartatom, startbead)
2860 DO ib = startbead, helium%beads
2861 helium%work(:, bstartatom, ib) = helium%pos(:, fstartatom, ib)
2864 IF (endbead > startbead)
THEN
2865 DO ib = endbead, helium%beads
2866 helium%work(:, fstartatom, ib) = helium%pos(:, bstartatom, ib)
2871 tmpi = helium%permutation(bstartatom)
2872 helium%permutation(bstartatom) = helium%permutation(fstartatom)
2873 helium%permutation(fstartatom) = tmpi
2875 DO ib = 1,
SIZE(helium%permutation)
2876 helium%iperm(helium%permutation(ib)) = ib
2878 helium%worm_atom_idx_work = bstartatom
2881 IF (endbead > startbead)
THEN
2882 snew = worm_path_action(helium, helium%work, &
2883 fstartatom, startbead, fstartatom, endbead)
2884 IF (helium%solute_present)
THEN
2887 snew = snew + worm_path_inter_action(pint_env, helium, helium%work, &
2888 fstartatom, startbead, fstartatom, endbead)
2891 snew = snew + oldheadpotential + 0.5_dp*newheadpotential
2894 snew = worm_path_action(helium, helium%work, &
2895 fstartatom, startbead, helium%permutation(fstartatom), endbead)
2896 IF (helium%solute_present)
THEN
2899 snew = snew + worm_path_inter_action(pint_env, helium, helium%work, &
2900 fstartatom, startbead, helium%permutation(fstartatom), endbead)
2903 snew = snew + oldheadpotential + 0.5_dp*newheadpotential
2909 sdiff = sdiff + log(forwarddensmatsum/backwarddensmatsum)
2911 should_reject = .false.
2912 IF (sdiff < -100.0_dp)
THEN
2913 should_reject = .true.
2915 rtmp = helium%rng_stream_uniform%next()
2916 IF (exp(sdiff) < rtmp)
THEN
2917 should_reject = .true.
2920 IF (should_reject)
THEN
2923 DO kbead = startbead, helium%beads
2924 helium%work(:, bstartatom, kbead) = helium%pos(:, bstartatom, kbead)
2926 DO kbead = startbead, helium%beads
2927 helium%work(:, fstartatom, kbead) = helium%pos(:, fstartatom, kbead)
2929 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
2930 helium%worm_atom_idx_work = helium%worm_atom_idx
2931 IF (startbead > endbead)
THEN
2932 DO kbead = 1, endbead
2933 helium%work(:, fendatom, kbead) = helium%pos(:, fendatom, kbead)
2937 tmpi = helium%permutation(bstartatom)
2938 helium%permutation(bstartatom) = helium%permutation(fstartatom)
2939 helium%permutation(fstartatom) = tmpi
2941 DO ib = 1,
SIZE(helium%permutation)
2942 helium%iperm(helium%permutation(ib)) = ib
2953 IF (.NOT. helium%periodic)
THEN
2954 IF (helium%solute_present)
THEN
2955 new_com(:) = helium%center(:)
2956 old_com(:) = new_com(:)
2959 DO ia = 1, helium%atoms
2960 DO ib = 1, helium%beads
2961 new_com(:) = new_com(:) + helium%work(:, ia, ib)
2964 new_com(:) = new_com(:)/(real(helium%atoms*helium%beads,
dp))
2967 DO ia = 1, helium%atoms
2968 DO ib = 1, helium%beads
2969 old_com(:) = old_com(:) + helium%pos(:, ia, ib)
2972 old_com(:) = old_com(:)/(real(helium%atoms*helium%beads,
dp))
2974 should_reject = .false.
2975 atom:
DO ia = 1, helium%atoms
2977 DO ib = 1, helium%beads
2978 dr(:) = dr(:) + helium%work(:, ia, ib) - new_com(:)
2980 dr(:) = dr(:)/real(helium%beads,
dp)
2981 rtmp = dot_product(dr, dr)
2982 IF (rtmp >= helium%droplet_radius**2)
THEN
2984 DO ib = 1, helium%beads
2985 dro(:) = dro(:) + helium%pos(:, ia, ib) - old_com(:)
2987 dro(:) = dro(:)/real(helium%beads,
dp)
2988 rtmpo = dot_product(dro, dro)
2990 IF (rtmpo < rtmp)
THEN
2992 should_reject = .true.
2997 IF (should_reject)
THEN
2999 DO kbead = startbead, helium%beads
3000 helium%work(:, bstartatom, kbead) = helium%pos(:, bstartatom, kbead)
3002 DO kbead = startbead, helium%beads
3003 helium%work(:, fstartatom, kbead) = helium%pos(:, fstartatom, kbead)
3005 helium%worm_xtra_bead_work(:) = helium%worm_xtra_bead(:)
3006 helium%worm_atom_idx_work = helium%worm_atom_idx
3007 IF (startbead > endbead)
THEN
3008 DO kbead = 1, endbead
3009 helium%work(:, fendatom, kbead) = helium%pos(:, fendatom, kbead)
3014 tmpi = helium%permutation(bstartatom)
3015 helium%permutation(bstartatom) = helium%permutation(fstartatom)
3016 helium%permutation(fstartatom) = tmpi
3018 DO ib = 1,
SIZE(helium%permutation)
3019 helium%iperm(helium%permutation(ib)) = ib
3028 DO kbead = startbead, helium%beads
3029 helium%pos(:, bstartatom, kbead) = helium%work(:, bstartatom, kbead)
3031 DO kbead = startbead, helium%beads
3032 helium%pos(:, fstartatom, kbead) = helium%work(:, fstartatom, kbead)
3034 helium%worm_xtra_bead(:) = helium%worm_xtra_bead_work(:)
3035 helium%worm_atom_idx = helium%worm_atom_idx_work
3036 IF (startbead > endbead)
THEN
3037 DO kbead = 1, endbead
3038 helium%pos(:, fendatom, kbead) = helium%work(:, fendatom, kbead)
3042 END SUBROUTINE worm_swap_move
3055 REAL(kind=
dp)
FUNCTION worm_path_action(helium, pos, &
3056 startatom, startbead, endatom, endbead)
RESULT(partaction)
3059 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
3061 INTEGER,
INTENT(IN) :: startatom, startbead, endatom, endbead
3063 INTEGER :: iatom, ibead
3064 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work2, work3
3065 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: work
3067 ALLOCATE (work(3, helium%beads + 1), work2(helium%beads + 1), work3(
SIZE(helium%uoffdiag, 1) + 1))
3071 IF (startbead < endbead)
THEN
3074 DO iatom = 1, helium%atoms
3076 IF (iatom == startatom) cycle
3079 DO ibead = startbead, endbead
3080 work(:, ibead + 1 - startbead) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3082 partaction = partaction +
helium_eval_chain(helium, work, endbead - startbead + 1, work2, work3)
3087 DO iatom = 1, helium%atoms
3089 IF (iatom == startatom) cycle
3092 DO ibead = startbead, helium%beads
3093 work(:, ibead + 1 - startbead) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3096 work(:, helium%beads + 2 - startbead) = pos(:, helium%permutation(iatom), 1) - pos(:, endatom, 1)
3097 partaction = partaction +
helium_eval_chain(helium, work, helium%beads - startbead + 2, work2, work3)
3101 DO iatom = 1, helium%atoms
3103 IF (iatom == endatom) cycle
3105 IF (endbead > 1)
THEN
3106 DO ibead = 1, endbead
3107 work(:, ibead) = pos(:, iatom, ibead) - pos(:, endatom, ibead)
3109 partaction = partaction +
helium_eval_chain(helium, work, endbead, work2, work3)
3114 DEALLOCATE (work, work2, work3)
3116 END FUNCTION worm_path_action
3132 REAL(kind=
dp)
FUNCTION worm_path_action_worm_corrected(helium, pos, &
3133 startatom, startbead, endatom, endbead, xtrapos, worm_atom_idx, worm_bead_idx)
RESULT(partaction)
3136 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
3138 INTEGER,
INTENT(IN) :: startatom, startbead, endatom, endbead
3139 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xtrapos
3140 INTEGER,
INTENT(IN) :: worm_atom_idx, worm_bead_idx
3142 INTEGER :: iatom, ibead
3143 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work2, work3
3144 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: work
3145 REAL(kind=
dp),
DIMENSION(3) :: r, rp
3147 ALLOCATE (work(3, helium%beads + 1), work2(helium%beads + 1), work3(
SIZE(helium%uoffdiag, 1) + 1))
3151 IF (startbead < endbead)
THEN
3154 DO iatom = 1, helium%atoms
3156 IF (iatom == startatom) cycle
3159 IF (worm_bead_idx - startbead > 1)
THEN
3160 DO ibead = startbead, worm_bead_idx - 1
3161 work(:, ibead + 1 - startbead) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3163 partaction = partaction +
helium_eval_chain(helium, work, worm_bead_idx - startbead, work2, work3)
3166 IF (endbead > worm_bead_idx)
THEN
3167 DO ibead = worm_bead_idx, endbead
3168 work(:, ibead + 1 - worm_bead_idx) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3170 partaction = partaction +
helium_eval_chain(helium, work, endbead - worm_bead_idx + 1, work2, work3)
3174 IF (worm_atom_idx /= startatom)
THEN
3175 DO iatom = 1, helium%atoms
3176 IF (iatom == startatom) cycle
3177 IF (iatom == worm_atom_idx) cycle
3178 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, startatom, worm_bead_idx - 1)
3179 rp(:) = pos(:, iatom, worm_bead_idx) - pos(:, startatom, worm_bead_idx)
3183 r(:) = pos(:, startatom, worm_bead_idx - 1) - pos(:, worm_atom_idx, worm_bead_idx - 1)
3184 rp(:) = pos(:, startatom, worm_bead_idx) - xtrapos(:)
3188 DO iatom = 1, helium%atoms
3189 IF (iatom == startatom) cycle
3190 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, startatom, worm_bead_idx - 1)
3191 rp(:) = pos(:, iatom, worm_bead_idx) - xtrapos(:)
3198 IF (worm_bead_idx > startbead)
THEN
3200 DO iatom = 1, helium%atoms
3202 IF (iatom == startatom) cycle
3205 IF (worm_bead_idx - startbead > 1)
THEN
3206 DO ibead = startbead, worm_bead_idx - 1
3207 work(:, ibead + 1 - startbead) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3209 partaction = partaction +
helium_eval_chain(helium, work, worm_bead_idx - startbead, work2, work3)
3213 DO ibead = worm_bead_idx, helium%beads
3214 work(:, ibead + 1 - worm_bead_idx) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3217 work(:, helium%beads - worm_bead_idx + 2) = pos(:, helium%permutation(iatom), 1) - &
3218 pos(:, helium%permutation(startatom), 1)
3219 partaction = partaction +
helium_eval_chain(helium, work, helium%beads - worm_bead_idx + 2, work2, work3)
3224 DO iatom = 1, helium%atoms
3226 IF (iatom == endatom) cycle
3228 IF (endbead > 1)
THEN
3229 DO ibead = 1, endbead
3230 work(:, ibead) = pos(:, iatom, ibead) - pos(:, endatom, ibead)
3232 partaction = partaction +
helium_eval_chain(helium, work, endbead, work2, work3)
3236 IF (worm_atom_idx /= startatom)
THEN
3237 DO iatom = 1, helium%atoms
3238 IF (iatom == startatom) cycle
3239 IF (iatom == worm_atom_idx) cycle
3240 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, startatom, worm_bead_idx - 1)
3241 rp(:) = pos(:, iatom, worm_bead_idx) - pos(:, startatom, worm_bead_idx)
3245 r(:) = pos(:, startatom, worm_bead_idx - 1) - pos(:, worm_atom_idx, worm_bead_idx - 1)
3246 rp(:) = pos(:, startatom, worm_bead_idx) - xtrapos(:)
3250 DO iatom = 1, helium%atoms
3251 IF (iatom == startatom) cycle
3252 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, startatom, worm_bead_idx - 1)
3253 rp(:) = pos(:, iatom, worm_bead_idx) - xtrapos(:)
3258 IF (worm_bead_idx /= 1)
THEN
3259 DO iatom = 1, helium%atoms
3261 IF (iatom == startatom) cycle
3264 DO ibead = startbead, helium%beads
3265 work(:, ibead + 1 - startbead) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3268 work(:, helium%beads - startbead + 2) = pos(:, helium%permutation(iatom), 1) - pos(:, helium%permutation(startatom), 1)
3269 partaction = partaction +
helium_eval_chain(helium, work, helium%beads - startbead + 2, work2, work3)
3273 DO iatom = 1, helium%atoms
3275 IF (iatom == endatom) cycle
3277 IF (worm_bead_idx > 2)
THEN
3278 DO ibead = 1, worm_bead_idx - 1
3279 work(:, ibead) = pos(:, iatom, ibead) - pos(:, endatom, ibead)
3281 partaction = partaction +
helium_eval_chain(helium, work, worm_bead_idx - 1, work2, work3)
3284 IF (endbead > worm_bead_idx)
THEN
3285 DO ibead = worm_bead_idx, endbead
3286 work(:, ibead - worm_bead_idx + 1) = pos(:, iatom, ibead) - pos(:, endatom, ibead)
3288 partaction = partaction +
helium_eval_chain(helium, work, endbead - worm_bead_idx + 1, work2, work3)
3292 IF (worm_atom_idx /= endatom)
THEN
3293 DO iatom = 1, helium%atoms
3294 IF (iatom == endatom) cycle
3295 IF (iatom == worm_atom_idx) cycle
3296 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, endatom, worm_bead_idx - 1)
3297 rp(:) = pos(:, iatom, worm_bead_idx) - pos(:, endatom, worm_bead_idx)
3301 r(:) = pos(:, endatom, worm_bead_idx - 1) - pos(:, worm_atom_idx, worm_bead_idx - 1)
3302 rp(:) = pos(:, endatom, worm_bead_idx) - xtrapos(:)
3306 DO iatom = 1, helium%atoms
3307 IF (iatom == endatom) cycle
3308 r(:) = pos(:, iatom, worm_bead_idx - 1) - pos(:, endatom, worm_bead_idx - 1)
3309 rp(:) = pos(:, iatom, worm_bead_idx) - xtrapos(:)
3315 DO iatom = 1, helium%atoms
3317 IF (iatom == startatom) cycle
3320 IF (helium%beads > startbead)
THEN
3321 DO ibead = startbead, helium%beads
3322 work(:, ibead - startbead + 1) = pos(:, iatom, ibead) - pos(:, startatom, ibead)
3324 partaction = partaction +
helium_eval_chain(helium, work, helium%beads - startbead + 1, work2, work3)
3329 DO iatom = 1, helium%atoms
3330 IF (endbead > 1)
THEN
3331 DO ibead = 1, endbead
3332 work(:, ibead) = pos(:, iatom, ibead) - pos(:, endatom, ibead)
3334 partaction = partaction +
helium_eval_chain(helium, work, endbead, work2, work3)
3338 IF (worm_atom_idx /= endatom)
THEN
3339 DO iatom = 1, helium%atoms
3340 IF (iatom == endatom) cycle
3341 IF (iatom == worm_atom_idx) cycle
3342 r(:) = pos(:, helium%iperm(iatom), helium%beads) - pos(:, startatom, helium%beads)
3343 rp(:) = pos(:, iatom, 1) - pos(:, endatom, 1)
3347 r(:) = pos(:, startatom, helium%beads) - pos(:, helium%iperm(worm_atom_idx), helium%beads)
3348 rp(:) = pos(:, endatom, 1) - xtrapos(:)
3352 DO iatom = 1, helium%atoms
3353 IF (iatom == endatom) cycle
3354 r(:) = pos(:, helium%iperm(iatom), helium%beads) - pos(:, startatom, helium%beads)
3355 rp(:) = pos(:, iatom, 1) - xtrapos(:)
3362 DEALLOCATE (work, work2, work3)
3364 END FUNCTION worm_path_action_worm_corrected
3378 REAL(kind=
dp)
FUNCTION worm_path_inter_action(pint_env, helium, pos, &
3379 startatom, startbead, endatom, endbead)
RESULT(partaction)
3383 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
3385 INTEGER,
INTENT(IN) :: startatom, startbead, endatom, endbead
3388 REAL(kind=
dp) :: energy
3395 IF (startbead < endbead)
THEN
3399 DO ibead = startbead + 1, endbead - 1
3401 startatom, ibead, pos(:, startatom, ibead), energy=energy)
3402 partaction = partaction + energy
3409 DO ibead = startbead + 1, helium%beads
3411 startatom, ibead, pos(:, startatom, ibead), energy=energy)
3412 partaction = partaction + energy
3415 DO ibead = 1, endbead - 1
3417 endatom, ibead, pos(:, endatom, ibead), energy=energy)
3418 partaction = partaction + energy
3422 partaction = partaction*helium%tau
3424 END FUNCTION worm_path_inter_action
3439 REAL(kind=
dp)
FUNCTION worm_path_inter_action_head(pint_env, helium, pos, &
3440 startatom, startbead, xtrapos, worm_atom_idx, worm_bead_idx)
RESULT(partaction)
3444 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
3446 INTEGER,
INTENT(IN) :: startatom, startbead
3447 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xtrapos
3448 INTEGER,
INTENT(IN) :: worm_atom_idx, worm_bead_idx
3451 REAL(kind=
dp) :: energy
3457 IF (startbead < worm_bead_idx)
THEN
3458 DO ibead = startbead + 1, worm_bead_idx - 1
3460 startatom, ibead, pos(:, startatom, ibead), energy=energy)
3461 partaction = partaction + energy
3464 startatom, ibead, xtrapos, energy=energy)
3465 partaction = partaction + 0.5_dp*energy
3467 DO ibead = startbead + 1, helium%beads
3469 startatom, ibead, pos(:, startatom, ibead), energy=energy)
3470 partaction = partaction + energy
3472 DO ibead = 1, worm_bead_idx - 1
3474 worm_atom_idx, ibead, pos(:, worm_atom_idx, ibead), energy=energy)
3475 partaction = partaction + energy
3478 worm_atom_idx, ibead, xtrapos, energy=energy)
3479 partaction = partaction + 0.5_dp*energy
3482 partaction = partaction*helium%tau
3484 END FUNCTION worm_path_inter_action_head
3498 REAL(kind=
dp)
FUNCTION worm_path_inter_action_tail(pint_env, helium, pos, &
3499 endatom, endbead, worm_atom_idx, worm_bead_idx)
RESULT(partaction)
3503 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN), &
3505 INTEGER,
INTENT(IN) :: endatom, endbead, worm_atom_idx, &
3509 REAL(kind=
dp) :: energy
3515 IF (worm_bead_idx < endbead)
THEN
3517 worm_atom_idx, worm_bead_idx, pos(:, worm_atom_idx, worm_bead_idx), energy=energy)
3518 partaction = partaction + 0.5_dp*energy
3519 DO ibead = worm_bead_idx + 1, endbead - 1
3521 endatom, ibead, pos(:, endatom, ibead), energy=energy)
3522 partaction = partaction + energy
3526 worm_atom_idx, worm_bead_idx, pos(:, worm_atom_idx, worm_bead_idx), energy=energy)
3527 partaction = partaction + 0.5_dp*energy
3528 DO ibead = worm_bead_idx + 1, helium%beads
3530 worm_atom_idx, ibead, pos(:, worm_atom_idx, ibead), energy=energy)
3531 partaction = partaction + energy
3533 DO ibead = 1, endbead - 1
3535 endatom, ibead, pos(:, endatom, ibead), energy=energy)
3536 partaction = partaction + energy
3540 partaction = partaction*helium%tau
3542 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
data structure for solvent helium
environment for a path integral run