Line data Source code
1 : !!****m* ABINIT/m_pred_velverlet
2 : !! NAME
3 : !! m_pred_velverlet
4 : !!
5 : !! FUNCTION
6 : !!
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2017-2026 ABINIT group (SPr)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : module m_pred_velverlet
23 :
24 : use defs_basis
25 : use m_errors
26 : use m_abicore
27 : use m_abimover
28 : use m_abihist
29 :
30 : use m_geometry, only : xcart2xred, xred2xcart
31 :
32 : implicit none
33 :
34 : private
35 : !!***
36 :
37 : public :: pred_velverlet
38 : !!***
39 :
40 : contains
41 : !!***
42 :
43 : !!****f* ABINIT/pred_velverlet
44 : !! NAME
45 : !! pred_velverlet
46 : !!
47 : !! FUNCTION
48 : !! Velocity Verlet (VV) predictor of ionic positions (ionmov = 24).
49 : !! In constrast to Verlet algorithm, Velocity Verlet is a
50 : !! SYMPLECTIC integrator (for small enough step sizes "dtion",
51 : !! it better conserves the total energy and time-reversibility).
52 : !! VV is a second order integration scheme that requires a single
53 : !! evaluatoin of forces per time step. These properties make VV
54 : !! a good candidate integrator for use in Hybrid Monte Carlo simulation scheme.
55 : !!
56 : !! INPUTS
57 : !! ab_mover = Data structure containing information about
58 : !! input variables related to MD, e.g dtion, masses, etc.
59 : !! hist = history of ionic positions, forces,
60 : !! itime = index of current time step
61 : !! ntime = total number of time steps
62 : !! zDEBUG = flag indicating whether to print debug info
63 : !! iexit = flag indicating finilization of mover loop
64 : !! hmcflag = optional argument indicating whether the predictor is called from the Hybrid Monte Carlo (HMC) routine
65 : !! icycle = if hmcflag==1, then icycle providing information about number of HMC cycle is needed
66 : !! ncycle = if hmcflag==1, then ncycle provides the total number of cycles within one HMC iteration
67 : !!
68 : !! OUTPUT
69 : !! hist = history of ionic positions, forces etc. is updated
70 : !!
71 : !! SIDE EFFECTS
72 : !!
73 : !! NOTES
74 : !!
75 : !! This routine can be used either to simulate NVE molecular dynamics (ionmov = 24) or
76 : !! is called from pred_hmc routine (ionmov = 25) to perform updates of ionic positions
77 : !! in Hybrid Monte Carlo iterations.
78 : !!
79 : !! SOURCE
80 :
81 10 : subroutine pred_velverlet(ab_mover,hist,itime,ntime,zDEBUG,iexit,hmcflag,icycle,ncycle)
82 :
83 : !Arguments ------------------------------------
84 : type(abimover),intent(in) :: ab_mover
85 : type(abihist),intent(inout) :: hist
86 : integer,intent(in) :: itime
87 : integer,intent(in) :: ntime
88 : integer,intent(in) :: iexit
89 : logical,intent(in) :: zDEBUG
90 : integer,intent(in),optional :: hmcflag
91 : integer,intent(in),optional :: icycle
92 : integer,intent(in),optional :: ncycle
93 :
94 : !Local variables-------------------------------
95 :
96 : integer :: ii,jj ! dummy integers for loop indexes
97 : real(dp) :: epot,ekin !,ekin_tmp ! potential (electronic), kinetic (ionic) energies
98 20 : real(dp) :: xcart(3,ab_mover%natom) ! Cartesian coordinates of all ions
99 20 : real(dp) :: xred(3,ab_mover%natom) ! reduced coordinates of all ions
100 20 : real(dp) :: vel(3,ab_mover%natom) ! ionic velocities in Cartesian coordinates
101 1 : real(dp) :: fcart(3,ab_mover%natom),gred(3,ab_mover%natom) ! cartesian forces, and gradient in reduced coordinates
102 : !real(dp) :: factor ! factor, indicating change of time step at last iteration
103 : integer :: hmcflag_
104 : integer :: icycle_
105 : integer :: ncycle_
106 :
107 : real(dp) :: acell(3) ! lattice parameters
108 : real(dp) :: rprimd(3,3) ! lattice vectors
109 : real(dp),allocatable,save :: vel_prev(:,:) ! velocities at the end of each time step (half time step ahead of coordinates)
110 :
111 : !***************************************************************************
112 : !Beginning of executable session
113 : !***************************************************************************
114 :
115 : DBG_ENTER("COLL")
116 :
117 : ABI_UNUSED((/ntime/))
118 :
119 10 : hmcflag_=0
120 10 : if(present(hmcflag))then
121 0 : hmcflag_=hmcflag
122 : end if
123 :
124 10 : icycle_ =0
125 10 : if(present(icycle))then
126 0 : icycle_=icycle
127 : end if
128 :
129 10 : ncycle_ =0
130 : if(present(ncycle))then
131 : ncycle_=ncycle
132 : end if
133 :
134 :
135 10 : if(iexit/=0)then
136 1 : ABI_SFREE(vel_prev)
137 : return
138 : end if
139 :
140 9 : if((hmcflag_==0.and.itime==1).or.(hmcflag_==1.and.icycle_==1))then
141 1 : ABI_SFREE(vel_prev)
142 3 : ABI_MALLOC(vel_prev,(3,ab_mover%natom))
143 : end if
144 :
145 : ! Start preparation for velocity verlet, get information about current ionic positions, forces, velocities, etc.
146 :
147 9 : call hist2var(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
148 9 : call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
149 81 : fcart(:,:) = hist%fcart(:,:,hist%ihist) ! forces in Cartesian coordinates
150 81 : vel(:,:) = hist%vel(:,:,hist%ihist) ! velocities of all ions, not needed in reality
151 9 : epot = hist%etot(hist%ihist) ! electronic sub-system energy, not needed
152 9 : ekin = hist%ekin(hist%ihist) ! kinetic energy, not needed
153 :
154 :
155 9 : if(zDEBUG)then
156 0 : write (std_out,*) 'velverlet step',itime
157 0 : write (std_out,*) 'fcart:'
158 0 : do ii=1,3
159 0 : write (std_out,*) fcart(ii,:)
160 : end do
161 0 : write (std_out,*) 'gred:'
162 0 : do ii=1,3
163 0 : write (std_out,*) gred(ii,:)
164 : end do
165 0 : write (std_out,*) 'xcart:'
166 0 : do ii=1,3
167 0 : write (std_out,*) xcart(ii,:)
168 : end do
169 0 : write (std_out,*) 'vel:'
170 0 : do ii=1,3
171 0 : write (std_out,*) vel(ii,:)
172 : end do
173 : end if
174 :
175 :
176 9 : if((hmcflag_==0.and.itime==1).or.(hmcflag_==1.and.icycle_==1))then
177 :
178 : !the following breakdown of single time step in two halfs is needed for initialization.
179 : !half step velocities "vel_prev" are saved to be used in the next iteration
180 : !the velocities "vel" are only used to estimate kinetic energy at correct time instances
181 3 : do ii=1,ab_mover%natom ! propagate velocities half time step forward
182 9 : do jj=1,3
183 8 : vel_prev(jj,ii) = vel(jj,ii) + 0.5_dp * ab_mover%dtion*fcart(jj,ii)/ab_mover%amass(ii)
184 : end do
185 : end do
186 :
187 : ! propagate velocities half time step forward
188 3 : do ii=1,ab_mover%natom
189 9 : do jj=1,3
190 8 : vel(jj,ii) = vel_prev(jj,ii) + 0.5_dp * ab_mover%dtion*fcart(jj,ii)/ab_mover%amass(ii)
191 : end do
192 : end do
193 : ! use half-step behind velocity values to propagate coordinates one time step forward!!!!
194 3 : do ii=1,ab_mover%natom
195 9 : do jj=1,3
196 8 : xcart(jj,ii) = xcart(jj,ii) + ab_mover%dtion*vel_prev(jj,ii)
197 : end do
198 : end do
199 : ! now, at this 1st iteration, "vel_prev" correspond to a time instance half-step behind
200 : ! that of "xcart"
201 :
202 : else
203 :
204 : !at this moment "vel_prev" is behind "xcart" by half of a time step
205 : !(saved from the previous iteration) and these are the velocity values to be propagated
206 : !using forces that are evaluated at the same time instance as xcart
207 24 : do ii=1,ab_mover%natom ! propagate velocities one time step forward
208 72 : do jj=1,3
209 64 : vel_prev(jj,ii) = vel_prev(jj,ii) + ab_mover%dtion*fcart(jj,ii)/ab_mover%amass(ii)
210 : end do
211 : end do
212 : !now, the "vel_prev" velocities are half of a time step ahead and can be used to propagate xcart
213 :
214 : !if((hmcflag_==0.and.itime==ntime-1).or.(hmcflag_==1.and.icycle_==ncycle_-1))then
215 : ! factor=0.5_dp
216 : !else
217 : ! factor=one
218 : !end if
219 :
220 24 : do ii=1,ab_mover%natom ! propagate coordinates
221 72 : do jj=1,3
222 64 : xcart(jj,ii) = xcart(jj,ii) + ab_mover%dtion*vel_prev(jj,ii)
223 : !xcart(jj,ii) = xcart(jj,ii) + factor*ab_mover%dtion*vel_prev(jj,ii)
224 : end do
225 : end do
226 : !to estimate kinetic energy at the same time instance as the potential (electronic sub-system) energy
227 : !propagate "vel" another half-time forward (these values are not to be used in the next time-step)
228 24 : do ii=1,ab_mover%natom ! propagate velocities half time step forward
229 72 : do jj=1,3
230 64 : vel(jj,ii) = vel_prev(jj,ii) + 0.5_dp * ab_mover%dtion*fcart(jj,ii)/ab_mover%amass(ii)
231 : !vel(jj,ii) = vel_prev(jj,ii) +(factor-0.5_dp) * ab_mover%dtion*fcart(jj,ii)/ab_mover%amass(ii)
232 : end do
233 : end do
234 :
235 : ekin=0.0
236 : do ii=1,ab_mover%natom
237 : do jj=1,3
238 : ekin=ekin+0.5_dp*ab_mover%amass(ii)*vel(jj,ii)**2
239 : end do
240 : end do
241 : !ekin_tmp=0.0
242 : !do ii=1,ab_mover%natom
243 : ! do jj=1,3
244 : ! ekin_tmp=ekin_tmp+0.5_dp*ab_mover%amass(ii)*vel_prev(jj,ii)**2
245 : ! end do
246 : !end do
247 : !write(238,*) itime,icycle,ekin_tmp,ekin,epot,factor
248 :
249 : end if
250 :
251 : !Convert new xcart to xred to set correct output values
252 : !Update the history with the new coordinates, velocities, etc.
253 :
254 : !Increase indexes
255 9 : hist%ihist=abihist_findIndex(hist,+1)
256 :
257 9 : call xcart2xred(ab_mover%natom,rprimd,xcart,xred)
258 9 : call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
259 :
260 81 : hist%vel(:,:,hist%ihist)=vel(:,:)
261 9 : hist%time(hist%ihist)=real(itime,kind=dp)*ab_mover%dtion
262 :
263 : DBG_EXIT("COLL")
264 :
265 : end subroutine pred_velverlet
266 : !!***
267 :
268 : end module m_pred_velverlet
269 : !!***
|