Branch data Line data Source code
1 : : !!****m* ABINIT/m_pred_hmc
2 : : !! NAME
3 : : !! m_pred_hmc
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !! COPYRIGHT
8 : : !! Copyright (C) 2017-2026 ABINIT group (SPr)
9 : : !! This file is distributed under the terms of the
10 : : !! GNU General Public License, see ~abinit/COPYING
11 : : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : : !!
13 : : !! SOURCE
14 : :
15 : : #if defined HAVE_CONFIG_H
16 : : #include "config.h"
17 : : #endif
18 : :
19 : : #include "abi_common.h"
20 : :
21 : : module m_pred_hmc
22 : :
23 : : implicit none
24 : :
25 : : private
26 : : !!***
27 : :
28 : : public :: pred_hmc
29 : : !!***
30 : :
31 : : contains
32 : : !!***
33 : :
34 : : !!****f* ABINIT/pred_hmc
35 : : !! NAME
36 : : !! pred_hmc
37 : : !!
38 : : !! FUNCTION
39 : : !! Hybrid Monte Carlo simulation algorithm. The routine generates a markov
40 : : !! chain of structural configurations (states characterized by ionic positions
41 : : !! and lattice parameters) with probability of observing a certian state
42 : : !! equal to Gibbs statistical weight (exp(-etotal/kT)/Z).
43 : : !!
44 : : !! INPUTS
45 : : !! ab_mover = Data structure containing information about
46 : : !! input variables related to MD, e.g dtion, masses, etc.
47 : : !! hist = history of ionic positions, forces,
48 : : !! itime = index of current iteration
49 : : !! icycle = index of current cycle of the iteration
50 : : !! ntime = total number of iterations
51 : : !! ncycle = total number of cycles
52 : : !! zDEBUG = flag indicating whether to print debug info
53 : : !! iexit = flag indicating finilization of mover loop
54 : : !!
55 : : !! OUTPUT
56 : : !! hist = ionic positions, lattice parameters etc. are updated
57 : : !!
58 : : !! SIDE EFFECTS
59 : : !!
60 : : !! NOTES
61 : : !!
62 : : !! SOURCE
63 : :
64 : 8014 : subroutine pred_hmc(ab_mover,hist,itime,icycle,ntime,ncycle,mttk_vars,zDEBUG,iexit)
65 : :
66 : : use defs_basis
67 : : use m_errors
68 : : use m_abicore
69 : : use m_abimover
70 : : use m_abihist
71 : : use m_io_tools
72 : : use m_hmc
73 : :
74 : : use m_geometry, only : xred2xcart
75 : : use m_numeric_tools, only : uniformrandom
76 : : use m_pred_velverlet, only : pred_velverlet
77 : : use m_pred_isothermal, only : pred_isothermal
78 : :
79 : : !Arguments ------------------------------------
80 : : type(abimover),intent(in) :: ab_mover
81 : : type(abihist),intent(inout) :: hist
82 : : type(mttk_type),intent(inout) :: mttk_vars
83 : : integer,intent(in) :: itime
84 : : integer,intent(in) :: icycle
85 : : integer,intent(in) :: ntime
86 : : integer,intent(in) :: ncycle
87 : : integer,intent(in) :: iexit
88 : : logical,intent(in) :: zDEBUG
89 : :
90 : : !Local variables-------------------------------
91 : : integer,save :: seed ! seed for rnd generator
92 : : integer :: iacc ! dummy integers for loop indexes and acceptance decision flag
93 : : real(dp) :: etotal,epot,ekin,de ! total, potential (electronic), kinetic (ionic) energies and energy difference
94 : : !real(dp) :: mv2tot,factor ! dummies used for rescaling of velocities
95 : 16028 : real(dp) :: xred(3,ab_mover%natom) ! reduced coordinates of all ions
96 : 16028 : real(dp) :: vel(3,ab_mover%natom) ! ionic velocities in Cartesian coordinates
97 : : !real(dp) :: mvtot(3) ! total momentum of the cell used to rescale velocities
98 : : real(dp) :: kbtemp !mtot, ! total ionic mass and target temperature in energy units
99 : : real(dp) :: acell(3) ! lattice parameters
100 : : real(dp) :: rprimd(3,3) ! lattice vectors
101 : :
102 : : real(dp),save :: etotal_hmc_prev,epot_hmc_prev ! total energy of the initial state
103 : : real(dp),save :: strain(3,3),dstrain ! strain tensor
104 : : real(dp),save :: rprimd_original(3,3) ! initial lattice vectors <= itime=1,icycle=1
105 : : real(dp),allocatable,save :: xred_hmc_prev(:,:) ! reduced coordinates of the ions corresponding to the initial state
106 : : real(dp),allocatable,save :: fcart_hmc_prev(:,:) ! reduced coordinates of the ions corresponding to the initial state
107 : :
108 : : logical,save :: strain_updated
109 : : logical,save :: xred_updated
110 : : integer,save :: strain_steps
111 : : logical :: strain_sweep
112 : :
113 : : ! character(len=500) :: message
114 : : ! *************************************************************************
115 : :
116 : : DBG_ENTER("COLL")
117 : :
118 : : ! if (option/=1 .and. option/=2 ) then
119 : : ! write(msg,'(3a,i0)')&
120 : : !& 'The argument option should be 1 or 2,',ch10,&
121 : : !& 'however, option=',option
122 : : ! ABI_BUG(msg)
123 : : ! end if
124 : : !
125 : : ! if (sizein<1) then
126 : : ! write(msg,'(3a,i0)')&
127 : : !& 'The argument sizein should be a positive number,',ch10,&
128 : : !& 'however, sizein=',sizein
129 : : ! ABI_ERROR(msg)
130 : : ! end if
131 : :
132 : : DBG_EXIT("COLL")
133 : :
134 : 8014 : strain_sweep=.FALSE.
135 : :
136 [ + + ]: 8014 : if(iexit/=0)then !icycle=ncycle and itime=ntime
137 [ + - ]: 2 : ABI_SFREE(xred_hmc_prev)
138 [ + - ]: 2 : ABI_SFREE(fcart_hmc_prev)
139 : : !call pred_velverlet(ab_mover,hist,itime,ntime,zDEBUG,iexit,1,icycle,ncycle) ! this is needed to deallocate vel_prev array allocated in pred_velverlet
140 : 2 : call pred_isothermal(ab_mover,hist,icycle,mttk_vars,ncycle,zDEBUG,iexit)
141 : : return
142 : : end if
143 : :
144 : :
145 : : !get current values of ionic positions and cell geometry and set up the target temperature
146 : 8012 : call hist2var(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
147 : :
148 [ + + + + ]: 34569932 : vel(:,:) = hist%vel(:,:,hist%ihist) ! velocities of all ions, not needed in reality
149 : 8012 : epot = hist%etot(hist%ihist) ! electronic sub-system energy, not needed
150 : 8012 : ekin = hist%ekin(hist%ihist) ! kinetic energy, not needed
151 : :
152 : 8012 : kbtemp=(ab_mover%mdtemp(1)+((ab_mover%mdtemp(2)-ab_mover%mdtemp(1))/dble(ntime-1))*(itime-1))*kb_HaK ! correct temperature taking into account the possible heating/cooling
153 : :
154 [ + + + + ]: 8012 : if(itime==1.and.icycle==1) then
155 [ - + ]: 2 : ABI_SFREE(xred_hmc_prev)
156 [ - + ]: 2 : ABI_SFREE(fcart_hmc_prev)
157 : :
158 [ - + + - : 6 : ABI_MALLOC(xred_hmc_prev,(3,ab_mover%natom))
+ - + - -
+ - + -
+ ]
159 [ - + + - : 4 : ABI_MALLOC(fcart_hmc_prev,(3,ab_mover%natom))
- + - + -
+ ]
160 : :
161 : 2 : seed=-239
162 : :
163 : 2 : rprimd_original(:,:)=rprimd(:,:)
164 : 2 : strain(:,:) = 0.0_dp
165 : 2 : strain_steps=0
166 : 2 : dstrain=0.001
167 : :
168 : 2 : strain_updated=.FALSE.
169 : 2 : xred_updated=.FALSE.
170 : :
171 : 2 : etotal_hmc_prev = zero
172 : 2 : epot_hmc_prev = zero
173 : :
174 : : end if
175 : :
176 : :
177 : : !IN CASE THE SWEEP IS FOR UPDATE OF ATOMIC COORDINATES************************************************
178 : : !if(.NOT.strain_sweep) then
179 : :
180 : : ! *---->*
181 : : ! 1 n
182 : :
183 [ + + ]: 8012 : if (icycle==1) then
184 : :
185 [ + + ]: 204 : if(itime==1) then
186 : 2 : iacc=1
187 : 2 : etotal = epot + ekin
188 : 2 : de=zero
189 : : else
190 : 202 : etotal = epot + ekin
191 : 202 : de = etotal - etotal_hmc_prev
192 : 202 : call metropolis_check(seed,de,kbtemp,iacc)
193 : : !DEBUG
194 : : ! write(std_out,*)' m_pred_hmc, after metropolis_check : seed,de,kbtemp,iacc=',seed,de,kbtemp,iacc
195 : : !ENDDEBUG
196 : : end if
197 : :
198 [ - + ]: 204 : if(iacc==0)then !in case the new state is not accepted, then roll back the coordinates and energies
199 [ # # # # ]: 0 : xred(:,:)= xred_hmc_prev(:,:)
200 : 0 : epot = epot_hmc_prev
201 [ # # # # ]: 0 : hist%fcart(:,:,hist%ihist) = fcart_hmc_prev(:,:)
202 : : else
203 [ + + + + ]: 864844 : xred_hmc_prev(:,:)=xred(:,:)
204 [ + + + + ]: 864844 : fcart_hmc_prev(:,:) = hist%fcart(:,:,hist%ihist)
205 : 204 : epot_hmc_prev = epot !update reference potential energy
206 : : end if
207 : :
208 : : ! write(message,'(2a,i7,a,i2,a,E24.16,a,E24.16,a,E24.16)') ch10,' HMC Sweep => ',itime,' iacc= ', iacc,' epot= ',&
209 : : !& epot,' ekin=',ekin,' de=',de
210 : : ! call wrtout(ab_out,message,'COLL')
211 : : ! call wrtout(std_out,message,'COLL')
212 : :
213 : : !call generate_random_velocities(ab_mover,kbtemp,seed,vel,ekin) ! this routine also computes the new kinetic energy
214 : : !hist%vel(:,:,hist%ihist)=vel(:,:)
215 [ + + + + ]: 864844 : hist%vel(:,:,hist%ihist)=0
216 : : !call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
217 : : !etotal_hmc_prev=epot+ekin ! either old or current potential energy + new kinetic energy
218 : :
219 : : !call pred_velverlet(ab_mover,hist,itime,ntime,zDEBUG,iexit,1,icycle,ncycle) ! 1 is indicating that velverlet is called from hmc routine
220 : 204 : call pred_isothermal(ab_mover,hist,icycle,mttk_vars,ncycle,zDEBUG,iexit)
221 : :
222 [ + - + - ]: 7808 : elseif(icycle > 1 .and. icycle <= ncycle)then !icycle/=1
223 : :
224 : : !call pred_velverlet(ab_mover,hist,itime,ntime,zDEBUG,iexit,1,icycle,ncycle) ! 1 is indicating that velverlet is called from hmc routine
225 : 7808 : call pred_isothermal(ab_mover,hist,icycle,mttk_vars,ncycle,zDEBUG,iexit)
226 : :
227 : : !end if
228 : : !END OF ATOMIC COORDINATES SWEEP************************************************
229 : :
230 : : ! else if(icycle>ncycle) then ! strain update
231 : : ! strain_updated = .TRUE.
232 : : ! strain_steps = strain_steps + 1
233 : : !! Metropolis update of lattice vectors and parameters in case optcell/=0
234 : : ! if(icycle==ncycle+1.and.xred_updated) then
235 : : ! !save rprimd_hmc_prev and total electronic energy etotal_hmc_prev
236 : : ! call hist2var(acell_hmc_prev,hist,ab_mover%natom,rprimd_hmc_prev,xred,zDEBUG)
237 : : ! etotal_hmc_prev = hist%etot(hist%ihist)
238 : : ! strain_hmc_prev(:,:) = strain(:,:)
239 : : !
240 : : ! select case (ab_mover%optcell)
241 : : ! case (1) !volume optimization only
242 : : ! acell(:)=acell(:)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
243 : : ! case (2,3,7,8,9) !full geometry optimization
244 : : ! !suggest new strain tensor values
245 : : ! do ii=1,3
246 : : ! do jj=ii,3
247 : : ! strain(ii,jj) = strain(ii,jj)+ 2.0_dp*dstrain*(uniformrandom(seed)-0.5_dp)
248 : : ! strain(jj,ii) = strain(ii,jj)
249 : : ! enddo
250 : : ! enddo
251 : : ! if(ab_mover%optcell==3) then !eliminate volume change if optcell==3
252 : : ! do ii=1,3
253 : : ! strain(ii,ii) = strain(ii,ii) -(strain(1,1)+strain(2,2)+strain(3,3))
254 : : ! enddo
255 : : ! endif
256 : : ! do jj=1,3 ! sum over three lattice vectors
257 : : ! do ii=1,3 ! sum over Cart components
258 : : ! rprimd(ii,jj)=rprimd_original(ii,jj)+&
259 : : !& rprimd_original(1,jj)*strain(ii,1)+&
260 : : !& rprimd_original(2,jj)*strain(ii,2)+&
261 : : !& rprimd_original(3,jj)*strain(ii,3)
262 : : ! enddo
263 : : ! enddo
264 : : ! if(ab_mover%optcell==7) then
265 : : ! rprimd(:,1)=rprimd_original(:,1)
266 : : ! else if (ab_mover%optcell==8) then
267 : : ! rprimd(:,2)=rprimd_original(:,2)
268 : : ! else if (ab_mover%optcell==9) then
269 : : ! rprimd(:,3)=rprimd_original(:,3)
270 : : ! endif
271 : : ! case(4)
272 : : ! acell(1)=acell(1)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
273 : : ! case(5)
274 : : ! acell(2)=acell(2)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
275 : : ! case(6)
276 : : ! acell(3)=acell(3)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
277 : : ! !case default
278 : : ! ! write(message,"(a,i0)") "Wrong value of optcell: ",ab_mover%optcell
279 : : ! ! ABI_ERROR(message)
280 : : ! end select
281 : : !
282 : : ! !update the new suggested rprimd and or acell in the history record
283 : : ! hist%ihist=abihist_findIndex(hist,+1)
284 : : ! call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
285 : : ! else
286 : : !
287 : : ! etotal = hist%etot(hist%ihist)
288 : : ! de = etotal - etotal_hmc_prev
289 : : !
290 : : ! iacc=0
291 : : ! rnd=uniformrandom(seed)
292 : : ! if(de<0)then
293 : : ! iacc=1
294 : : ! else
295 : : ! if(exp(-de/kbtemp)>rnd)then
296 : : ! iacc=1
297 : : ! end if
298 : : ! end if
299 : : !
300 : : ! if(iacc==0) then
301 : : ! strain(:,:)=strain_hmc_prev(:,:)
302 : : ! acell(:)=acell_hmc_prev(:)
303 : : ! else
304 : : ! call hist2var(acell_hmc_prev,hist,ab_mover%natom,rprimd_hmc_prev,xred,zDEBUG)
305 : : ! strain_hmc_prev(:,:) = strain(:,:)
306 : : ! etotal_hmc_prev=etotal
307 : : ! endif
308 : : !
309 : : ! !suggest new acell/rprimd values depending on the optcell value
310 : : ! select case (ab_mover%optcell)
311 : : ! case (1) !volume optimization only
312 : : ! acell(:)=acell(:)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
313 : : ! case (2,3,7,8,9) !full geometry optimization
314 : : ! !suggest new strain tensor values
315 : : ! do ii=1,3
316 : : ! do jj=ii,3
317 : : ! strain(ii,jj) = strain(ii,jj)+ 2.0_dp*dstrain*(uniformrandom(seed)-0.5_dp)
318 : : ! strain(jj,ii) = strain(ii,jj)
319 : : ! enddo
320 : : ! enddo
321 : : ! if(ab_mover%optcell==3) then !eliminate volume change if optcell==3
322 : : ! do ii=1,3
323 : : ! strain(ii,ii) = strain(ii,ii) -(strain(1,1)+strain(2,2)+strain(3,3))
324 : : ! enddo
325 : : ! endif
326 : : ! do jj=1,3 ! sum over three lattice vectors
327 : : ! do ii=1,3 ! sum over Cart components
328 : : ! rprimd(ii,jj)=rprimd_original(ii,jj)+&
329 : : !& rprimd_original(1,jj)*strain(ii,1)+&
330 : : !& rprimd_original(2,jj)*strain(ii,2)+&
331 : : !& rprimd_original(3,jj)*strain(ii,3)
332 : : ! enddo
333 : : ! enddo
334 : : ! if(ab_mover%optcell==7) then
335 : : ! rprimd(:,1)=rprimd_original(:,1)
336 : : ! else if (ab_mover%optcell==8) then
337 : : ! rprimd(:,2)=rprimd_original(:,2)
338 : : ! else if (ab_mover%optcell==9) then
339 : : ! rprimd(:,3)=rprimd_original(:,3)
340 : : ! endif
341 : : ! case(4)
342 : : ! acell(1)=acell(1)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
343 : : ! case(5)
344 : : ! acell(2)=acell(2)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
345 : : ! case(6)
346 : : ! acell(3)=acell(3)*(1.0_dp+dstrain*2.0_dp*(uniformrandom(seed)-0.5_dp))
347 : : ! case default
348 : : ! ! write(message,"(a,i0)") "Wrong value of optcell: ",ab_mover%optcell
349 : : ! ! ABI_ERROR(message)
350 : : ! end select
351 : : !
352 : : ! !update the new suggested rprimd/acell in the history record
353 : : ! hist%ihist=abihist_findIndex(hist,+1)
354 : : ! call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
355 : : !
356 : : ! endif
357 : :
358 : : end if
359 : :
360 : 8014 : end subroutine pred_hmc
361 : : !!***
362 : :
363 : : end module m_pred_hmc
364 : : !!***
|