44 integer,
parameter ::
ntab = 32
45 integer(int64),
dimension(ntab),
save ::
iv = 0
46 integer(int64),
save ::
iy = 0
75 character(len=30) :: c_seed
78 open (access=
'stream', action=
'read', file=
'/dev/urandom', &
79 form=
'unformatted', iostat=rc, newunit=fu)
81 if (rc == 0)
read (fu)
seed
86 write(c_seed,
"(I30)")
seed
88 c_seed = adjustl(c_seed)
89 c_seed = c_seed(7:l_seed)
122 integer(int64),
intent(inout) :: dseed
123 real(real64),
intent(out) :: sample
126 integer(int64),
parameter :: ia = 16807, im = 2147483647, iq = 127773
127 integer(int64),
parameter :: ir = 2836, &
128 ndiv = 1 + floor((real(im, kind=real64)-1.0)/
ntab)
129 real(real64),
parameter :: am = 1.0/real(im, kind=real64), eps = 1.2e-7, &
133 integer(int64) :: j, k
136 if (dseed<=0 .or.
iy==0)
then
138 dseed = max(-dseed,1)
141 k = floor(real(dseed, kind=real64)/real(iq, kind=real64))
142 dseed = ia * (dseed-k*iq) - ir * k
143 if (dseed < 0) dseed = dseed + im
144 if (j <=
ntab)
iv(j) = dseed
150 k = floor(real(dseed, kind=real64)/real(iq, kind=real64))
151 dseed = ia * (dseed-k*iq) - ir * k
152 if (dseed < 0) dseed = dseed + im
153 j = 1_int64 +
iy / ndiv
156 sample = min(am*
iy, rnmx)
182 function linspace(start, end, num)
result(ls_array)
186 real(real64),
intent(in) :: start, end, num
188 real(real64),
dimension(:),
allocatable :: ls_array
197 if (inum .eq. 1)
then
198 allocate(ls_array(inum))
203 allocate(ls_array(inum))
205 step = (
end - start) / real(inum-1, kind=real64)
208 ls_array(i) = start + (i-1)*step
232 integer,
intent(in) :: dim
233 real(real64),
intent(out),
dimension(:) :: x
235 real(real64) :: u_1, u_2
250 x(i) = sqrt(-2*log(u_1))*cos(2*pi*u_2)
289 subroutine vqmc_qho(sigma, N, burn, thin, alpha_const, X_burnt, &
290 accept_rate, energy_chain, energy_mean, energy_variance, x_start)
294 real(real64),
intent(in) :: sigma, alpha_const
295 integer,
intent(in) :: N, burn, thin
296 real(real64),
optional :: x_start
298 real(real64),
intent(out) :: accept_rate, energy_mean, energy_variance
299 real(real64),
intent(out),
dimension(:),
allocatable :: X_burnt, energy_chain
301 real(real64) :: log_prob_n
302 real(real64) :: a_prob_trans
303 real(real64) :: unif_num
304 real(real64),
dimension(1) :: start
305 real(real64),
dimension(1) :: X_n
306 real(real64),
dimension(1) :: sample_normal
307 real(real64),
dimension(:),
allocatable :: X
308 integer :: thin_counter
309 integer :: reset_counter
314 character(len=1) :: acceptance
317 re_size = (n - burn) / thin
319 allocate(x(1: n+1)); x(:) = 0.0_real64
320 allocate(x_burnt(1: re_size)); x_burnt(:) = 0.0_real64
321 allocate(energy_chain(1: re_size)); energy_chain(:) = 0.0_real64
324 if (
present(x_start))
then
328 write(logid,
"('Starting from provided Markov chain position', F12.8)") x(1)
333 do while(norm2(sample_normal) >= qho%rcut)
336 start = sample_normal
339 write(logid,
"('Generated random Markov chain start position', F12.8)") x(1)
352 write(logid,
"('Markov chain for alpha = ', F7.4)") alpha_const
353 write(logid,
"('Sample Position Local Energy Accepted?')")
354 write(logid,
"(I8, ' ', F12.8, ' ', F12.6)") 1, x(1), energy_chain(1)
359 energy_chain(1) = qho_energy(alpha_const, x(1))
364 thin_counter = 1 + thin_counter
367 x_n = x(i-1) + sigma * sample_normal
370 log_prob_n = log(qho_prob(alpha_const, x(i-1), x_n(1)))
373 a_prob_trans = min(1.0_real64, exp(log_prob_n))
376 call ran1(unif_num, seed)
379 if (a_prob_trans >= unif_num)
then
384 if (thin_counter == thin)
then
386 reset_counter = 1 + reset_counter
388 i_bt = i - burn - (reset_counter * (thin - 1))
390 x_burnt(i_bt) = x_n(1)
392 energy_chain(i_bt) = qho_energy(alpha_const, x_n(1))
401 if (mod(i_bt, re_size/
logfrac) .le. 1e-6_real64)
then
402 write(logid,
"(I8, ' ', F12.8, ' ', F12.6, ' ', A1)") &
403 (i_bt), x_burnt(i_bt), energy_chain(i_bt), acceptance
412 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
414 reset_counter = 1 + reset_counter
416 i_bt = i - burn - (reset_counter * (thin - 1))
418 x_burnt(i_bt) = x(i-1)
420 energy_chain(i_bt) = qho_energy(alpha_const, x(i-1))
427 if (mod(i_bt, re_size/
logfrac) .le. 1e-6_real64)
then
428 write(logid,
"(I8, ' ', F12.8, ' ', F12.6, ' ', A1)") &
429 (i_bt), x_burnt(i_bt), energy_chain(i_bt), acceptance
438 else if (burn >= 2)
then
442 x_n = x(i-1) + sigma * sample_normal
444 log_prob_n = log(qho_prob(alpha_const, x(i-1), x_n(1)))
446 a_prob_trans = min(1.0_real64, exp(log_prob_n))
448 call ran1(unif_num, seed)
451 if (a_prob_trans >= unif_num)
then
465 thin_counter = 1 + thin_counter
468 x_n = x(i-1) + sigma * sample_normal
471 log_prob_n = log(qho_prob(alpha_const, x(i-1), x_n(1)))
474 a_prob_trans = min(1.0_real64, exp(log_prob_n))
477 call ran1(unif_num, seed)
480 if (a_prob_trans >= unif_num)
then
485 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
487 reset_counter = 1 + reset_counter
489 i_bt = i - burn - (reset_counter * (thin - 1))
491 x_burnt(i_bt) = x_n(1)
493 energy_chain(i_bt) = qho_energy(alpha_const, x_n(1))
502 if (mod(i_bt, re_size/
logfrac) .le. 1e-6_real64)
then
503 write(logid,
"(I8, ' ', F12.8, ' ', F12.6, ' ', A1)") &
504 (i_bt), x_burnt(i_bt), energy_chain(i_bt), acceptance
515 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
517 reset_counter = 1 + reset_counter
519 i_bt = i - burn - (reset_counter * (thin - 1))
521 x_burnt(i_bt) = x(i-1)
523 energy_chain(i_bt) = qho_energy(alpha_const, x(i-1))
530 if (mod(i_bt, re_size/
logfrac) .le. 1e-6_real64)
then
531 write(logid,
"(I8, ' ', F12.8, ' ', F12.6, ' ', A1)") &
532 (i_bt), x_burnt(i_bt), energy_chain(i_bt), acceptance
542 accept_rate = (real(accept, kind=real64) / real(re_size, kind=real64))
545 energy_mean = sum(energy_chain) / real(re_size, kind=real64)
546 energy_variance = 0.0_real64
548 energy_variance = energy_variance + ((1.0_real64 / real(re_size - 1, kind=real64)) * &
549 (energy_chain(i) - energy_mean) * (energy_chain(i) - energy_mean))
551 energy_variance = (1.0_real64 / real(re_size, kind=real64)) * energy_variance
554 write(logid,
"('Local energy = ', F12.8)") energy_mean
555 write(logid,
"('Variance = ', F12.8)") energy_variance
556 write(logid,
"('Acceptance rate = ', F12.8)") accept_rate
579 subroutine grid_qho(alpha_array, energies, acc_rates, variances)
583 real(real64),
dimension(:),
intent(in) :: alpha_array
584 real(real64),
dimension(:),
intent(inout) :: energies
585 real(real64),
dimension(:),
intent(inout) :: acc_rates
586 real(real64),
dimension(:),
intent(inout) :: variances
588 real(real64),
dimension(:),
allocatable :: energy_chain, trimmed_energy_chain
589 real(real64),
dimension(:),
allocatable :: pos_chain, trimmed_pos_chain
590 real(real64) :: accept_rate
591 real(real64) :: energy_mean
592 real(real64) :: energy_variance
594 character(len=3) :: str_i
595 character(len=40) :: chainfile
598 real(real64) :: my_ensum
602 write(*,
"('-------------- Begin VQMC Runs --------------')")
603 write(*,
"('Alpha Energy Acceptance Rate')")
605 write(logid,
"('-------------- Begin VQMC Runs --------------')")
606 if (.not. run_equil)
then
608 write(logid,
"('Logging the chains from Rank 0.')")
615 do i = alpha_start,
size(alpha_array)
618 call vqmc_qho(qho%sigma, my_steps+qho%burn_step, qho%burn_step, qho%thin_step, &
619 alpha_array(i), pos_chain, accept_rate, energy_chain, energy_mean, &
630 my_ensum = sum(energy_chain)
631 call mpi_reduce(my_ensum,energies(i),1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
634 call mpi_reduce(accept_rate,acc_rates(i),1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
637 call mpi_reduce(energy_variance,variances(i),1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
646 energies(i) = energies(i) * per_step
647 acc_rates(i) = acc_rates(i) * per_proc
648 variances(i) = variances(i) * per_proc
649 write(*,
"(F7.4, ' ', F12.8, ' ', F12.8)") alpha_array(i), &
650 energies(i), acc_rates(i)
653 if (write_chains)
then
656 write(str_i,
"(I3)") i
657 write(chainfile,
"(3A)")
'./chains_out/alpha_', trim(adjustl(str_i)),
'.nc'
660 if (
size(energy_chain) < max_chain_len)
then
661 write(*,
"(2A)")
'Writing Markov chain to from rank 0 to', chainfile
662 call write_qho_equilibration(pos_chain, energy_chain, chainfile, ierr, &
663 qho, accept_rate, alpha_array(i))
667 allocate(trimmed_pos_chain(max_chain_len))
668 allocate(trimmed_energy_chain(max_chain_len))
670 trimmed_pos_chain(:) = pos_chain(1:max_chain_len)
671 trimmed_energy_chain(:) = energy_chain(1:max_chain_len)
673 write(*,
"(2A)")
'Writing trimmed Markov chain to from rank 0 to', chainfile
674 call write_qho_equilibration(trimmed_pos_chain, trimmed_energy_chain, chainfile, ierr, &
675 qho, accept_rate, alpha_array(i))
677 deallocate(trimmed_pos_chain)
678 deallocate(trimmed_energy_chain)
683 if (write_restart)
then
684 if (mod(i,restart_num)==0)
then
686 call write_res_nml(i+1)
688 call write_qho_main(alpha_array, energies, variances, resfile_etot, ierr, qho, acc_rates)
698 write(*,
"('-------------- End VQMC Runs --------------')")
700 write(logid,
"('-------------- End VQMC Runs --------------')")
701 write(logid,
"('Results:')")
702 write(logid,
"('alpha Energy')")
703 do i = 1,
size(alpha_array)
704 write(logid,
"(F12.8, ' ', F12.8)") alpha_array(i), energies(i)
707 write(logid,
"('Min Energy = ', F12.8, ' at c = ', F12.8)") &
708 minval(energies), alpha_array(minloc(energies, 1))
713 write(*, *)
'Calculations finished, writing results to NetCDF output file ', &
716 write(logid, *)
'Calculations finished, writing results to NetCDF &
717 &output file ', outfile
719 call write_qho_main(alpha_array, energies, variances, outfile, ierr, qho, acc_rates)
746 real(real64),
dimension(:),
intent(in) :: alpha_array
748 real(real64),
dimension(:),
allocatable :: energy_chain
749 real(real64),
dimension(:),
allocatable :: pos_chain
750 real(real64) :: energy
751 real(real64) :: accept_rate
752 real(real64) :: variance
754 character(len=3) :: str_i
755 character(len=40) :: equilfile
758 write(*,
"('-------------- Begin VQMC Runs --------------')")
759 write(*,
"('Alpha Energy Acceptance Rate')")
761 write(logid,
"('-------------- Begin VQMC Runs --------------')")
765 do i = alpha_start,
size(alpha_array)
768 call vqmc_qho(qho%sigma,qho%steps, qho%burn_step, qho%thin_step, &
769 alpha_array(i), pos_chain, accept_rate, energy_chain, energy, &
773 write(*,
"(F7.4, ' ', F12.8, ' ', F12.8)") alpha_array(i), &
777 write(logid,
"('Results:')")
778 write(logid,
"('alpha = ', F12.8, ', Energy = ', F12.8)") alpha_array(i), energy
783 write(str_i,
"(I3)") i
784 write(equilfile,
"(3A)")
'./equil_out/alpha_', trim(adjustl(str_i)),
'.nc'
785 write(*, *)
'Writing equilibration outfile to ', equilfile
786 call write_qho_equilibration(pos_chain, energy_chain, equilfile, ierr, qho, &
787 accept_rate, alpha_array(i))
790 if (write_restart)
then
791 if (mod(i,restart_num)==0)
then
793 call write_res_nml(i+1)
801 write(*,
"('-------------- End VQMC Runs --------------')")
803 write(logid,
"('-------------- End VQMC Runs --------------')")
858 X_burnt, accept_rate, energy_chain, energy_mean, energy_variance, &
859 DphiDc_chain, x_start)
863 real(real64),
intent(in),
dimension(3) :: R_a, R_b
864 real(real64),
intent(in) :: sigma
865 real(real64),
intent(in) :: c_const
866 real(real64),
dimension(3),
optional :: x_start
867 integer,
intent(in) :: N, burn, thin
870 real(real64),
intent(out) :: accept_rate, energy_mean, energy_variance
871 real(real64),
intent(out),
dimension(:, :),
allocatable :: X_burnt
872 real(real64),
intent(out),
dimension(:),
allocatable :: energy_chain
873 real(real64),
intent(out),
dimension(:),
allocatable :: DphiDc_chain
875 real(real64) :: E_loc
876 real(real64) :: DphiDc
877 real(real64) :: log_prob_n
878 real(real64) :: a_prob_trans
879 real(real64) :: unif_num
880 real(real64),
dimension(3) :: start
881 real(real64),
dimension(:, :),
allocatable :: X
882 real(real64),
dimension(3) :: X_n
883 real(real64),
dimension(3) :: sample_normal
885 integer :: thin_counter
886 integer :: reset_counter
890 character(len=1) :: acceptance
893 write(logid,
"('Markov chain for c = ', F7.4)") c_const
894 if (.not. run_equil)
write(logid,
"('Logging the chain from Rank 0.')")
898 re_size = (n - burn) / thin
900 allocate(x(3, 1:n+1)); x(:, :) = 0.0_real64
901 allocate(x_burnt(3, 1:re_size)); x_burnt(:, :) = 0.0_real64
902 allocate(energy_chain(1:re_size)); energy_chain(:) = 0.0_real64
903 allocate(dphidc_chain(1:re_size)); dphidc_chain(:) = 0.0_real64
906 if (
present(x_start))
then
910 write(logid,
"('Starting from provided Markov chain position:')")
911 write(logid,
"(' x = ', F12.8, ' y = ', F12.8, ' z = ', F12.8)") &
912 x(1, 1), x(2, 1), x(3, 1)
917 do while(norm2(sample_normal) >= h2plus%rcut)
920 start = sample_normal
923 write(logid,
"('Generated random Markov chain start position:')")
924 write(logid,
"('X = ', F12.8, ', Y = ', F12.8, ', Z = ', F12.8)") &
925 x(1, 1), x(2, 1), x(3, 1)
937 write(logid,
"('Sample X Y Z &
938 &Local Energy Accepted?')")
939 write(logid,
"(I8, ' ', F12.8, ' ', F12.8, ' ', F12.8, ' ', F12.6)")&
940 1, x(1, 1), x(2, 1), x(3, 1), energy_chain(1)
945 call h_2_plus_energy(c_const, x(:, 1), r_a, r_b, e_loc, dphidc)
946 energy_chain(1) = e_loc
947 dphidc_chain(1) = dphidc
948 x_burnt(:, 1) = x(:, 1)
952 thin_counter = 1 + thin_counter
955 x_n = x(:, i-1) + sigma * sample_normal
958 log_prob_n = log(h_2_plus_prob(c_const, x(:, i-1), x_n, r_a, r_b))
961 a_prob_trans = min(1.0_real64, exp(log_prob_n))
964 call ran1(unif_num, seed)
967 if (a_prob_trans >= unif_num)
then
972 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
974 reset_counter = 1 + reset_counter
976 i_bt = i - burn - (reset_counter * (thin - 1))
978 x_burnt(:, i_bt) = x_n
980 call h_2_plus_energy(c_const, x_n, r_a, r_b, e_loc, dphidc)
981 energy_chain(i_bt) = e_loc
982 dphidc_chain(i_bt) = dphidc
991 if (mod(i_bt, re_size/
logfrac) .le. 1e-6_real64)
then
992 write(logid,
"(I8, ' ', F12.8, ' ', F12.8, ' ', F12.8,&
993 &' ', F12.6, ' ', A1)") (i_bt), x_burnt(1, i_bt), &
994 x_burnt(2, i_bt), x_burnt(2, i_bt), energy_chain(i_bt), &
1003 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
1005 reset_counter = 1 + reset_counter
1007 i_bt = i - burn - (reset_counter * (thin - 1))
1009 x_burnt(:, i_bt) = x(:, i-1)
1011 call h_2_plus_energy(c_const, x(:, i-1), r_a, r_b, e_loc, dphidc)
1012 energy_chain(i_bt) = e_loc
1013 dphidc_chain(i_bt) = dphidc
1020 if (mod(i_bt, re_size/
logfrac) .le. 1e-6_real64)
then
1021 write(logid,
"(I8, ' ', F12.8, ' ', F12.8, ' ', F12.8,&
1022 &' ', F12.6, ' ', A1)") (i_bt), x_burnt(1, i_bt), &
1023 x_burnt(2, i_bt), x_burnt(2, i_bt), energy_chain(i_bt), &
1031 else if (burn >= 2)
then
1035 x_n = x(:, i-1) + sigma * sample_normal
1038 log_prob_n = log(h_2_plus_prob(c_const, x(:, i-1), x_n, r_a, r_b))
1041 a_prob_trans = min(1.0_real64, exp(log_prob_n))
1044 call ran1(unif_num, seed)
1047 if (a_prob_trans >= unif_num)
then
1060 do i = burn + 1, n+1
1062 thin_counter = 1 + thin_counter
1065 x_n = x(:, i-1) + sigma * sample_normal
1068 log_prob_n = log(h_2_plus_prob(c_const, x(:, i-1), x_n, r_a, r_b))
1071 a_prob_trans = min(1.0_real64, exp(log_prob_n))
1074 call ran1(unif_num, seed)
1077 if (a_prob_trans >= unif_num)
then
1082 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
1084 reset_counter = 1 + reset_counter
1086 i_bt = i - burn - (reset_counter * (thin - 1))
1088 x_burnt(:, i_bt) = x_n
1090 call h_2_plus_energy(c_const, x_n, r_a, r_b, e_loc, dphidc)
1091 energy_chain(i_bt) = e_loc
1092 dphidc_chain(i_bt) = dphidc
1101 if (mod(i_bt, re_size/
logfrac) .le. 1e-6_real64)
then
1102 write(logid,
"(I8, ' ', F12.8, ' ', F12.8, ' ', F12.8,&
1103 &' ', F12.6, ' ', A1)") (i_bt), x_burnt(1, i_bt), &
1104 x_burnt(2, i_bt), x_burnt(2, i_bt), energy_chain(i_bt), &
1115 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
1117 reset_counter = 1 + reset_counter
1119 i_bt = i - burn - (reset_counter * (thin - 1))
1121 x_burnt(:, i_bt) = x(:, i-1)
1123 call h_2_plus_energy(c_const, x(:, i-1), r_a, r_b, e_loc, dphidc)
1124 energy_chain(i_bt) = e_loc
1125 dphidc_chain(i_bt) = dphidc
1132 if (mod(i_bt, re_size/
logfrac) .le. 1e-6_real64)
then
1133 write(logid,
"(I8, ' ', F12.8, ' ', F12.8, ' ', F12.8,&
1134 &' ', F12.6, ' ', A1)") (i_bt), x_burnt(1, i_bt), &
1135 x_burnt(2, i_bt), x_burnt(2, i_bt), energy_chain(i_bt), &
1146 accept_rate = (real(accept, kind=real64) / real(re_size, kind=real64))
1149 energy_mean = sum(energy_chain) / real(re_size, kind=real64)
1150 energy_variance = 0.0_real64
1152 energy_variance = energy_variance + ((1.0_real64 / real(re_size - 1, kind=real64)) * &
1153 (energy_chain(i) - energy_mean) * (energy_chain(i) - energy_mean))
1155 energy_variance = (1.0_real64 / real(re_size, kind=real64)) * energy_variance
1158 write(logid,
"('Local energy = ', F12.8)") energy_mean
1159 write(logid,
"('Variance = ', F12.8)") energy_variance
1160 write(logid,
"('Acceptance rate = ', F12.8)") accept_rate
1161 write(logid,
"('')")
1189 accept_out, converged)
1193 real(real64),
intent(in) :: c_in
1194 real(real64),
intent(in) :: bond_length
1195 real(real64),
intent(out) :: c_out
1196 real(real64),
intent(out) :: energy_out
1197 real(real64),
intent(out) :: variance_out
1198 real(real64),
intent(out) :: accept_out
1199 character(len=1),
intent(out) :: converged
1201 real(real64),
dimension(3) :: R_a, R_b
1202 real(real64) :: c_current, c_new
1203 real(real64) :: c_grad
1204 real(real64),
dimension(:, :),
allocatable :: pos_chain
1205 real(real64),
dimension(:),
allocatable :: energy_chain
1206 real(real64),
dimension(:),
allocatable :: DphiDc_chain
1207 integer :: viz_steps
1210 integer :: maxiter = 200
1211 real(real64) :: tol = 1e-4_real64
1212 character(len=6) :: str_b
1213 character(len=40) :: chainfile
1216 real(real64) :: my_c_grad, my_ensum
1217 real(real64) :: sum_var, sum_acc
1221 r_a = (/-bond_length/2, 0.0_real64, 0.0_real64/)
1222 r_b = (/bond_length/2, 0.0_real64, 0.0_real64/)
1225 write(logid,
"('Starting parameter search for c...')")
1229 do k = auto_start, maxiter
1232 call vqmc_h_2_plus(h2plus%sigma, my_steps+h2plus%burn_step, h2plus%burn_step, h2plus%thin_step, &
1233 c_current, r_a, r_b, pos_chain, accept_out, energy_chain, energy_out, &
1234 variance_out, dphidc_chain)
1237 my_c_grad = 2.0_real64 * (sum(energy_chain * dphidc_chain) /
size(energy_chain)) &
1238 - (energy_out * (sum(dphidc_chain) /
size(dphidc_chain)))
1241 call mpi_allreduce(my_c_grad,c_grad,1,mpi_double_precision,mpi_sum,mpi_comm_world,mpierr)
1242 c_grad = c_grad * per_proc
1246 write(logid,
"('c Gradient')")
1247 write(logid,
"(F13.7, ' ', F13.7)") c_current, c_grad
1251 if (abs(c_grad) .le. tol)
then
1258 my_ensum = sum(energy_chain)
1259 call mpi_reduce(my_ensum,energy_out,1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
1262 call mpi_reduce(variance_out, sum_var,1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
1265 call mpi_reduce(accept_out, sum_acc,1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
1268 if (my_rank==0)
then
1270 energy_out = energy_out * per_step
1271 variance_out = sum_var * per_proc2
1272 accept_out = sum_acc * per_proc
1276 write(logid,
"('Parameter search converged!')")
1277 write(logid,
"('Results:')")
1278 write(logid,
"('c = ', F13.7, ', Energy = ', F12.8, ', Variance = ', F12.8)") &
1279 c_current, energy_out, variance_out
1280 write(logid,
"('')")
1292 call h_2_plus_update_c(c_current, c_grad, c_new)
1296 if (write_restart .and. my_rank==0)
then
1297 if (mod(k,restart_num)==0)
then
1298 call write_res_nml(i_bond,k+1,h2plus%auto_params,c_current)
1305 if (k .ge. maxiter)
then
1309 write(logid,
"('Parameter search NOT converged! Consider changing&
1310 & the starting value of c, or the damping in the H_2_update_c&
1316 if (my_rank==0)
then
1318 write(*,
"(F12.8, ' ', A, ' ', F13.7, ' ', F12.8)") &
1319 bond_length, converged, c_out, energy_out
1322 if (write_chains)
then
1323 write(str_b,
"(F6.3)") bond_length
1324 write(chainfile,
"(3A)")
'./chains_out/bond_', trim(adjustl(str_b)),
'.nc'
1325 write(*,
"('Running VQMC at c = ', F12.7, ' to produce single Markov chain...')") c_out
1326 viz_steps = min(h2plus%steps,max_chain_len)
1327 call vqmc_h_2_plus(h2plus%sigma, viz_steps, h2plus%burn_step, h2plus%thin_step, &
1328 c_out, r_a, r_b, pos_chain, accept_out, energy_chain, energy_out, &
1329 variance_out, dphidc_chain)
1330 write(*,
"(2A)")
'Writing Markov chain to ', chainfile
1331 call write_h2plus_equilibration(pos_chain, energy_chain, chainfile, ierr, h2plus, &
1332 accept_out, c_out, bond_length)
1359 subroutine grid_h_2_plus(c_array, bond_length, c_out, energy_out, variance_out, &
1364 real(real64),
dimension(:),
intent(in) :: c_array
1365 real(real64),
intent(in) :: bond_length
1366 real(real64),
intent(out) :: c_out
1367 real(real64),
intent(out) :: energy_out
1368 real(real64),
intent(out) :: variance_out
1369 real(real64),
intent(out) :: accept_out
1371 real(real64),
dimension(3) :: R_a, R_b
1372 real(real64),
dimension(:, :),
allocatable :: pos_chain
1373 real(real64),
dimension(:),
allocatable :: energy_chain, DphiDc_chain
1374 real(real64),
dimension(:),
allocatable :: param_energies, param_accepts, param_variances
1375 integer :: viz_steps
1378 character(len=6) :: str_b
1379 character(len=40) :: chainfile
1382 real(real64) :: my_ensum
1385 r_a = (/-bond_length/2, 0.0_real64, 0.0_real64/)
1386 r_b = (/bond_length/2, 0.0_real64, 0.0_real64/)
1387 allocate(param_energies(
size(c_array))); param_energies(:)= 0.0_real64
1388 allocate(param_accepts(
size(c_array))); param_accepts(:) = 0.0_real64
1389 allocate(param_variances(
size(c_array))); param_variances(:) = 0.0_real64
1392 if (run_restart)
then
1394 call read_energies(resfile_epar, param_energies, param_variances, param_accepts)
1396 run_restart = .false.
1400 write(logid,
"('Starting parameter search for c...')")
1404 do i = grid_start,
size(c_array)
1407 call vqmc_h_2_plus(h2plus%sigma, my_steps+h2plus%burn_step, h2plus%burn_step, h2plus%thin_step, &
1408 c_array(i), r_a, r_b, pos_chain, accept_out, energy_chain, energy_out, &
1409 variance_out, dphidc_chain)
1417 my_ensum = sum(energy_chain)
1418 call mpi_reduce(my_ensum,param_energies(i),1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
1421 call mpi_reduce(variance_out,param_variances(i),1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
1424 call mpi_reduce(accept_out,param_accepts(i),1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
1427 if (my_rank==0)
then
1428 param_energies(i) = param_energies(i) * per_step
1429 param_variances(i) = param_variances(i) * per_proc2
1430 param_accepts(i) = param_accepts(i) * per_proc
1433 if (write_restart)
then
1434 if (mod(i,restart_num)==0)
then
1436 call write_res_nml(i_bond,i+1,h2plus%auto_params)
1438 call write_qho_main(c_array, param_energies, param_variances, resfile_epar, ierr, qho, param_accepts)
1447 if (my_rank==0)
then
1450 energy_out = minval(param_energies)
1451 c_out = c_array(minloc(param_energies, 1))
1452 variance_out = param_variances(minloc(param_energies, 1))
1453 accept_out = param_accepts(minloc(param_energies, 1))
1455 write(*,
"(F12.8, ' - ', F13.7, ' ', F12.8)") &
1456 bond_length, c_out, energy_out
1459 write(logid,
"('Results:')")
1460 write(logid,
"('c Energy')")
1461 do i = 1,
size(c_array)
1462 write(logid,
"(F12.8, ' ', F12.8)") c_array(i), param_energies(i)
1464 write(logid,
"('')")
1465 write(logid,
"('Min Energy = ', F12.8, ' at c = ', F12.8)") energy_out, c_out
1466 write(logid,
"('')")
1470 if (write_chains)
then
1471 write(str_b,
"(F6.3)") bond_length
1472 write(chainfile,
"(3A)")
'./chains_out/bond_', trim(adjustl(str_b)),
'.nc'
1473 write(*,
"('Running VQMC at c = ', F12.7, ' to produce single Markov chain...')") c_out
1474 viz_steps = min(h2plus%steps,max_chain_len)
1475 call vqmc_h_2_plus(h2plus%sigma, viz_steps, h2plus%burn_step, h2plus%thin_step, &
1476 c_out, r_a, r_b, pos_chain, accept_out, energy_chain, energy_out, &
1477 variance_out, dphidc_chain)
1478 write(*,
"(2A)")
'Writing Markov chain to ', chainfile
1479 call write_h2plus_equilibration(pos_chain, energy_chain, chainfile, ierr, h2plus, &
1480 accept_out, c_out, bond_length)
1509 real(real64),
dimension(:),
intent(in) :: c_array
1510 real(real64),
intent(in) :: bond_length
1511 integer,
intent(in) :: bonds_pos
1513 real(real64),
dimension(3) :: R_a, R_b
1514 real(real64),
dimension(:),
allocatable :: variances
1515 real(real64),
dimension(:),
allocatable :: energies
1516 real(real64),
dimension(:),
allocatable :: energy_chain
1517 real(real64),
dimension(:, :),
allocatable :: pos_chain
1518 real(real64),
dimension(:),
allocatable :: DphiDc_chain
1519 real(real64) :: accept_rate
1520 real(real64) :: energy_variance
1522 character(len=3) :: str_i, str_b
1523 character(len=40) :: equilfile
1526 r_a = (/-bond_length/2, 0.0_real64, 0.0_real64/)
1527 r_b = (/bond_length/2, 0.0_real64, 0.0_real64/)
1528 allocate(energies(
size(c_array))); energies(:) = 0.0_real64
1529 allocate(variances(
size(c_array)))
1532 do i = grid_start,
size(c_array)
1535 call vqmc_h_2_plus(h2plus%sigma, h2plus%steps, h2plus%burn_step, h2plus%thin_step, &
1536 c_array(i), r_a, r_b, pos_chain, accept_rate, energy_chain,energies(i), &
1537 energy_variance, dphidc_chain)
1539 write(*,
"(F12.8, ' - ', F13.7, ' ', F12.8)") &
1540 bond_length, c_array(i), energies(i)
1543 write(str_i,
"(I3)") i
1544 write(str_b,
"(I3)") bonds_pos
1545 write(equilfile,
"(5A)")
'./equil_out/b', trim(adjustl(str_b)), &
1546 '_c', trim(adjustl(str_i)),
'.nc'
1547 write(*, *)
'Writing equilibration outfile to ', equilfile
1548 call write_h2plus_equilibration(pos_chain, energy_chain, equilfile, ierr, h2plus, &
1549 accept_rate, c_array(i), bond_length)
1552 if (write_restart)
then
1553 if (mod(i,restart_num)==0)
then
1554 call write_res_nml(i_bond,i+1,h2%auto_params)
1561 write(logid,
"('Results:')")
1562 write(logid,
"('c Energy')")
1563 do i = 1,
size(c_array)
1564 write(logid,
"(F12.8, ' ', F12.8)") c_array(i), energies(i)
1566 write(logid,
"('')")
1569 deallocate(energies)
1570 deallocate(variances)
1617 subroutine vqmc_h_2(sigma, N, burn, thin, a, beta, R_a, R_b, &
1618 X_1_burnt, X_2_burnt, accept_rate, energy_chain, energy_mean, energy_variance, &
1619 DphiDbeta_chain, x_start_1, x_start_2)
1623 real(real64),
intent(in),
dimension(3) :: R_a, R_b
1624 real(real64),
intent(in) :: sigma
1625 real(real64),
intent(in) :: a, beta
1626 real(real64),
dimension(3),
optional :: x_start_1, x_start_2
1627 integer,
intent(in) :: N, burn, thin
1630 real(real64),
intent(out) :: accept_rate, energy_mean, energy_variance
1631 real(real64),
intent(out),
dimension(:, :),
allocatable :: X_1_burnt, X_2_burnt
1632 real(real64),
intent(out),
dimension(:),
allocatable :: energy_chain
1633 real(real64),
intent(out),
dimension(:),
allocatable :: DphiDbeta_chain
1635 real(real64) :: E_loc
1636 real(real64) :: DphiDbeta
1637 real(real64) :: log_prob_n
1638 real(real64) :: a_prob_trans
1639 real(real64) :: unif_num
1640 real(real64),
dimension(3) :: start_1, start_2
1641 real(real64),
dimension(3) :: X_n_1, X_n_2
1642 real(real64),
dimension(3) :: sample_normal
1643 real(real64),
dimension(:, :),
allocatable :: X_1, X_2
1645 integer :: thin_counter
1646 integer :: reset_counter
1650 character(len=1) :: acceptance
1653 write(logid,
"('Markov chain for beta = ', F7.4)") beta
1654 if (.not. run_equil)
write(logid,
"('Logging the chain from Rank 0.')")
1658 re_size = (n - burn) / thin
1660 allocate(x_1(3, 1:n+1)); x_1(:, :) = 0.0_real64
1661 allocate(x_2(3, 1:n+1)); x_2(:, :) = 0.0_real64
1662 allocate(x_1_burnt(3, 1:re_size)); x_1_burnt(:, :) = 0.0_real64
1663 allocate(x_2_burnt(3, 1:re_size)); x_2_burnt(:, :) = 0.0_real64
1664 allocate(energy_chain(1:re_size)); energy_chain(:) = 0.0_real64
1665 allocate(dphidbeta_chain(1:re_size)); dphidbeta_chain(:) = 0.0_real64
1668 if (
present(x_start_1) .and.
present(x_start_2))
then
1676 write(logid,
"('Starting from provided Markov chain position:')")
1677 write(logid,
"(' x1 = ', F12.8, ' y1 = ', F12.8, ' z1 = ', F12.8)") &
1678 x_1(1, 1), x_1(2, 1), x_1(3, 1)
1679 write(logid,
"(' x2 = ', F12.8, ' y2 = ', F12.8, ' z2 = ', F12.8)") &
1680 x_2(1, 1), x_2(2, 1), x_2(3, 1)
1685 do while(norm2(sample_normal) >= h2%rcut)
1688 start_1 = sample_normal
1693 do while(norm2(sample_normal) >= h2%rcut)
1696 start_2 = sample_normal
1708 write(logid,
"('Sample X1 Y1 Z1 &
1710 &Local Energy Accepted?')")
1711 write(logid,
"(I8, ' ', F12.8, ' ', F12.8, ' ', F12.8, ' ', F12.8, &
1712 &' ', F12.8, ' ', F12.8, ' ', F12.6)") 1, x_1(1, 1), x_1(2, 1), x_1(3, 1),&
1713 x_2(1, 1), x_2(2, 1), x_2(3, 1), energy_chain(1)
1718 call h_2_energy(a, beta, x_1(:,1), x_2(:,1), r_a, r_b, e_loc, dphidbeta)
1719 energy_chain(1) = e_loc
1720 dphidbeta_chain(1) = dphidbeta
1721 x_1_burnt(:, 1) = x_1(:, 1)
1722 x_2_burnt(:, 1) = x_2(:, 1)
1726 thin_counter = 1 + thin_counter
1730 x_n_1 = x_1(:, i-1) + sigma * sample_normal
1734 x_n_2 = x_2(:, i-1) + sigma * sample_normal
1737 log_prob_n = log(h_2_prob(a, beta, x_1(:, i-1), x_2(:, i-1), x_n_1, x_n_2, r_a, r_b))
1740 a_prob_trans = min(1.0_real64, exp(log_prob_n))
1743 call ran1(unif_num, seed)
1746 if (a_prob_trans >= unif_num)
then
1752 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
1754 reset_counter = 1 + reset_counter
1756 i_bt = i - burn - (reset_counter * (thin - 1))
1758 x_1_burnt(:, i_bt) = x_n_1
1759 x_2_burnt(:, i_bt) = x_n_2
1761 call h_2_energy(a, beta, x_n_1, x_n_2, r_a, r_b, e_loc, dphidbeta)
1762 energy_chain(i_bt) = e_loc
1763 dphidbeta_chain(i_bt) = dphidbeta
1772 if (mod(i_bt, re_size/
logfrac) .le. 1e-6_real64)
then
1773 write(logid,
"(I8, ' ', F12.8, ' ', F12.8, ' ', F12.8,&
1774 & ' ', F12.8, ' ', F12.8, ' ', F12.8, ' ', F12.6, ' ', A1)") &
1775 (i-burn), x_1_burnt(1, i-burn), x_1_burnt(2, i-burn), x_1_burnt(3, i-burn),&
1776 x_2_burnt(1, i-burn), x_2_burnt(2, i-burn), x_2_burnt(3, i-burn),&
1777 energy_chain(i-burn), acceptance
1783 x_1(:, i) = x_1(:, i-1)
1784 x_2(:, i) = x_2(:, i-1)
1787 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
1789 reset_counter = 1 + reset_counter
1791 i_bt = i - burn - (reset_counter * (thin - 1))
1793 x_1_burnt(:, i_bt) = x_1(:, i-1)
1794 x_2_burnt(:, i_bt) = x_2(:, i-1)
1796 call h_2_energy(a, beta, x_1(:, i-1), x_2(:, i-1), r_a, r_b, e_loc, dphidbeta)
1797 energy_chain(i_bt) = e_loc
1798 dphidbeta_chain(i_bt) = dphidbeta
1805 if (mod(i_bt, re_size/
logfrac) .le. 1e-6_real64)
then
1806 write(logid,
"(I8, ' ', F12.8, ' ', F12.8, ' ', F12.8,&
1807 & ' ', F12.8, ' ', F12.8, ' ', F12.8, ' ', F12.6, ' ', A1)") &
1808 (i_bt), x_1_burnt(1, i_bt), x_1_burnt(2, i_bt), x_1_burnt(3, i_bt),&
1809 x_2_burnt(1, i_bt), x_2_burnt(2, i_bt), x_2_burnt(3, i_bt),&
1810 energy_chain(i_bt), acceptance
1817 else if (burn >= 2)
then
1821 x_n_1 = x_1(:, i-1) + sigma * sample_normal
1825 x_n_2 = x_2(:, i-1) + sigma * sample_normal
1828 log_prob_n = log(h_2_prob(a, beta, x_1(:, i-1), x_2(:, i-1), x_n_1, x_n_2, r_a, r_b))
1831 a_prob_trans = min(1.0_real64, exp(log_prob_n))
1834 call ran1(unif_num, seed)
1837 if (a_prob_trans >= unif_num)
then
1843 x_1(:, i) = x_1(:, i-1)
1844 x_2(:, i) = x_2(:, i-1)
1848 if (i_log)
write(logid,
"('---------- Burning steps completed. ----------')")
1855 do i = (burn + 1) , n+1
1857 thin_counter = 1 + thin_counter
1860 x_n_1 = x_1(:, i-1) + sigma * sample_normal
1864 x_n_2 = x_2(:, i-1) + sigma * sample_normal
1867 log_prob_n = log(h_2_prob(a, beta, x_1(:, i-1), x_2(:, i-1), x_n_1, x_n_2, r_a, r_b))
1870 a_prob_trans = min(1.0_real64, exp(log_prob_n))
1873 call ran1(unif_num, seed)
1876 if (a_prob_trans >= unif_num)
then
1882 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
1884 reset_counter = 1 + reset_counter
1886 i_bt = i - burn - (reset_counter * (thin - 1))
1888 x_1_burnt(:, i_bt) = x_n_1
1889 x_2_burnt(:, i_bt) = x_n_2
1891 call h_2_energy(a, beta, x_n_1, x_n_2, r_a, r_b, e_loc, dphidbeta)
1892 energy_chain(i_bt) = e_loc
1893 dphidbeta_chain(i_bt) = dphidbeta
1902 if (mod(i-burn, re_size/
logfrac) .le. 1e-6_real64)
then
1903 write(logid,
"(I8, ' ', F12.8, ' ', F12.8, ' ', F12.8,&
1904 & ' ', F12.8, ' ', F12.8, ' ', F12.8, ' ', F12.6, ' ', A1)") &
1905 (i_bt), x_1_burnt(1, i_bt), x_1_burnt(2, i_bt), x_1_burnt(3, i_bt),&
1906 x_2_burnt(1, i_bt), x_2_burnt(2, i_bt), x_2_burnt(3, i_bt),&
1907 energy_chain(i_bt), acceptance
1913 x_1(:, i) = x_1(:, i-1)
1914 x_2(:, i) = x_2(:, i-1)
1917 if ((i > (burn + 1)) .and. (thin_counter == thin))
then
1919 reset_counter = 1 + reset_counter
1921 i_bt = i - burn - (reset_counter * (thin - 1))
1923 x_1_burnt(:, i_bt) = x_1(:, i-1)
1924 x_2_burnt(:, i_bt) = x_2(:, i-1)
1926 call h_2_energy(a, beta, x_1(:, i-1), x_2(:, i-1), r_a, r_b, e_loc, dphidbeta)
1927 energy_chain(i_bt) = e_loc
1928 dphidbeta_chain(i_bt) = dphidbeta
1937 accept_rate = (real(accept, kind=real64) / real(re_size, kind=real64))
1940 energy_mean = sum(energy_chain) / real(re_size, kind=real64)
1941 energy_variance = 0.0_real64
1943 energy_variance = energy_variance + ((1.0_real64 / real(re_size - 1, kind=real64)) * &
1944 (energy_chain(i) - energy_mean) * (energy_chain(i) - energy_mean))
1946 energy_variance = (1.0_real64 / real(re_size, kind=real64)) * energy_variance
1949 write(logid,
"('Local energy = ', F12.8)") energy_mean
1950 write(logid,
"('Variance = ', F12.8)") energy_variance
1951 write(logid,
"('Acceptance rate = ', F12.8)") accept_rate
1952 write(logid,
"('')")
1980 subroutine auto_h_2(a, beta_in, bond_length, beta_out, energy_out, variance_out, &
1981 accept_out, converged)
1985 real(real64),
intent(in) :: a
1986 real(real64),
intent(in) :: beta_in
1987 real(real64),
intent(in) :: bond_length
1988 real(real64),
intent(out) :: beta_out
1989 real(real64),
intent(out) :: energy_out
1990 real(real64),
intent(out) :: variance_out
1991 real(real64),
intent(out) :: accept_out
1992 character(len=1),
intent(out) :: converged
1994 real(real64),
dimension(3) :: R_a, R_b
1995 real(real64) :: beta_current, beta_new
1996 real(real64) :: beta_grad
1997 real(real64),
dimension(:, :),
allocatable :: e1_pos_chain, e2_pos_chain
1998 real(real64),
dimension(:),
allocatable :: energy_chain, DphiDbeta_chain
1999 integer :: viz_steps
2002 integer :: maxiter = 200
2003 real(real64) :: tol = 1e-4_real64
2004 character(len=6) :: str_b
2005 character(len=40) :: chainfile
2008 real(real64) :: my_beta_grad, my_ensum
2009 real(real64) :: sum_var, sum_acc
2012 beta_current = beta_in
2013 r_a = (/-bond_length/2, 0.0_real64, 0.0_real64/)
2014 r_b = (/bond_length/2, 0.0_real64, 0.0_real64/)
2017 write(logid,
"('Starting parameter search for beta...')")
2021 do k = auto_start, maxiter
2024 call vqmc_h_2(h2%sigma, my_steps+h2%burn_step, h2%burn_step, h2%thin_step, a, &
2025 beta_current, r_a, r_b, e1_pos_chain, e2_pos_chain, accept_out, &
2026 energy_chain, energy_out, variance_out, dphidbeta_chain)
2029 my_beta_grad = 2.0_real64 * ((sum(energy_chain * dphidbeta_chain) /
size(energy_chain)) &
2030 - energy_out * (sum(dphidbeta_chain) /
size(energy_chain)))
2033 call mpi_allreduce(my_beta_grad,beta_grad,1,mpi_double_precision,mpi_sum,mpi_comm_world,mpierr)
2034 beta_grad = beta_grad * per_proc
2038 write(logid,
"('Beta Gradient')")
2039 write(logid,
"(F13.7, ' ', F13.7)") beta_current, beta_grad
2043 if (abs(beta_grad) .le. tol)
then
2046 beta_out = beta_current
2050 my_ensum = sum(energy_chain)
2051 call mpi_reduce(my_ensum,energy_out,1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
2054 call mpi_reduce(variance_out, sum_var,1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
2057 call mpi_reduce(accept_out, sum_acc,1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
2060 if (my_rank==0)
then
2062 energy_out = energy_out * per_step
2063 variance_out = sum_var * per_proc2
2064 accept_out = sum_acc * per_proc
2067 write(logid,
"('Parameter search converged!')")
2068 write(logid,
"('Results:')")
2069 write(logid,
"('Beta = ', F13.7, ', Energy = ', F12.8, ', Variance = ', F12.8)") &
2070 beta_current, energy_out, variance_out
2071 write(logid,
"('')")
2083 call h_2_update_beta(beta_current, beta_grad, beta_new)
2084 beta_current = beta_new
2087 if (write_restart .and. my_rank==0)
then
2088 if (mod(k,restart_num)==0)
then
2090 call write_res_nml(i_bond,k+1,h2%auto_params,beta_current)
2097 if (k .ge. maxiter)
then
2099 beta_out = beta_current
2101 write(logid,
"('Parameter search NOT converged! Consider changing&
2102 & the starting value of beta, or the damping in the H_2_update_beta&
2108 if (my_rank==0)
then
2109 write(*,
"(F12.8, ' ', A, ' ', F13.7, ' ', F12.8)") &
2110 bond_length, converged, beta_out, energy_out
2114 if (my_rank == 0)
then
2115 if (write_chains)
then
2116 write(str_b,
"(F6.3)") bond_length
2117 write(chainfile,
"(3A)")
'./chains_out/bond_', trim(adjustl(str_b)),
'.nc'
2118 write(*,
"('Running VQMC at beta = ', F12.7, ' to produce single Markov chain...')") beta_out
2119 viz_steps = min(h2plus%steps,max_chain_len)
2120 call vqmc_h_2(h2%sigma, viz_steps, h2%burn_step, h2%thin_step, a, &
2121 beta_out, r_a, r_b, e1_pos_chain, e2_pos_chain, accept_out, &
2122 energy_chain, energy_out, variance_out, dphidbeta_chain)
2123 write(*,
"(2A)")
'Writing Markov chain to ', chainfile
2124 call write_h2_equilibration(e1_pos_chain, energy_chain, chainfile, ierr, &
2125 h2, accept_out, beta_out, bond_length)
2153 subroutine grid_h_2(a, beta_array, bond_length, beta_out, energy_out, variance_out, &
2158 real(real64),
intent(in) :: a
2159 real(real64),
dimension(:),
intent(in) :: beta_array
2160 real(real64),
intent(in) :: bond_length
2161 real(real64),
intent(out) :: beta_out
2162 real(real64),
intent(out) :: energy_out
2163 real(real64),
intent(out) :: variance_out
2164 real(real64),
intent(out) :: accept_out
2166 real(real64),
dimension(3) :: R_a, R_b
2167 real(real64),
dimension(:, :),
allocatable :: e1_pos_chain, e2_pos_chain
2168 real(real64),
dimension(:),
allocatable :: energy_chain, DphiDbeta_chain
2169 real(real64),
dimension(:),
allocatable :: param_energies, param_accepts, param_variances
2170 integer :: viz_steps
2173 character(len=6) :: str_b
2174 character(len=40) :: chainfile
2177 real(real64) :: my_ensum
2180 r_a = (/-bond_length/2, 0.0_real64, 0.0_real64/)
2181 r_b = (/bond_length/2, 0.0_real64, 0.0_real64/)
2182 allocate(param_energies(
size(beta_array))); param_energies(:)= 0.0_real64
2183 allocate(param_accepts(
size(beta_array))); param_accepts(:) = 0.0_real64
2184 allocate(param_variances(
size(beta_array))) ; param_variances(:) = 0.0_real64
2187 if (run_restart)
then
2189 call read_energies(resfile_epar, param_energies, param_variances, param_accepts)
2191 run_restart = .false.
2195 write(logid,
"('Starting parameter search for beta...')")
2199 do i = grid_start,
size(beta_array)
2202 call vqmc_h_2(h2%sigma, my_steps+h2%burn_step, h2%burn_step, h2%thin_step, a, &
2203 beta_array(i), r_a, r_b, e1_pos_chain, e2_pos_chain, accept_out, &
2204 energy_chain, energy_out, variance_out, dphidbeta_chain)
2212 my_ensum = sum(energy_chain)
2213 call mpi_reduce(my_ensum,param_energies(i),1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
2216 call mpi_reduce(variance_out,param_variances(i),1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
2219 call mpi_reduce(accept_out,param_accepts(i),1,mpi_double_precision,mpi_sum,0,mpi_comm_world,mpierr)
2222 if (my_rank==0)
then
2223 param_energies(i) = param_energies(i) * per_step
2224 param_variances(i) = param_variances(i) * per_proc2
2225 param_accepts(i) = param_accepts(i) * per_proc
2228 if (write_restart)
then
2230 call write_res_nml(i_bond,i+1,h2%auto_params)
2232 call write_qho_main(beta_array, param_energies, param_variances, resfile_epar, ierr, qho, param_accepts)
2239 if (my_rank==0)
then
2242 energy_out = minval(param_energies)
2243 beta_out = beta_array(minloc(param_energies, 1))
2244 variance_out = param_variances(minloc(param_energies, 1))
2245 accept_out = param_accepts(minloc(param_energies, 1))
2248 write(*,
"(F12.8, ' - ', F13.7, ' ', F12.8)") &
2249 bond_length, beta_out, energy_out
2252 write(logid,
"('Results:')")
2253 write(logid,
"('beta Energy')")
2254 do i = 1,
size(beta_array)
2255 write(logid,
"(F12.8, ' ', F12.8)") beta_array(i), param_energies(i)
2257 write(logid,
"('')")
2258 write(logid,
"('Min Energy = ', F12.8, ' at c = ', F12.8)") energy_out, beta_out
2259 write(logid,
"('')")
2263 if (write_chains)
then
2264 write(str_b,
"(F6.3)") bond_length
2265 write(chainfile,
"(3A)")
'./chains_out/bond_', trim(adjustl(str_b)),
'.nc'
2266 write(*,
"('Running VQMC at beta = ', F12.7, ' to produce single Markov chain...')") beta_out
2267 viz_steps = min(h2plus%steps,max_chain_len)
2268 call vqmc_h_2(h2%sigma, viz_steps, h2%burn_step, h2%thin_step, a, &
2269 beta_out, r_a, r_b, e1_pos_chain, e2_pos_chain, accept_out, &
2270 energy_chain, energy_out, variance_out, dphidbeta_chain)
2271 write(*,
"(2A)")
'Writing Markov chain to ', chainfile
2272 call write_h2_equilibration(e1_pos_chain, energy_chain, chainfile, ierr, &
2273 h2, accept_out, beta_out, bond_length)
2303 real(real64),
intent(in) :: a
2304 real(real64),
dimension(:),
intent(in) :: beta_array
2305 real(real64),
intent(in) :: bond_length
2306 integer,
intent(in) :: bonds_pos
2308 real(real64),
dimension(3) :: R_a, R_b
2309 real(real64),
dimension(:),
allocatable :: variances
2310 real(real64),
dimension(:),
allocatable :: energies
2311 real(real64),
dimension(:, :),
allocatable :: e1_pos_chain, e2_pos_chain
2312 real(real64),
dimension(:),
allocatable :: energy_chain, DphiDbeta_chain
2313 real(real64) :: accept_rate
2314 real(real64) :: energy_mean
2315 real(real64) :: energy_variance
2317 character(len=3) :: str_i, str_b
2318 character(len=40) :: equilfile
2321 r_a = (/-bond_length/2, 0.0_real64, 0.0_real64/)
2322 r_b = (/bond_length/2, 0.0_real64, 0.0_real64/)
2323 allocate(energies(
size(beta_array))); energies(:) = 0.0_real64
2324 allocate(variances(
size(beta_array)))
2327 do i = grid_start,
size(beta_array)
2330 call vqmc_h_2(h2%sigma, h2%steps, h2%burn_step, h2%thin_step, a, &
2331 beta_array(i), r_a, r_b, e1_pos_chain, e2_pos_chain, accept_rate, &
2332 energy_chain, energy_mean, energy_variance, dphidbeta_chain)
2334 energies(i) = energy_mean
2336 write(*,
"(F12.8, ' - ', F13.7, ' ', F12.8)") &
2337 bond_length, beta_array(i), energies(i)
2340 write(str_i,
"(I3)") i
2341 write(str_b,
"(I3)") bonds_pos
2342 write(equilfile,
"(5A)")
'./equil_out/b', trim(adjustl(str_b)), &
2343 '_beta', trim(adjustl(str_i)),
'.nc'
2344 write(*, *)
'Writing equilibration outfile to ', equilfile
2345 call write_h2_equilibration(e1_pos_chain, energy_chain, equilfile, ierr, &
2346 h2, accept_rate, beta_array(i), bond_length)
2349 if (write_restart)
then
2350 if (mod(i,restart_num)==0)
then
2351 call write_res_nml(i_bond,i+1,h2%auto_params)
2358 write(logid,
"('Results:')")
2359 write(logid,
"('beta Energy')")
2360 do i = 1,
size(beta_array)
2361 write(logid,
"(F12.8, ' ', F12.8)") beta_array(i), energies(i)
2363 write(logid,
"('')")
2366 deallocate(energies)
2367 deallocate(variances)
Contains mathematical constants needed throughout the code, all of which are globally accessible.
Contains routines to read and write restart files.
Contains derived types, and global variables to store input values of simulation parameters.
integer(int64) seed
Seed for the random number generator.
Contains local energy and transition probability solvers for available problems.
Contains routines for handline random number generation, the main VQMC algorithms and routines for de...
subroutine ran1(sample, dseed)
Implementation of Press et al's random number generator.
subroutine vqmc_qho(sigma, N, burn, thin, alpha_const, X_burnt, accept_rate, energy_chain, energy_mean, energy_variance, x_start)
Performs VQMC for the QHO system.
subroutine grid_h_2(a, beta_array, bond_length, beta_out, energy_out, variance_out, accept_out)
Performs a grid search to find the optimal value for the variational parameter in the problem.
subroutine auto_h_2_plus(c_in, bond_length, c_out, energy_out, variance_out, accept_out, converged)
Automatically finds the best variational parameter for the problem at given bond length.
subroutine vqmc_h_2(sigma, N, burn, thin, a, beta, R_a, R_b, X_1_burnt, X_2_burnt, accept_rate, energy_chain, energy_mean, energy_variance, DphiDbeta_chain, x_start_1, x_start_2)
Performs VQMC for the system.
integer(int64), save iy
Variable controlling the RNG sequence.
subroutine equil_h_2_plus(c_array, bond_length, bonds_pos)
Performs VQMC on an array of values for the variational parameter , outputting energy traces for each...
integer, parameter ntab
Variable controlling the RNG sequence.
integer logfrac
1/logfrac is the fraction of samples to report in the log, if shared_data::write_log is TRUE.
subroutine equil_qho(alpha_array)
Performs VQMC on an array of values for the variational parameter , outputting energy traces for each...
subroutine random_normal(dim, x)
Draws a sample from a normal distribution using the Box-Muller transform.
real(real64) function, dimension(:), allocatable linspace(start, end, num)
Adaptation of numpy's linspace function.
subroutine grid_h_2_plus(c_array, bond_length, c_out, energy_out, variance_out, accept_out)
Performs a grid search to find the optimal value for the variational parameter in the problem.
subroutine auto_h_2(a, beta_in, bond_length, beta_out, energy_out, variance_out, accept_out, converged)
Automatically finds the best variational parameter for the problem at a given bond length.
subroutine grid_qho(alpha_array, energies, acc_rates, variances)
Performs VQMC on an array of values for the variational parameter .
subroutine vqmc_h_2_plus(sigma, N, burn, thin, c_const, R_a, R_b, X_burnt, accept_rate, energy_chain, energy_mean, energy_variance, DphiDc_chain, x_start)
Performs VQMC for the system.
integer(int64), dimension(ntab), save iv
Variable controlling the RNG sequence.
subroutine equil_h_2(a, beta_array, bond_length, bonds_pos)
Performs VQMC on an array of values for the variational parameter , outputting energy traces for each...
subroutine init_ran1()
Initialiser for the random number generator.
Contains NetCDF output functions for different problem main & equilibration runs.