54#include "../base/base_uses.f90"
60 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
61 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'helium_sampling'
84 INTEGER :: k, num_steps, step, tot_steps
85 LOGICAL :: should_stop
94 IF (
ASSOCIATED(helium_env))
THEN
95 DO k = 1,
SIZE(helium_env)
97 NULLIFY (helium_env(k)%helium%logger)
105 CALL cp_iterate(helium_env(k)%helium%logger%iter_info, &
106 iter_nr=helium_env(k)%helium%first_step)
108 tot_steps = helium_env(k)%helium%first_step
109 num_steps = helium_env(k)%helium%num_steps
112 helium_env(k)%helium%proarea%accu(:) = 0.0_dp
113 helium_env(k)%helium%prarea2%accu(:) = 0.0_dp
114 helium_env(k)%helium%wnmber2%accu(:) = 0.0_dp
115 helium_env(k)%helium%mominer%accu(:) = 0.0_dp
116 IF (helium_env(k)%helium%rho_present)
THEN
117 helium_env(k)%helium%rho_accu(:, :, :, :) = 0.0_dp
119 IF (helium_env(k)%helium%rdf_present)
THEN
120 helium_env(k)%helium%rdf_accu(:, :) = 0.0_dp
126 CALL logger%para_env%bcast(num_steps)
127 CALL logger%para_env%bcast(tot_steps)
129 DO step = 1, num_steps
131 tot_steps = tot_steps + 1
133 IF (
ASSOCIATED(helium_env))
THEN
134 DO k = 1,
SIZE(helium_env)
136 CALL cp_iterate(helium_env(k)%helium%logger%iter_info, &
137 last=(step == helium_env(k)%helium%num_steps), &
140 helium_env(k)%helium%current_step = tot_steps
147 IF (
ASSOCIATED(helium_env))
THEN
148 CALL write_restart(root_section=helium_env(1)%helium%input, helium_env=helium_env)
153 IF (should_stop)
EXIT
158 IF (
ASSOCIATED(helium_env))
THEN
187 CHARACTER(len=default_string_length) :: msg_str
188 INTEGER :: i, irot, iweight, k, nslices, nsteps, &
189 num_env, offset, sel_mp_source
190 REAL(kind=
dp) :: inv_num_env, inv_xn, rnd, rtmp, rweight
191 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: work_2d
195 IF (
SIZE(helium_env) < 1)
THEN
202 DO k = 1,
SIZE(helium_env)
204 IF (helium_env(k)%helium%solute_present)
THEN
205 helium_env(k)%helium%force_avrg(:, :) = 0.0_dp
206 helium_env(k)%helium%current_step = pint_env%iter
210 helium_env(k)%helium%energy_avrg(:) = 0.0_dp
211 helium_env(k)%helium%plength_avrg(:) = 0.0_dp
212 helium_env(k)%helium%num_accepted(:, :) = 0.0_dp
218 SELECT CASE (helium_env(k)%helium%sampling_method)
224 inv_xn = 1.0_dp/real(helium_env(k)%helium%worm_nstat,
dp)
228 DO irot = 1, helium_env(k)%helium%iter_rot
234 rnd = helium_env(k)%helium%rng_stream_uniform%next()
235 nslices = int(rnd*helium_env(k)%helium%beads)
238 CALL helium_try_permutations(helium_env(k)%helium, pint_env)
241 IF (helium_env(k)%helium%solute_present)
THEN
244 helium_env(k)%helium%force_avrg(:, :) = helium_env(k)%helium%force_avrg(:, :) + &
245 helium_env(k)%helium%force_inst(:, :)
250 helium_env(k)%helium%energy_avrg(:) = helium_env(k)%helium%energy_avrg(:) + helium_env(k)%helium%energy_inst(:)
252 helium_env(k)%helium%plength_avrg(:) = helium_env(k)%helium%plength_avrg(:) + helium_env(k)%helium%plength_inst(:)
262 IF ((helium_env(k)%helium%solute_present) .AND. (helium_env(k)%helium%get_helium_forces ==
helium_forces_last))
THEN
264 helium_env(k)%helium%force_avrg(:, :) = helium_env(k)%helium%force_inst(:, :)
270 CALL helium_rotate(helium_env(k)%helium, -helium_env(k)%helium%relrot)
272 inv_xn = 1.0_dp/real(helium_env(k)%helium%iter_rot,
dp)
275 WRITE (msg_str, *) helium_env(k)%helium%sampling_method
276 msg_str =
"Sampling method ("//trim(adjustl(msg_str))//
") not supported."
282 IF ((helium_env(k)%helium%solute_present) .AND. (helium_env(k)%helium%get_helium_forces ==
helium_forces_average))
THEN
283 helium_env(k)%helium%force_avrg(:, :) = helium_env(k)%helium%force_avrg(:, :)*inv_xn
285 helium_env(k)%helium%energy_avrg(:) = helium_env(k)%helium%energy_avrg(:)*inv_xn
286 helium_env(k)%helium%plength_avrg(:) = helium_env(k)%helium%plength_avrg(:)*inv_xn
290 helium_env(k)%helium%prarea2%inst(:) = helium_env(k)%helium%proarea%inst(:)*helium_env(k)%helium%proarea%inst(:)
292 helium_env(k)%helium%wnmber2%inst(:) = helium_env(k)%helium%wnumber%inst(:)*helium_env(k)%helium%wnumber%inst(:)
296 helium_env(k)%helium%proarea%accu(:) = helium_env(k)%helium%proarea%accu(:) + helium_env(k)%helium%proarea%inst(:)
297 helium_env(k)%helium%prarea2%accu(:) = helium_env(k)%helium%prarea2%accu(:) + helium_env(k)%helium%prarea2%inst(:)
298 helium_env(k)%helium%wnmber2%accu(:) = helium_env(k)%helium%wnmber2%accu(:) + helium_env(k)%helium%wnmber2%inst(:)
299 helium_env(k)%helium%mominer%accu(:) = helium_env(k)%helium%mominer%accu(:) + helium_env(k)%helium%mominer%inst(:)
300 IF (helium_env(k)%helium%rho_present)
THEN
302 helium_env(k)%helium%rho_accu(:, :, :, :) = helium_env(k)%helium%rho_accu(:, :, :, :) + &
303 helium_env(k)%helium%rho_inst(:, :, :, :)
305 IF (helium_env(k)%helium%rdf_present)
THEN
308 helium_env(k)%helium%rdf_accu(:, :) = helium_env(k)%helium%rdf_accu(:, :) + helium_env(k)%helium%rdf_inst(:, :)
312 nsteps = helium_env(k)%helium%current_step - helium_env(k)%helium%first_step
313 iweight = helium_env(k)%helium%averages_iweight
314 rweight = real(iweight,
dp)
315 rtmp = 1.0_dp/(real(max(1, nsteps + iweight),
dp))
316 helium_env(k)%helium%proarea%ravr(:) = (helium_env(k)%helium%proarea%accu(:) + &
317 rweight*helium_env(k)%helium%proarea%rstr(:))*rtmp
318 helium_env(k)%helium%prarea2%ravr(:) = (helium_env(k)%helium%prarea2%accu(:) + &
319 rweight*helium_env(k)%helium%prarea2%rstr(:))*rtmp
320 helium_env(k)%helium%wnmber2%ravr(:) = (helium_env(k)%helium%wnmber2%accu(:) + &
321 rweight*helium_env(k)%helium%wnmber2%rstr(:))*rtmp
322 helium_env(k)%helium%mominer%ravr(:) = (helium_env(k)%helium%mominer%accu(:) + &
323 rweight*helium_env(k)%helium%mominer%rstr(:))*rtmp
329 num_env = helium_env(1)%helium%num_env
330 inv_num_env = 1.0_dp/real(num_env,
dp)
333 DO k = 2,
SIZE(helium_env)
334 helium_env(1)%helium%energy_avrg(:) = helium_env(1)%helium%energy_avrg(:) + &
335 helium_env(k)%helium%energy_avrg(:)
337 CALL helium_env(1)%comm%sum(helium_env(1)%helium%energy_avrg(:))
338 helium_env(1)%helium%energy_avrg(:) = helium_env(1)%helium%energy_avrg(:)*inv_num_env
339 DO k = 2,
SIZE(helium_env)
340 helium_env(k)%helium%energy_avrg(:) = helium_env(1)%helium%energy_avrg(:)
344 DO k = 2,
SIZE(helium_env)
345 helium_env(1)%helium%plength_avrg(:) = helium_env(1)%helium%plength_avrg(:) + &
346 helium_env(k)%helium%plength_avrg(:)
348 CALL helium_env(1)%comm%sum(helium_env(1)%helium%plength_avrg(:))
349 helium_env(1)%helium%plength_avrg(:) = helium_env(1)%helium%plength_avrg(:)*inv_num_env
350 DO k = 2,
SIZE(helium_env)
351 helium_env(k)%helium%plength_avrg(:) = helium_env(1)%helium%plength_avrg(:)
355 DO k = 2,
SIZE(helium_env)
356 helium_env(1)%helium%num_accepted(:, :) = helium_env(1)%helium%num_accepted(:, :) + &
357 helium_env(k)%helium%num_accepted(:, :)
359 CALL helium_env(1)%comm%sum(helium_env(1)%helium%num_accepted(:, :))
360 helium_env(1)%helium%num_accepted(:, :) = helium_env(1)%helium%num_accepted(:, :)*inv_num_env
361 DO k = 2,
SIZE(helium_env)
362 helium_env(k)%helium%num_accepted(:, :) = helium_env(1)%helium%num_accepted(:, :)
366 IF (helium_env(1)%helium%solute_present)
THEN
368 DO k = 2,
SIZE(helium_env)
369 helium_env(1)%helium%force_avrg(:, :) = helium_env(1)%helium%force_avrg(:, :) + &
370 helium_env(k)%helium%force_avrg(:, :)
372 CALL helium_env(1)%comm%sum(helium_env(1)%helium%force_avrg(:, :))
373 helium_env(1)%helium%force_avrg(:, :) = helium_env(1)%helium%force_avrg(:, :)*inv_num_env
374 DO k = 2,
SIZE(helium_env)
375 helium_env(k)%helium%force_avrg(:, :) = helium_env(1)%helium%force_avrg(:, :)
378 IF (logger%para_env%is_source())
THEN
379 sel_mp_source = int(helium_env(1)%helium%rng_stream_uniform%next() &
380 *real(helium_env(1)%helium%num_env,
dp))
382 CALL helium_env(1)%comm%bcast(sel_mp_source, logger%para_env%source)
385 DO i = 1, logger%para_env%mepos
386 offset = offset + helium_env(1)%env_all(i)
388 ALLOCATE (work_2d(
SIZE(helium_env(1)%helium%force_avrg, 1), &
389 SIZE(helium_env(1)%helium%force_avrg, 2)))
390 work_2d(:, :) = 0.0_dp
391 IF (sel_mp_source .GE. offset .AND. sel_mp_source .LT. offset +
SIZE(helium_env))
THEN
392 work_2d(:, :) = helium_env(sel_mp_source - offset + 1)%helium%force_avrg(:, :)
394 CALL helium_env(1)%comm%sum(work_2d(:, :))
395 DO k = 1,
SIZE(helium_env)
396 helium_env(k)%helium%force_avrg(:, :) = work_2d(:, :)
402 IF (
SIZE(helium_env) > 0)
THEN
424 CHARACTER(len=*),
PARAMETER :: routinen =
'helium_step'
426 CHARACTER(len=default_string_length) :: msgstr, stmp, time_unit
428 REAL(kind=
dp) :: time_start, time_stop, time_used
429 REAL(kind=
dp),
DIMENSION(:),
POINTER ::
DATA
431 CALL timeset(routinen, handle)
434 IF (
ASSOCIATED(helium_env))
THEN
451 ALLOCATE (
DATA(3*
SIZE(helium_env)))
453 WRITE (stmp, *) helium_env(1)%helium%apref
455 DO k = 1,
SIZE(helium_env)
456 DATA((k - 1)*3 + 1:k*3) = helium_env(k)%helium%proarea%inst(:)
459 "MOTION%PINT%HELIUM%PRINT%PROJECTED_AREA", &
462 (/
"A_x",
"A_y",
"A_z"/), &
463 "prefactor = "//trim(adjustl(stmp))//
" [Angstrom^-2]", &
467 DO k = 1,
SIZE(helium_env)
468 DATA((k - 1)*3 + 1:k*3) = helium_env(k)%helium%prarea2%ravr(:)
471 "MOTION%PINT%HELIUM%PRINT%PROJECTED_AREA_2_AVG", &
474 (/
"<A_x^2>",
"<A_y^2>",
"<A_z^2>"/), &
475 "prefactor = "//trim(adjustl(stmp))//
" [Angstrom^-2]", &
481 DO k = 1,
SIZE(helium_env)
482 DATA((k - 1)*3 + 1:k*3) = helium_env(k)%helium%mominer%inst(:)
485 "MOTION%PINT%HELIUM%PRINT%MOMENT_OF_INERTIA", &
488 (/
"I_x/m",
"I_y/m",
"I_z/m"/), &
489 "prefactor = "//trim(adjustl(stmp))//
" [Angstrom^-2]", &
493 DO k = 1,
SIZE(helium_env)
494 DATA((k - 1)*3 + 1:k*3) = helium_env(k)%helium%mominer%ravr
497 "MOTION%PINT%HELIUM%PRINT%MOMENT_OF_INERTIA_AVG", &
500 (/
"<I_x/m>",
"<I_y/m>",
"<I_z/m>"/), &
501 "prefactor = "//trim(adjustl(stmp))//
" [Angstrom^-2]", &
507 DO k = 1,
SIZE(helium_env)
508 DATA((k - 1)*3 + 1:k*3) = helium_env(k)%helium%wnumber%inst
510 WRITE (stmp, *) helium_env(1)%helium%wpref
512 "MOTION%PINT%HELIUM%PRINT%WINDING_NUMBER", &
515 (/
"W_x",
"W_y",
"W_z"/), &
516 "prefactor = "//trim(adjustl(stmp))//
" [Angstrom^-2]", &
520 DO k = 1,
SIZE(helium_env)
521 DATA((k - 1)*3 + 1:k*3) = helium_env(k)%helium%wnmber2%ravr
524 "MOTION%PINT%HELIUM%PRINT%WINDING_NUMBER_2_AVG", &
527 (/
"<W_x^2>",
"<W_y^2>",
"<W_z^2>"/), &
528 "prefactor = "//trim(adjustl(stmp))//
" [Angstrom^-2]", &
535 time_used = time_stop - time_start
537 IF (time_used .GE. 60.0_dp)
THEN
538 time_used = time_used/60.0_dp
540 IF (time_used .GE. 60.0_dp)
THEN
541 time_used = time_used/60.0_dp
547 WRITE (stmp, *) helium_env(1)%helium%current_step
548 msgstr = trim(adjustl(msgstr))//
" "//trim(adjustl(stmp))//
" of"
550 WRITE (stmp, *) helium_env(1)%helium%last_step
551 msgstr = trim(adjustl(msgstr))//
" "//trim(adjustl(stmp))//
" in"
553 WRITE (stmp,
'(F20.1)') time_used
554 msgstr = trim(adjustl(msgstr))//
" "//trim(adjustl(stmp))
555 msgstr = trim(adjustl(msgstr))//
" "//trim(adjustl(time_unit))//
"."
560 WRITE (stmp, *) helium_env(1)%helium%energy_avrg(
e_id_total)
561 msgstr =
"Total energy = "//trim(adjustl(stmp))
565 CALL timestop(handle)
579 SUBROUTINE helium_try_permutations(helium, pint_env)
583 CHARACTER(len=default_string_length) :: err_str, stmp
584 INTEGER :: cyclen, ni
585 LOGICAL :: accepted, selected
586 REAL(kind=
dp) :: r, rnd, x, y, z
594 helium%work(:, :, :) = helium%pos(:, :, :)
597 DO ni = 1, helium%iter_norot
600 r = 1.0_dp/(1.0_dp + (helium%maxcycle - 1)/helium%m_ratio)
604 SELECT CASE (helium%m_dist_type)
607 x = helium%rng_stream_uniform%next()
611 cyclen = helium%m_value
615 x = helium%rng_stream_uniform%next()
617 cyclen = helium%m_value
620 x = helium%rng_stream_uniform%next()
621 cyclen = int(helium%maxcycle*x) + 1
622 IF (cyclen .NE. helium%m_value)
EXIT
627 x = helium%rng_stream_uniform%next()
629 cyclen = helium%m_value
632 x = helium%rng_stream_uniform%next()
634 cyclen = int(helium%maxcycle*y/sqrt(2.0_dp)) + 1
635 IF (cyclen .NE. helium%m_value)
EXIT
640 x = helium%rng_stream_uniform%next()
642 cyclen = helium%m_value
645 x = helium%rng_stream_uniform%next()
646 y = (3.0_dp*x)**(1.0_dp/3.0_dp)
647 z = 3.0_dp**(1.0_dp/3.0_dp)
648 cyclen = int(helium%maxcycle*y/z) + 1
649 IF (cyclen .NE. helium%m_value)
EXIT
654 x = helium%rng_stream_uniform%next()
656 cyclen = helium%m_value
660 x = helium%rng_stream_uniform%next()
661 IF (x .GE. 0.01_dp)
EXIT
664 y = log(x)/z + 1.0_dp;
665 cyclen = int(helium%maxcycle*y) + 1
666 IF (cyclen .NE. helium%m_value)
EXIT
671 x = helium%rng_stream_uniform%next()
676 x = helium%rng_stream_gaussian%next()
677 cyclen = int(x*0.75_dp + helium%m_value - 0.5_dp) + 1
678 IF (cyclen .NE. 1)
EXIT
683 WRITE (stmp, *) helium%m_dist_type
684 err_str =
"M distribution type unknown ("//trim(adjustl(stmp))//
")"
690 IF (cyclen < 1) cyclen = 1
691 IF (cyclen > helium%maxcycle) cyclen = helium%maxcycle
692 helium%num_accepted(1, cyclen) = helium%num_accepted(1, cyclen) + 1
695 IF (cyclen == 1)
THEN
696 rnd = helium%rng_stream_uniform%next()
697 helium%ptable(1) = 1 + int(rnd*helium%atoms)
698 helium%ptable(2) = -1
699 helium%pweight = 0.0_dp
702 selected = helium_select_permutation(helium, cyclen)
707 accepted = helium_slice_metro_cyclic(helium, pint_env, cyclen)
720 IF (helium%solute_present)
THEN
723 IF (helium%periodic)
THEN
735 END SUBROUTINE helium_try_permutations
745 FUNCTION helium_slice_metro_cyclic(helium, pint_env, cyclen)
RESULT(res)
748 INTEGER,
INTENT(IN) :: cyclen
751 CHARACTER(len=default_string_length) :: err_str, stmp
752 INTEGER :: c, ia, ib, ic, ifix, j, k, l, level, &
754 INTEGER,
DIMENSION(:),
POINTER :: p, perm
755 LOGICAL :: nperiodic, should_reject
756 REAL(kind=
dp) :: cell_size, ds, dtk, e1, e2, pds, &
757 prev_ds, r, rtmp, rtmpo, sigma, x
758 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work3
759 REAL(kind=
dp),
DIMENSION(3) :: bis, biso, new_com, rm1, rm2, tmp1, tmp2
760 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: pos, work
771 prev_ds = helium%pweight
773 helium%num_accepted(2, cyclen) = helium%num_accepted(2, cyclen) + 1
778 IF (helium%bisection == 0)
RETURN
789 perm => helium%permutation
791 cell_size = (0.5_dp*helium%cell_size)**2
792 nperiodic = .NOT. helium%periodic
795 ifix = helium%beads - helium%bisection + 1
801 err_str =
"ifix<1 test failed (ifix="//trim(adjustl(stmp))//
")"
813 IF (j /= helium%bisection)
THEN
814 WRITE (stmp, *) helium%bisection
815 err_str =
"helium%bisection not a power of 2 (helium%bisection="//trim(adjustl(stmp))//
")"
819 IF (helium%bisection < 2)
THEN
820 WRITE (stmp, *) helium%bisection
821 err_str =
"helium%bisection less than 2 (helium%bisection="//trim(adjustl(stmp))//
")"
825 stride = helium%bisection
827 IF (stride <= 2)
EXIT
830 sigma = sqrt(0.5_dp*helium%hb2m*(stride/2)*helium%tau)
836 IF (j > helium%beads - stride/2)
EXIT
842 tmp1(:) = bis(:) - pos(:, p(k), j)
844 tmp1(:) = tmp1(:)/sigma
845 dtk = dtk - 0.5_dp*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
851 x = helium%rng_stream_gaussian%next(variance=1.0_dp)
853 tmp1(c) = tmp1(c) + x
858 work(:, p(k), j) = tmp1(:)
859 tmp2(:) = tmp2(:)/sigma
860 dtk = dtk + 0.5_dp*(tmp2(1)*tmp2(1) + tmp2(2)*tmp2(2) + tmp2(3)*tmp2(3))
865 j = helium%beads - stride/2 + 1
869 tmp1(:) = bis(:) - pos(:, p(k), j)
871 tmp1(:) = tmp1(:)/sigma
872 dtk = dtk - 0.5_dp*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
875 CALL helium_boxmean_3d(helium, work(:, p(k), pk1), work(:, perm(p(1 + mod(k, cyclen))), 1), tmp1)
877 x = helium%rng_stream_gaussian%next(variance=1.0_dp)
879 tmp1(c) = tmp1(c) + x
884 work(:, p(k), j) = tmp1(:)
885 tmp2(:) = tmp2(:)/sigma
886 dtk = dtk + 0.5_dp*(tmp2(1)*tmp2(1) + tmp2(2)*tmp2(2) + tmp2(3)*tmp2(3))
890 x = 1.0_dp/(helium%tau*helium%hb2m*stride)
893 IF (j > helium%beads - stride/2)
EXIT
896 tmp1(:) = pos(:, p(k), j) - pos(:, p(k), pk1)
898 ds = ds + x*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
899 tmp1(:) = work(:, p(k), j) - work(:, p(k), pk1)
901 ds = ds - x*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
903 IF (helium%solute_present)
THEN
906 ds = ds + (stride/2)*(e1 - e2)*helium%tau
908 DO l = 1, helium%atoms
910 tmp1(:) = pos(:, p(k), pk1) - pos(:, l, pk1)
912 r = tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3)
913 IF ((r < cell_size) .OR. nperiodic)
THEN
917 tmp1(:) = work(:, p(k), pk1) - work(:, l, pk1)
919 r = tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3)
920 IF ((r < cell_size) .OR. nperiodic)
THEN
929 tmp1(:) = pos(:, p(k), pk1) - pos(:, p(l), pk1)
931 r = tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3)
932 IF ((r < cell_size) .OR. nperiodic)
THEN
936 tmp1(:) = work(:, p(k), pk1) - work(:, p(l), pk1)
938 r = tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3)
939 IF ((r < cell_size) .OR. nperiodic)
THEN
949 pk1 = helium%beads - stride/2 + 1
951 tmp1(:) = pos(:, p(k), pk1) - pos(:, perm(p(k)), 1)
953 ds = ds + x*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
954 tmp1(:) = work(:, p(k), pk1) - work(:, perm(p(1 + mod(k, cyclen))), 1)
956 ds = ds - x*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
959 rtmp = helium%rng_stream_uniform%next()
961 IF (dtk + ds - pds < 0.0_dp)
THEN
962 IF (exp(dtk + ds - pds) < rtmp)
THEN
963 DO c = ifix, helium%beads
965 work(:, p(k), c) = pos(:, p(k), c)
972 helium%num_accepted(level + 2, cyclen) = helium%num_accepted(level + 2, cyclen) + 1
980 sigma = sqrt(0.5_dp*helium%hb2m*helium%tau)
983 DO j = ifix + 1, helium%beads - 1, 2
989 tmp1(:) = bis(:) - pos(:, p(k), j)
991 tmp1(:) = tmp1(:)/sigma
992 dtk = dtk - 0.5_dp*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
998 x = helium%rng_stream_gaussian%next(variance=1.0_dp)
1000 tmp1(c) = tmp1(c) + x
1005 work(:, p(k), j) = tmp1(:)
1006 tmp2(:) = tmp2(:)/sigma
1007 dtk = dtk + 0.5_dp*(tmp2(1)*tmp2(1) + tmp2(2)*tmp2(2) + tmp2(3)*tmp2(3))
1014 tmp1(:) = bis(:) - pos(:, p(k), j)
1016 tmp1(:) = tmp1(:)/sigma
1017 dtk = dtk - 0.5_dp*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
1020 CALL helium_boxmean_3d(helium, work(:, p(k), pk1), work(:, perm(p(1 + mod(k, cyclen))), 1), tmp1)
1022 x = helium%rng_stream_gaussian%next(variance=1.0_dp)
1024 tmp1(c) = tmp1(c) + x
1029 work(:, p(k), j) = tmp1(:)
1031 dtk = dtk + 0.5_dp*(tmp2(1)*tmp2(1) + tmp2(2)*tmp2(2) + tmp2(3)*tmp2(3))
1037 IF (helium%solute_present)
THEN
1038 DO j = ifix, helium%beads
1042 ds = ds + (e1 - e2)*helium%tau
1046 ALLOCATE (work3(
SIZE(helium%uoffdiag, 1) + 1))
1047 x = 1.0_dp/(helium%tau*helium%hb2m*stride)
1048 DO j = ifix, helium%beads - 1
1051 tmp1(:) = pos(:, p(k), j) - pos(:, p(k), pk1)
1053 ds = ds + x*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
1054 tmp1(:) = work(:, p(k), j) - work(:, p(k), pk1)
1056 ds = ds - x*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
1057 DO l = 1, helium%atoms
1059 rm1(:) = pos(:, p(k), j) - pos(:, l, j)
1060 rm2(:) = pos(:, p(k), pk1) - pos(:, l, pk1)
1062 rm1(:) = work(:, p(k), j) - work(:, l, j)
1063 rm2(:) = work(:, p(k), pk1) - work(:, l, pk1)
1068 IF (k < cyclen)
THEN
1069 DO l = k + 1, cyclen
1070 rm1(:) = pos(:, p(k), j) - pos(:, p(l), j)
1071 rm2(:) = pos(:, p(k), pk1) - pos(:, p(l), pk1)
1073 rm1(:) = work(:, p(k), j) - work(:, p(l), j)
1074 rm2(:) = work(:, p(k), pk1) - work(:, p(l), pk1)
1083 tmp1(:) = pos(:, p(k), j) - pos(:, perm(p(k)), 1)
1085 ds = ds + x*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
1086 tmp1(:) = work(:, p(k), j) - work(:, perm(p(1 + mod(k, cyclen))), 1)
1088 ds = ds - x*(tmp1(1)*tmp1(1) + tmp1(2)*tmp1(2) + tmp1(3)*tmp1(3))
1089 DO l = 1, helium%atoms
1091 rm1(:) = pos(:, p(k), j) - pos(:, l, j)
1092 rm2(:) = pos(:, perm(p(k)), 1) - pos(:, perm(l), 1)
1097 IF (k < cyclen)
THEN
1098 DO l = k + 1, cyclen
1099 rm1(:) = pos(:, p(k), j) - pos(:, p(l), j)
1100 rm2(:) = pos(:, perm(p(k)), pk1) - pos(:, perm(p(l)), pk1)
1105 IF (cyclen > 1)
THEN
1108 DO k = 1, cyclen - 1
1109 perm(p(k)) = perm(p(k + 1))
1114 DO l = 1, helium%atoms
1116 rm1(:) = work(:, p(k), j) - work(:, l, j)
1117 rm2(:) = work(:, perm(p(k)), 1) - work(:, perm(l), 1)
1122 IF (k < cyclen)
THEN
1123 DO l = k + 1, cyclen
1124 rm1(:) = work(:, p(k), j) - work(:, p(l), j)
1125 rm2(:) = work(:, perm(p(k)), 1) - work(:, perm(p(l)), 1)
1132 rtmp = helium%rng_stream_uniform%next()
1134 IF (dtk + ds - pds < 0.0_dp)
THEN
1135 IF (exp(dtk + ds - pds) < rtmp)
THEN
1136 DO c = ifix, helium%beads
1138 work(:, p(k), c) = pos(:, p(k), c)
1141 IF (cyclen > 1)
THEN
1143 DO k = cyclen - 1, 1, -1
1144 perm(p(k + 1)) = perm(p(k))
1156 IF (.NOT. helium%periodic)
THEN
1157 IF (helium%solute_present)
THEN
1158 new_com(:) = helium%center(:)
1161 DO k = 1, helium%atoms
1162 DO l = 1, helium%beads
1163 new_com(:) = new_com(:) + helium%work(:, k, l)
1166 new_com(:) = new_com(:)/helium%atoms/helium%beads
1169 should_reject = .false.
1170 outer:
DO ia = 1, helium%atoms
1172 DO ib = 1, helium%beads
1174 bis(ic) = bis(ic) + work(ic, ia, ib) - new_com(ic)
1177 bis(:) = bis(:)/helium%beads
1178 rtmp = dot_product(bis, bis)
1179 IF (rtmp .GE. helium%droplet_radius**2)
THEN
1181 DO ib = 1, helium%beads
1183 biso(ic) = biso(ic) + pos(ic, ia, ib) - helium%center(ic)
1186 biso(:) = biso(:)/helium%beads
1187 rtmpo = dot_product(biso, biso)
1189 IF (rtmpo < rtmp)
THEN
1191 should_reject = .true.
1196 IF (should_reject)
THEN
1198 DO c = ifix, helium%beads
1200 work(:, p(k), c) = pos(:, p(k), c)
1203 IF (cyclen > 1)
THEN
1205 DO k = cyclen - 1, 1, -1
1206 perm(p(k + 1)) = perm(p(k))
1216 DO c = ifix, helium%beads
1218 pos(:, p(k), c) = work(:, p(k), c)
1222 helium%iperm(perm(p(k))) = p(k)
1224 helium%num_accepted(level + 2, cyclen) = helium%num_accepted(level + 2, cyclen) + 1
1228 END FUNCTION helium_slice_metro_cyclic
1237 FUNCTION helium_select_permutation(helium, len)
RESULT(res)
1239 INTEGER,
INTENT(IN) :: len
1242 INTEGER :: i, j, k, n
1243 INTEGER,
DIMENSION(:),
POINTER :: iperm, p, perm
1244 INTEGER,
DIMENSION(:, :),
POINTER :: nmatrix
1245 REAL(kind=
dp) :: rnd, s1, s2, t
1246 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: ipmatrix, pmatrix, tmatrix
1252 tmatrix => helium%tmatrix
1253 pmatrix => helium%pmatrix
1254 ipmatrix => helium%ipmatrix
1255 perm => helium%permutation
1256 iperm => helium%iperm
1258 nmatrix => helium%nmatrix
1261 rnd = helium%rng_stream_uniform%next()
1262 p(1) = int(n*rnd) + 1
1264 t = helium%rng_stream_uniform%next()
1269 IF (tmatrix(p(k), i) > t)
THEN
1270 i = nmatrix(p(k), 2*i - 1)
1272 i = nmatrix(p(k), 2*i)
1281 IF (p(j) == p(k + 1))
RETURN
1285 s1 = s1 + ipmatrix(p(k), i)
1286 s2 = s2 + ipmatrix(p(k), perm(p(k)))
1289 s1 = s1 + ipmatrix(p(len), perm(p(1)))
1290 s2 = s2 + ipmatrix(p(len), perm(p(len)))
1292 rnd = helium%rng_stream_uniform%next()
1298 s1 = pmatrix(p(len), perm(p(1))) - pmatrix(p(len), perm(p(len)))
1300 s1 = s1 + pmatrix(p(k), perm(p(k + 1))) - pmatrix(p(k), perm(p(k)))
1305 END FUNCTION helium_select_permutation
Routines to handle the external control of CP2K.
subroutine, public external_control(should_stop, flag, globenv, target_time, start_time, force_check)
External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype command is sent the progr...
various routines to log and control the output. The idea is that decisions about where to log should ...
subroutine, public cp_rm_default_logger()
the cousin of cp_add_default_logger, decrements the stack, so that the default logger is what it has ...
subroutine, public cp_logger_release(logger)
releases this logger
subroutine, public cp_logger_create(logger, para_env, print_level, default_global_unit_nr, default_local_unit_nr, global_filename, local_filename, close_global_unit_on_dealloc, iter_info, close_local_unit_on_dealloc, suffix, template_logger)
initializes a logger
subroutine, public cp_add_default_logger(logger)
adds a default logger. MUST be called before logging occours
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
subroutine, public cp_iterate(iteration_info, last, iter_nr, increment, iter_nr_out)
adds one to the actual iteration
subroutine, public cp_rm_iter_level(iteration_info, level_name, n_rlevel_att)
Removes an iteration level.
subroutine, public cp_add_iter_level(iteration_info, level_name, n_rlevel_new)
Adds an iteration level.
Define type storing the global information of a run. Keep the amount of stored data small....
Independent helium subroutines shared with other modules.
real(kind=dp) function, dimension(3), public helium_total_moment_of_inertia(helium)
Return total moment of inertia divided by m_He.
pure real(kind=dp) function, dimension(3), public helium_com(helium)
Calculate center of mass.
pure subroutine, public helium_rotate(helium, nslices)
Rotate helium particles in imaginary time by nslices.
subroutine, public helium_pbc(helium, r, enforce)
General PBC routine for helium.
subroutine, public helium_boxmean_3d(helium, a, b, c)
Calculate the point equidistant from two other points a and b within the helium box - 3D version.
subroutine, public helium_calc_rho(helium)
Calculate helium density distribution functions and store them in heliumrho_inst.
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.
subroutine, public helium_update_transition_matrix(helium)
...
subroutine, public helium_calc_rdf(helium)
Calculate helium radial distribution functions wrt positions given by <centers> using the atomic weig...
real(kind=dp) function, dimension(3), public helium_total_projected_area(helium)
Return total projected area.
real(kind=dp) function, public helium_spline(spl, xx)
...
real(kind=dp) function, dimension(3), public helium_total_winding_number(helium)
Return total winding number.
pure subroutine, public helium_set_rdf_coord_system(helium, pint_env)
Set coordinate system for RDF 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_print_action(pint_env, helium_env)
Print helium action file to HELIUMPRINTACTION.
subroutine, public helium_print_rdf(helium_env)
Print radial distribution functions according to HELIUMPRINTRDF.
subroutine, public helium_print_force(helium_env)
Print helium force according to HELIUMPRINTFORCE.
subroutine, public helium_print_accepts(helium_env)
Print acceptance counts according to HELIUMPRINTACCEPTS.
subroutine, public helium_print_energy(helium_env)
Print energies according to HELIUMPRINTENERGY.
subroutine, public helium_print_vector(helium_env, pkey, data, uconv, col_label, cmmnt, fname, fpos, avg)
Print a 3D real vector according to printkey <pkey>
subroutine, public helium_print_perm(helium_env)
Print permutation state according to HELIUMPRINTPERM.
subroutine, public helium_print_rho(helium_env)
Print densities according to HELIUMPRINTRHO.
subroutine, public helium_print_plength(helium_env)
Print permutation length according to HELIUMPRINTPLENGTH.
subroutine, public helium_write_line(line)
Writes out a line of text to the default output unit.
subroutine, public helium_print_coordinates(helium_env)
Print coordinates according to HELIUMPRINTCOORDINATES.
Methods for sampling helium variables.
subroutine, public helium_step(helium_env, pint_env)
Perform MC step for helium.
subroutine, public helium_do_run(helium_env, globenv)
Performs MC simulation for helium (only)
subroutine, public helium_sample(helium_env, pint_env)
Sample the helium phase space.
Data types representing superfluid helium.
integer, parameter, public e_id_total
Energy contributions - symbolic names for indexing energy arrays.
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
Machine interface based on Fortran 2003 and POSIX.
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition of physical constants:
real(kind=dp), parameter, public angstrom
Public path integral routines that can be called from other modules.
pure real(kind=dp) function, dimension(3), public pint_com_pos(pint_env)
Return the center of mass of the PI system.
routines for handling splines_types
type of a logger, at the moment it contains just a print level starting at which level it should be l...
contains the initially parsed file and the initial parallel environment
data structure for array of solvent helium environments
data structure for solvent helium
environment for a path integral run
Data-structure that holds all needed information about a specific spline interpolation.