mirror of
https://gitlab.com/scemama/qmcchem.git
synced 2024-12-21 20:03:31 +01:00
Improved async DMC
This commit is contained in:
parent
5b1379fd9c
commit
a0323922a8
@ -20,13 +20,15 @@
|
|||||||
integer :: iw ! Number of copies in branching
|
integer :: iw ! Number of copies in branching
|
||||||
integer :: l
|
integer :: l
|
||||||
|
|
||||||
double precision :: w, E_out, w_sum
|
real, allocatable :: elec_coord_new(:,:,:)
|
||||||
|
|
||||||
double precision, allocatable :: elec_coord_new(:,:,:)
|
double precision :: w
|
||||||
|
double precision, allocatable :: E_out(:), w_sum(:)
|
||||||
|
|
||||||
double precision, external :: qmc_ranf
|
double precision, external :: qmc_ranf
|
||||||
|
|
||||||
allocate(elec_coord_new(elec_num+1,3,walk_num))
|
allocate(elec_coord_new(elec_num+1,3,walk_num))
|
||||||
|
allocate(E_out(walk_num), w_sum(walk_num))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Main flow
|
** Main flow
|
||||||
@ -54,30 +56,33 @@ subroutine run
|
|||||||
call abrt(irp_here,'DMC should run with Brownian algorithm')
|
call abrt(irp_here,'DMC should run with Brownian algorithm')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
do iter=1,2
|
do iter=1,1000
|
||||||
call read_coords()
|
! call read_coords()
|
||||||
|
k_new = 1
|
||||||
k_new = 1
|
do k_full=1,walk_num
|
||||||
do while (k_new < walk_num)
|
call pdmc_trajectory(k_full, w, E_out(k_full), w_sum(k_full))
|
||||||
call pdmc_trajectory(k_full, w, E_out, w_sum)
|
|
||||||
write(*,*) 'E', E_out, w_sum
|
|
||||||
k_full = k_full+1
|
|
||||||
if (k_full > walk_num) k_full = 1
|
|
||||||
|
|
||||||
<<branching>>
|
<<branching>>
|
||||||
|
|
||||||
|
if (k_new >= walk_num) then
|
||||||
|
w_sum(k_full+1:) = 0.d0
|
||||||
|
exit
|
||||||
|
end if
|
||||||
end do
|
end do
|
||||||
|
|
||||||
elec_coord_full(1:elec_num+1,1:3,1:walk_num) = &
|
k_new = k_new-1
|
||||||
elec_coord_new(1:elec_num+1,1:3,1:walk_num)
|
elec_coord_full(1:elec_num+1,1:3,1:k_new) = &
|
||||||
|
elec_coord_new(1:elec_num+1,1:3,1:k_new)
|
||||||
|
|
||||||
call write_coords()
|
! call write_coords(k_new)
|
||||||
|
call write_energy(walk_num, E_out, w_sum)
|
||||||
end do
|
end do
|
||||||
|
|
||||||
end subroutine run
|
end subroutine run
|
||||||
|
|
||||||
<<read_coords>>
|
<<read_coords>>
|
||||||
<<write_coords>>
|
<<write_coords>>
|
||||||
|
<<write_energy>>
|
||||||
<<pdmc_trajectory>>
|
<<pdmc_trajectory>>
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
@ -95,16 +100,16 @@ end subroutine run
|
|||||||
! Duplicate walker
|
! Duplicate walker
|
||||||
do l=1,iw
|
do l=1,iw
|
||||||
elec_coord_new(1:elec_num+1,1:3,k_new) = &
|
elec_coord_new(1:elec_num+1,1:3,k_new) = &
|
||||||
elec_coord_full(1:elec_num+1,1:3,k_full)
|
elec_coord(1:elec_num+1,1:3)
|
||||||
k_new = k_new+1
|
k_new = k_new+1
|
||||||
if (k_new > walk_num) exit
|
if (k_new >= walk_num) exit
|
||||||
end do
|
end do
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
* Read/write coordinates
|
* Read/write
|
||||||
|
|
||||||
** Read
|
** Read coordinates
|
||||||
|
|
||||||
Fetch a new set of coordinates for ~walk_num~ walkers from the pool of coordinates.
|
Fetch a new set of coordinates for ~walk_num~ walkers from the pool of coordinates.
|
||||||
|
|
||||||
@ -126,7 +131,7 @@ subroutine read_coords()
|
|||||||
end subroutine read_coords
|
end subroutine read_coords
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Write
|
** Write coordinates
|
||||||
|
|
||||||
Send the current set of coordinates for ~walk_num~ walkers to the pool of coordinates.
|
Send the current set of coordinates for ~walk_num~ walkers to the pool of coordinates.
|
||||||
|
|
||||||
@ -146,6 +151,35 @@ subroutine write_coords()
|
|||||||
end subroutine write_coords
|
end subroutine write_coords
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
** Write energy
|
||||||
|
|
||||||
|
Compute the weighted average over the computed energies.
|
||||||
|
\[
|
||||||
|
E = \frac{\sum_i w_i E_i}{\sum_i w_i}
|
||||||
|
\]
|
||||||
|
|
||||||
|
#+NAME: write_energy
|
||||||
|
#+begin_src f90
|
||||||
|
subroutine write_energy(walk_num_, E_out, w_sum)
|
||||||
|
implicit none
|
||||||
|
integer, intent(in) :: walk_num_
|
||||||
|
double precision, intent(in) :: E_out(walk_num_)
|
||||||
|
double precision, intent(in) :: w_sum(walk_num_)
|
||||||
|
|
||||||
|
integer :: i, k
|
||||||
|
double precision :: E, S
|
||||||
|
|
||||||
|
E = 0.d0
|
||||||
|
S = 0.d0
|
||||||
|
do k=1,walk_num
|
||||||
|
S = S + w_sum(k)
|
||||||
|
E = E + w_sum(k) * E_out(k)
|
||||||
|
end do
|
||||||
|
write(*,*) 'E', E/S, S
|
||||||
|
|
||||||
|
end subroutine write_energy
|
||||||
|
#+end_src
|
||||||
|
|
||||||
* PDMC trajectory
|
* PDMC trajectory
|
||||||
|
|
||||||
Computes a PDMC trajectory until the weight ~w~ is $1/2 < w < 3/2$.
|
Computes a PDMC trajectory until the weight ~w~ is $1/2 < w < 3/2$.
|
||||||
@ -155,7 +189,7 @@ end subroutine write_coords
|
|||||||
\]
|
\]
|
||||||
|
|
||||||
The function returns:
|
The function returns:
|
||||||
- ~pdmc_weight~: the last of all $w_i$
|
- ~w~: the last of all $w_i$
|
||||||
- ~E_out~: The average energy $E$ of the trajectory
|
- ~E_out~: The average energy $E$ of the trajectory
|
||||||
- ~w_sum~: The sum of the weights
|
- ~w_sum~: The sum of the weights
|
||||||
|
|
||||||
@ -167,6 +201,10 @@ end subroutine write_coords
|
|||||||
! If true, continue to make more steps
|
! If true, continue to make more steps
|
||||||
logical :: loop
|
logical :: loop
|
||||||
|
|
||||||
|
! Max number of steps
|
||||||
|
integer :: imax
|
||||||
|
integer, parameter :: nmax=10000
|
||||||
|
|
||||||
! Brownian step variables
|
! Brownian step variables
|
||||||
double precision :: p,q
|
double precision :: p,q
|
||||||
real :: delta_x
|
real :: delta_x
|
||||||
@ -174,6 +212,7 @@ end subroutine write_coords
|
|||||||
|
|
||||||
! Local energies from the past
|
! Local energies from the past
|
||||||
double precision :: E_loc_save(4)
|
double precision :: E_loc_save(4)
|
||||||
|
double precision :: w
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
@ -198,32 +237,41 @@ subroutine pdmc_trajectory(k_full, pdmc_weight, E_out, w_sum)
|
|||||||
pdmc_weight = 1.d0
|
pdmc_weight = 1.d0
|
||||||
loop = .True.
|
loop = .True.
|
||||||
|
|
||||||
do while (loop)
|
do imax = 1, nmax
|
||||||
|
|
||||||
call brownian_step(p,q,accepted,delta_x)
|
call brownian_step(p,q,accepted,delta_x)
|
||||||
|
|
||||||
delta = (9.d0*E_loc+19.d0*E_loc_save(1)-5.d0*E_loc_save(2)+E_loc_save(3))/24.d0
|
! delta = (9.d0*E_loc+19.d0*E_loc_save(1)-5.d0*E_loc_save(2)+E_loc_save(3))/24.d0
|
||||||
|
delta = E_loc
|
||||||
delta = (delta - E_ref)*p
|
delta = (delta - E_ref)*p
|
||||||
|
|
||||||
if (delta >= 0.d0) then
|
if (delta >= 0.d0) then
|
||||||
pdmc_weight = dexp(-dtime_step*delta)
|
w = dexp(-dtime_step*delta)
|
||||||
else
|
else
|
||||||
pdmc_weight = 2.d0-dexp(dtime_step*delta)
|
w = 2.d0-dexp(dtime_step*delta)
|
||||||
endif
|
endif
|
||||||
elec_coord(elec_num+1,1) += p*time_step
|
elec_coord(elec_num+1,1) += p*time_step
|
||||||
elec_coord(elec_num+1,2) = E_loc
|
elec_coord(elec_num+1,2) = E_loc
|
||||||
elec_coord(elec_num+1,3) = pdmc_weight
|
elec_coord(elec_num+1,3) = pdmc_weight
|
||||||
|
if (accepted) then
|
||||||
|
E_loc_save(4) = E_loc_save(3)
|
||||||
|
E_loc_save(3) = E_loc_save(2)
|
||||||
|
E_loc_save(2) = E_loc_save(1)
|
||||||
|
E_loc_save(1) = E_loc
|
||||||
|
endif
|
||||||
|
|
||||||
w_sum = w_sum + pdmc_weight
|
w_sum = w_sum + pdmc_weight
|
||||||
E_out = E_out + pdmc_weight * E_loc
|
E_out = E_out + pdmc_weight * E_loc
|
||||||
|
|
||||||
loop = pdmc_weight > 0.5d0 .or. pdmc_weight < 1.5d0
|
pdmc_weight = pdmc_weight * w
|
||||||
|
|
||||||
|
loop = pdmc_weight > 0.5d0 .and. pdmc_weight < 2.0d0
|
||||||
|
if (.not.loop) exit
|
||||||
|
|
||||||
end do
|
end do
|
||||||
|
|
||||||
elec_coord_full(1:elec_num+1,1:3,k_full) = elec_coord(1:elec_num+1,1:3)
|
E_out = E_out / w_sum
|
||||||
SOFT_TOUCH elec_coord_full
|
|
||||||
|
|
||||||
end subroutine pdmc_trajectory
|
end subroutine pdmc_trajectory
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user