39 helium_solvent_p_type,&
54 #include "../base/base_uses.f90"
60 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
61 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'helium_sampling'
81 TYPE(helium_solvent_p_type),
DIMENSION(:),
POINTER :: helium_env
82 TYPE(global_environment_type),
POINTER :: globenv
84 INTEGER :: k, num_steps, step, tot_steps
85 LOGICAL :: should_stop
86 TYPE(cp_logger_type),
POINTER :: logger
87 TYPE(pint_env_type) :: pint_env
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
184 TYPE(helium_solvent_p_type),
DIMENSION(:),
POINTER :: helium_env
185 TYPE(pint_env_type),
INTENT(IN) :: pint_env
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
192 TYPE(cp_logger_type),
POINTER :: logger
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
421 TYPE(helium_solvent_p_type),
DIMENSION(:),
POINTER :: helium_env
422 TYPE(pint_env_type),
INTENT(IN) :: pint_env
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)
580 TYPE(helium_solvent_type),
POINTER :: helium
581 TYPE(pint_env_type),
INTENT(IN) :: 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)
746 TYPE(helium_solvent_type),
POINTER :: helium
747 TYPE(pint_env_type),
INTENT(IN) :: pint_env
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
761 TYPE(spline_data_type),
POINTER :: u0
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)
1238 TYPE(helium_solvent_type),
POINTER :: helium
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_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_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_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