Subroutine for running the main code (needed for Doxygen compatability).
The main driver code for the VQMC program. Links all other modules to run VQMC calculations on the Quantum Harmonic Oscillator (QHO), the Hydrogen Molecular Ion (H2plus) and the Hydrogen Molecule (H2).
Reads inputs from a provided input file, either generated by a Python frontend script or handwritten in the Fortran Namelist I/O format. Determines the problem to be solved, then runs VQMC routines. These can be run over a set parameter space, or in the case of the H2plus and H2 problems, can automatically determine the best variational parameter for the current bond length. Outputs results in NetCDF format, to be read by a Python frontend visualisation notebook for analysis.
Also includes extensions to start separate equilibration runs for determining optimal burning/thinning parameters for the Markov chain, and to write the energy traces for each parameter / parameter combination. Also capable of logging the full Markov chain to file (slow, should only be used for debug).
59 real(real64),
dimension(:),
allocatable :: p_arr
60 real(real64),
dimension(:),
allocatable :: bonds
61 real(real64),
dimension(:),
allocatable :: H2plus_param_c_array
62 real(real64),
dimension(:),
allocatable :: H2_param_a_array
63 real(real64),
dimension(:),
allocatable :: H2_param_beta_array
64 real(real64),
dimension(:),
allocatable :: energies
65 real(real64),
dimension(:),
allocatable :: variances
66 real(real64),
dimension(:),
allocatable :: accept_rates
68 real(real64) :: H2plus_param_c_guess
69 real(real64) :: H2plus_param_c_opt
70 real(real64) :: H2_param_beta_guess
71 real(real64) :: H2_param_beta_opt
72 real(real64) :: H2_param_a
73 real(real64) :: energy
74 real(real64) :: variance
75 real(real64) :: accept_rate
80 character(len=1) :: H2plus_c_converged
81 character(len=1) :: H2_beta_converged
91 call mpi_comm_size(mpi_comm_world,p,mpierr)
92 call mpi_comm_rank(mpi_comm_world,my_rank,mpierr)
101 write(*,
"('System: ', A)") p_system
109 call system(
'mkdir ./equil_out 2>/dev/null')
110 write(*,
"('Dice QMC started in Equilibration Mode')")
112 if(run_steps>max_chain_len)
then
114 write(*,
"(A, I7, A)")
'WARNING: The program will be slow at writing equilibration files, &
115 &as the requested number of steps exceeds the recommended &
116 &upper limit of ', max_chain_len,
' steps. Refer to the user manual for details.'
122 if (write_chains)
then
123 if (.not. run_equil)
then
124 call system(
'mkdir ./chains_out 2>/dev/null')
125 write(*,
"('Dice QMC started in full VQMC mode with additional Markov chain outputting')")
127 if(run_steps>max_chain_len)
then
128 write(*,*)
'NOTE: For efficiency, only the first ', max_chain_len,
' entries of the Markov chain &
129 &(after burning and thinning) will be written out to the chains_out folder.'
132 error stop
"Dice QMC cannot be started with both run_equil and write_chains set &
133 &to TRUE. Check your input params.txt and try again."
141 open(logid, file=logfile, status=
'unknown', access=
'sequential', &
142 form=
'formatted', iostat=logiostat)
143 if (logiostat .ne. 0)
write(0, *)
'Error opening log file ', logfile
146 write(logid,
"('*** Dice QMC log file ***')")
147 write(logid,
"('-------------------------------')")
148 write(logid, *)
'System: ', p_system
159 if (trim(p_system)==
'test')
then
165 call mpi_finalize(mpierr)
172 if (.not. run_equil)
then
175 my_steps = run_steps / p
176 if (my_rank < (run_steps-(my_steps*p)))
then
177 my_steps = my_steps+1
181 my_size = my_steps/tstep
182 call mpi_reduce(my_size,tot_size,1,mpi_integer,mpi_sum,0,mpi_comm_world,mpierr)
185 per_step = 1.0_real64 / real(tot_size,kind=real64)
187 per_proc = 1.0_real64 / real(p,kind=real64)
189 per_proc2 = per_proc**2
193 call mpi_bcast(per_proc,1,mpi_double_precision,0,mpi_comm_world,mpierr)
206 write(logid,
"('Initial seed from /dev/urandom: ', I20)") seed
210 if (trim(p_system) .eq.
'H2plus' .and. h2plus%auto_params)
then
211 h2plus%auto_params = .false.
212 write(*,
"('WARNING: H2plus%auto_params should not be .TRUE. when in Equilibration Mode, disabling...')")
213 else if (trim(p_system) .eq.
'H2' .and. h2%auto_params)
then
214 h2%auto_params = .false.
215 write(*,
"('WARNING: H2plus%auto_params should not be .TRUE. when in Equilibration Mode, disabling...')")
226 call mpi_send(seed,1,mpi_integer8,0,tag_seed,mpi_comm_world,mpierr)
229 write(logid,
"('Rank ',I2,'. Initial seed from /dev/urandom: ', I20)") my_rank, seed
232 call mpi_recv(ip_seed,1,mpi_integer8,ip,tag_seed,mpi_comm_world,status,mpierr)
234 write(logid,
"('Rank ',I2,'. Initial seed from /dev/urandom: ', I20)") ip, ip_seed
247 select case(trim(p_system))
257 write(*,
"('Doing VQMC runs across ', I3, ' parameter(s).')") int(qho%alpha(3))
258 write(*,
"('Steps: ', I10, ', Burn Steps: ', I7, ', Thin Every ', I7, ' Steps.')") &
259 qho%steps, qho%burn_step, qho%thin_step
264 p_arr = linspace(qho%alpha(1), qho%alpha(2), qho%alpha(3))
267 write(*,
"('Grid search across linearly spaced parameters enabled.')")
270 write(logid,
"('Grid search across linearly spaced parameters enabled.')")
271 write(logid,
"('Array of alpha values: ')")
272 do i = 1, int(qho%alpha(3))
273 write(logid,
"(F12.8)") p_arr(i)
283 call equil_qho(p_arr)
287 allocate(energies(int(qho%alpha(3)))); energies(:) = 0.0_real64
288 allocate(variances(int(qho%alpha(3)))); variances(:) = 0.0_real64
289 allocate(accept_rates(int(qho%alpha(3)))); accept_rates(:) = 0.0_real64
292 if (run_restart)
then
294 call read_energies(resfile_etot, energies, variances, accept_rates)
298 call grid_qho(p_arr, energies, accept_rates, variances)
308 allocate(energies(int(h2plus%bond(3))))
309 allocate(variances(int(h2plus%bond(3))))
310 allocate(accept_rates(int(h2plus%bond(3))))
311 allocate(h2plus_param_c_array(int(h2plus%bond(3))))
315 write(*,
"('Doing VQMC runs across ', I7, ' bond lengths.')") int(h2plus%bond(3))
316 write(*,
"('Steps: ', I10, ', Burn Steps: ', I7, ', Thin Every ', &
317 & I7, ' Steps.')") h2plus%steps, h2plus%burn_step, h2plus%thin_step
322 bonds = linspace(h2plus%bond(1), h2plus%bond(2), h2plus%bond(3))
324 write(logid,
"('Array of bond lengths: ')")
325 do i = 1, int(h2plus%bond(3))
326 write(logid,
"('Bond length ', I4, ': ', F7.4)") i, bonds(i)
332 if (h2plus%auto_params .eqv. .false.)
then
333 p_arr = linspace(h2plus%c_grid(1), h2plus%c_grid(2), h2plus%c_grid(3))
338 if (h2plus%auto_params .eqv. .false.)
then
339 write(*,
"('Grid search across linearly spaced parameters enabled.')")
342 write(logid,
"('Grid search across linearly spaced parameters enabled.')")
343 write(logid,
"('Array of c values: ')")
344 do i = 1, int(h2plus%c_grid(3))
345 write(logid,
"(F12.8)") p_arr(i)
350 write(*,
"('Automatic search across parameters enabled.')")
353 write(logid,
"('Automatic search across parameters enabled.')")
360 if (run_restart .and. (.not. run_equil))
then
362 call read_energies_h2plus(resfile_etot, energies, variances, accept_rates,h2plus_param_c_array)
366 if ((.not. run_equil) .and. h2plus%auto_params)
then
367 if ( run_restart)
then
368 if (.not. res%auto) error stop
'Error: Inconsistency in auto_params setting between params.txt and res_nml.txt.'
369 h2plus_param_c_guess = res%guess
371 h2plus_param_c_guess = h2plus%c
377 write(*,
"('------------------ Begin VQMC Runs ------------------')")
378 write(*,
"('Bond Length Converged? Optimised c Energy')")
380 write(logid,
"('------------------ Begin VQMC Runs ------------------')")
385 do b = bond_start, int(h2plus%bond(3))
391 write(logid,
"(' ------------- Bond Length = ', F7.4, ' ------------- ')") &
396 if (.not. run_equil)
then
398 if (h2plus%auto_params)
then
401 call auto_h_2_plus(h2plus_param_c_guess, bonds(b), h2plus_param_c_opt, &
402 energy, variance, accept_rate, h2plus_c_converged)
409 if (h2plus_c_converged .eq.
'Y') h2plus_param_c_guess = h2plus_param_c_opt
414 call grid_h_2_plus(p_arr, bonds(b), h2plus_param_c_opt, energy, &
415 variance, accept_rate)
425 h2plus_param_c_array(b) = h2plus_param_c_opt
427 variances(b) = variance
428 accept_rates(b) = accept_rate
431 if (write_restart)
then
433 call write_h2plus_main(h2plus_param_c_array, bonds, energies, variances, &
434 resfile_etot, ierr, h2plus, accept_rates)
436 if (h2plus%auto_params)
then
437 call write_res_nml(b+1,1,h2plus%auto_params,h2plus_param_c_guess)
439 call write_res_nml(b+1,1,h2plus%auto_params)
448 call equil_h_2_plus(p_arr, bonds(b), b)
450 if (write_restart)
then
451 call write_res_nml(b+1,1,h2plus%auto_params)
461 write(*,
"('------------------- End VQMC Runs -------------------')")
465 if (.not. run_equil)
then
466 write(*,
"(2A)")
'Calculations finished, writing results to NetCDF output file ', &
469 write(logid,
"(2A)")
'Calculations finished, writing results to NetCDF &
470 &output file ', outfile
473 call write_h2plus_main(h2plus_param_c_array, bonds, energies, variances, &
474 outfile, ierr, h2plus, accept_rates)
487 allocate(energies(int(h2%bond(3))))
488 allocate(variances(int(h2%bond(3))))
489 allocate(accept_rates(int(h2%bond(3))))
490 allocate(h2_param_a_array(int(h2%bond(3))))
491 allocate(h2_param_beta_array(int(h2%bond(3))))
495 write(*,
"('Doing VQMC runs across ', I7, ' bond lengths.')") int(h2%bond(3))
496 write(*,
"('Steps: ', I10, ', Burn Steps: ', I7, ', Thin Every ', I7, ' Steps.')") &
497 h2%steps, h2%burn_step, h2%thin_step
502 bonds = linspace(h2%bond(1), h2%bond(2), h2%bond(3))
504 write(logid,
"('Array of bond lengths: ')")
505 do i = 1, int(h2%bond(3))
506 write(logid,
"('Bond length ', I4, ': ', F7.4)") i, bonds(i)
512 if (h2%auto_params .eqv. .false.)
then
513 p_arr = linspace(h2%beta_grid(1), h2%beta_grid(2), h2%beta_grid(3))
518 if (h2%auto_params .eqv. .false.)
then
519 write(*,
"('Grid search across linearly spaced parameters enabled.')")
522 write(logid,
"('Grid search across linearly spaced parameters enabled.')")
523 write(logid,
"('Array of beta values: ')")
524 do i = 1, int(h2%beta_grid(3))
525 write(logid,
"(F12.8)") p_arr(i)
530 write(*,
"('Automatic search across parameters enabled.')")
533 write(logid,
"('Automatic search across parameters enabled.')")
540 if (run_restart .and. (.not. run_equil))
then
542 call read_energies_h2(resfile_etot, energies, variances, accept_rates,h2_param_a_array,h2_param_beta_array)
546 if ((.not. run_equil) .and. h2%auto_params)
then
547 if (run_restart)
then
548 if (.not. res%auto) error stop
'Error: Inconsistency in auto_params setting between params.txt and res_nml.txt.'
549 h2_param_beta_guess = res%guess
551 h2_param_beta_guess = h2%beta
557 write(*,
"('------------------ Begin VQMC Runs ------------------')")
558 write(*,
"('Bond Length Converged? Optimised Beta Energy')")
560 write(logid,
"('------------------ Begin VQMC Runs ------------------')")
565 do b = bond_start, int(h2%bond(3))
571 write(logid,
"(' ------------- Bond Length = ', F7.4, ' ------------- ')") &
576 h2_param_a = h_2_cusp(bonds(b))
579 if (.not. run_equil)
then
582 if (h2%auto_params)
then
585 call auto_h_2(h2_param_a, h2_param_beta_guess, bonds(b), h2_param_beta_opt, &
586 energy, variance, accept_rate, h2_beta_converged)
590 if (h2_beta_converged .eq.
'Y') h2_param_beta_guess = h2_param_beta_opt
598 call grid_h_2(h2_param_a, p_arr, bonds(b), h2_param_beta_opt, energy, &
599 variance, accept_rate)
605 if (write_restart .and. my_rank==0)
then
606 call write_h2_main(h2_param_a_array, h2_param_beta_array, bonds, &
607 energies, variances, resfile_etot, ierr, h2, accept_rates)
608 call write_res_nml(b+1,1,h2%auto_params)
616 h2_param_a_array(b) = h2_param_a
617 h2_param_beta_array(b) = h2_param_beta_opt
619 variances(b) = variance
620 accept_rates(b) = accept_rate
623 if (write_restart)
then
625 call write_h2_main(h2_param_a_array, h2_param_beta_array, bonds, &
626 energies, variances, resfile_etot, ierr, h2, accept_rates)
627 if (h2%auto_params)
then
628 call write_res_nml(b+1,1,h2%auto_params,h2_param_beta_guess)
630 call write_res_nml(b+1,1,h2%auto_params)
640 call equil_h_2(h2_param_a, p_arr, bonds(b), b)
642 if (write_restart)
then
643 call write_res_nml(b+1,1,h2%auto_params)
653 write(*,
"('------------------- End VQMC Runs -------------------')")
657 if (.not. run_equil)
then
659 write(*,
"(2A)")
'Calculations finished, writing results to NetCDF output file ', &
663 write(logid,
"(2A)")
'Calculations finished, writing results to NetCDF &
664 &output file ', outfile
667 call write_h2_main(h2_param_a_array, h2_param_beta_array, bonds, &
668 energies, variances, outfile, ierr, h2, accept_rates)
676 error stop
'Unknown case. How did you get here?'
680 if (i_log)
close(logid)
683 call system(
'rm res_etot.nc 2>/dev/null')
684 call system(
'rm res_nml.txt 2>/dev/null')
685 call system(
'rm res_epar.nc 2>/dev/null')
688 call mpi_finalize(mpierr)