Branch data Line data Source code
1 : : !!****m* ABINIT/m_pred_langevin
2 : : !! NAME
3 : : !! m_pred_langevin
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !! COPYRIGHT
8 : : !! Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, JCC, SE)
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_langevin
22 : :
23 : : use defs_basis
24 : : use m_abicore
25 : : use m_abimover
26 : : use m_abihist
27 : :
28 : : use m_numeric_tools, only : uniformrandom
29 : : use m_geometry, only : xcart2xred, xred2xcart, metric
30 : : use m_results_gs , only : results_gs_type
31 : :
32 : : implicit none
33 : :
34 : : private
35 : : !!***
36 : :
37 : : public :: pred_langevin
38 : : !!***
39 : :
40 : : contains
41 : : !!***
42 : :
43 : : !!****f* ABINIT/pred_langevin
44 : : !! NAME
45 : : !! pred_langevin
46 : : !!
47 : : !! FUNCTION
48 : : !! Ionmov predictors (9) Langevin dynamics algorithm
49 : : !!
50 : : !! IONMOV 9:
51 : : !! Uses a Langevin dynamics algorithm :
52 : : !! see J. Chelikowsky, J. Phys. D : Appl Phys. 33(2000)R33 [[cite:Chelikowsky2000]]
53 : : !!
54 : : !! INPUTS
55 : : !! ab_mover <type(abimover)> : Datatype with all the information
56 : : !! needed by the preditor
57 : : !! itime : Index of the present iteration
58 : : !! ntime : Maximal number of iterations
59 : : !! icycle : Index of the present cycle
60 : : !! ncycle : Maximal number of cycles
61 : : !! zDEBUG : if true print some debugging information
62 : : !!
63 : : !! OUTPUT
64 : : !!
65 : : !! SIDE EFFECTS
66 : : !! hist <type(abihist)> : History of positions,forces acell, rprimd, stresses
67 : : !!
68 : : !! SOURCE
69 : :
70 : 20 : subroutine pred_langevin(ab_mover,hist,icycle,itime,ncycle,ntime,zDEBUG,iexit,skipcycle)
71 : :
72 : : !Arguments ------------------------------------
73 : : !scalars
74 : : type(abimover),intent(in) :: ab_mover
75 : : type(abihist),intent(inout) :: hist
76 : : integer,intent(in) :: itime
77 : : integer,intent(in) :: ntime
78 : : integer,intent(in) :: iexit
79 : : integer,intent(in) :: icycle
80 : : integer,intent(inout) :: ncycle
81 : : logical,intent(in) :: zDEBUG
82 : : logical,intent(out) :: skipcycle
83 : :
84 : : !Local variables-------------------------------
85 : : !scalars
86 : : integer :: ii,kk,iatom,idim,iatom1,iatom2,itypat,idum=5,ihist_prev,mcfac
87 : : real(dp) :: ucvol,ucvol_next
88 : : real(dp),parameter :: v2tol=tol8
89 : : real(dp) :: etotal,rescale_vel,ran_num1,ran_num2
90 : : real(dp) :: ktemp,dist,distx,disty,distz,maxp1,maxp2,v2nose
91 : : real(dp) :: sig_gauss,delxi
92 : : logical :: jump_end_of_cycle=.FALSE.
93 : : character(len=5000) :: message
94 : : !arrays
95 : 20 : integer,allocatable :: imax_perm(:)
96 : : real(dp),allocatable,save :: max_perm(:),pot_perm(:)
97 : : real(dp),allocatable,save :: ran_force(:,:),lang_force(:,:)
98 : : real(dp),allocatable,save :: fcart_mold(:,:),fcart_m(:,:)
99 : :
100 : : real(dp) :: acell(3),acell_next(3)
101 : : real(dp) :: rprim(3,3),rprimd(3,3),rprimd_next(3,3),rprim_next(3,3)
102 : : real(dp) :: gprimd(3,3),gmet(3,3),rmet(3,3)
103 : 40 : real(dp) :: fcart(3,ab_mover%natom)
104 : 40 : real(dp) :: xcart(3,ab_mover%natom),xcart_next(3,ab_mover%natom)
105 : 40 : real(dp) :: xred(3,ab_mover%natom),xred_next(3,ab_mover%natom)
106 : 20 : real(dp) :: vel(3,ab_mover%natom)
107 : : real(dp) :: strten(6)
108 : :
109 : : !***************************************************************************
110 : : !Beginning of executable session
111 : : !***************************************************************************
112 : :
113 [ + + ]: 20 : if(iexit/=0)then
114 [ + - ]: 2 : ABI_SFREE(pot_perm)
115 [ + - ]: 2 : ABI_SFREE(max_perm)
116 : : ABI_SFREE(imax_perm)
117 [ + - ]: 2 : ABI_SFREE(ran_force)
118 [ + - ]: 2 : ABI_SFREE(lang_force)
119 [ + - ]: 2 : ABI_SFREE(fcart_mold)
120 [ + - ]: 2 : ABI_SFREE(fcart_m)
121 : : return
122 : : end if
123 : :
124 : 18 : jump_end_of_cycle=.FALSE.
125 : :
126 : : !write(std_out,*) 'langevin 02',jump_end_of_cycle
127 : : !##########################################################
128 : : !### 02. Allocate the arrays
129 : : !### These arrays could be allocated from a previus
130 : : !### dataset that exit before itime==ntime
131 : :
132 [ + + ]: 18 : if(itime==1)then
133 [ - + ]: 2 : ABI_SFREE(pot_perm)
134 [ - + ]: 2 : ABI_SFREE(max_perm)
135 : : ABI_SFREE(imax_perm)
136 [ - + ]: 2 : ABI_SFREE(ran_force)
137 [ - + ]: 2 : ABI_SFREE(lang_force)
138 [ - + ]: 2 : ABI_SFREE(fcart_mold)
139 [ - + ]: 2 : ABI_SFREE(fcart_m)
140 : : end if
141 : :
142 [ + + ]: 18 : if (.not.allocated(pot_perm)) then
143 [ - + + - : 6 : ABI_MALLOC(pot_perm,(ab_mover%natom))
+ - + - -
+ - + -
+ ]
144 : : end if
145 [ + + ]: 18 : if (.not.allocated(max_perm)) then
146 [ - + + - : 6 : ABI_MALLOC(max_perm,(ab_mover%ntypat))
+ - + - -
+ - + -
+ ]
147 : : end if
148 : : if (.not.allocated(imax_perm)) then
149 [ - + + - : 54 : ABI_MALLOC(imax_perm,(ab_mover%ntypat))
+ - + - -
+ - + ]
150 : : end if
151 [ + + ]: 18 : if (.not.allocated(ran_force)) then
152 [ - + + - : 6 : ABI_MALLOC(ran_force,(3,ab_mover%natom))
+ - + - -
+ - + -
+ ]
153 : : end if
154 [ + + ]: 18 : if (.not.allocated(lang_force)) then
155 [ - + + - : 6 : ABI_MALLOC(lang_force,(3,ab_mover%natom))
+ - + - -
+ - + -
+ ]
156 : : end if
157 [ + + ]: 18 : if (.not.allocated(fcart_mold)) then
158 [ - + + - : 6 : ABI_MALLOC(fcart_mold,(3,ab_mover%natom))
+ - + - -
+ - + -
+ ]
159 : : end if
160 [ + + ]: 18 : if (.not.allocated(fcart_m)) then
161 [ - + + - : 6 : ABI_MALLOC(fcart_m,(3,ab_mover%natom))
+ - + - -
+ - + -
+ ]
162 : : end if
163 : :
164 : : !write(std_out,*) 'langevin 03',jump_end_of_cycle
165 : : !##########################################################
166 : : !### 03. Obtain the present values from the history
167 : :
168 : 18 : call hist2var(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
169 : :
170 [ + + + + ]: 198 : fcart(:,:)=hist%fcart(:,:,hist%ihist)
171 [ + + ]: 126 : strten(:) =hist%strten(:,hist%ihist)
172 [ + + + + ]: 198 : vel(:,:) =hist%vel(:,:,hist%ihist)
173 : 18 : etotal =hist%etot(hist%ihist)
174 : :
175 : 18 : call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
176 [ + + ]: 72 : do ii=1,3
177 [ + + ]: 234 : rprim(ii,1:3)=rprimd(ii,1:3)/acell(1:3)
178 : : end do
179 : 18 : call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
180 : :
181 : : !write(std_out,*) 'langevin 04',jump_end_of_cycle
182 : : !##########################################################
183 : : !### 04. Compute the next values (Only for the first cycle)
184 : :
185 [ + - ]: 18 : if (icycle==1) then
186 : :
187 : : ! The temperature is linear between initial and final values
188 : : ! It is here converted from Kelvin to Hartree (kb_HaK)
189 : 18 : ktemp=(ab_mover%mdtemp(1)+((ab_mover%mdtemp(2)-ab_mover%mdtemp(1))/dble(ntime-1))*(itime-1))*kb_HaK
190 : : ! write(std_out,*) 'KTEMP=',ktemp
191 : : ! write(std_out,*) 'MDITEMP=',ab_mover%mdtemp(1)
192 : : ! write(std_out,*) 'MDFTEMP=',ab_mover%mdtemp(2)
193 : : ! write(std_out,*) 'DELAYPERM=',ab_mover%delayperm
194 : :
195 : :
196 : : ! %%% LANGEVIN DYNAMICS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197 : :
198 : : ! 1. Next values are the present ones
199 : 18 : acell_next(:)=acell(:)
200 : 18 : ucvol_next=ucvol
201 : 18 : rprim_next(:,:)=rprim(:,:)
202 : 18 : rprimd_next(:,:)=rprimd(:,:)
203 : :
204 [ - + ]: 18 : if (zDEBUG) then
205 : 0 : write (std_out,*) '1. Next values are the present ones'
206 : 0 : write(std_out,*) 'RPRIMD'
207 [ # # ]: 0 : do kk=1,3
208 : 0 : write(std_out,*) rprimd(:,kk)
209 : : end do
210 : 0 : write(std_out,*) 'RPRIM'
211 [ # # ]: 0 : do kk=1,3
212 : 0 : write(std_out,*) rprim(:,kk)
213 : : end do
214 : 0 : write(std_out,*) 'ACELL'
215 : 0 : write(std_out,*) acell(:)
216 : : end if
217 : :
218 [ + + ]: 18 : if(itime==1)then
219 : :
220 : : ! 2. Compute twice the kinetic energy of the system, called v2nose
221 : 2 : v2nose=0.0_dp
222 [ + + ]: 7 : do iatom=1,ab_mover%natom
223 [ + + ]: 22 : do idim=1,3
224 : 20 : v2nose=v2nose+vel(idim,iatom)*vel(idim,iatom)*ab_mover%amass(iatom)
225 : : end do
226 : : end do
227 [ - + ]: 2 : if (zDEBUG) then
228 : 0 : write (std_out,*) '2. Compute twice the kinetic energy of the system, called v2nose'
229 : 0 : write (std_out,*) 'V2NOSE=',v2nose
230 : : end if
231 : :
232 : : ! 3. If there is no kinetic energy, use random numbers
233 [ + - ]: 2 : if (v2nose<=v2tol) then
234 : 2 : v2nose=0.0_dp
235 [ + + ]: 7 : do iatom=1,ab_mover%natom
236 [ + + ]: 22 : do idim=1,3
237 : : ! uniformrandom returns a uniform random deviate between 0.0 and 1.0
238 : : ! if it were always 0 or 1, then the following expression
239 : : ! would give the requested temperature
240 : 15 : vel(idim,iatom)=(1.0_dp-2.0_dp*uniformrandom(idum))*sqrt(ktemp/ab_mover%amass(iatom))
241 : : ! Recompute v2nose
242 : 20 : v2nose=v2nose+vel(idim,iatom)*vel(idim,iatom)*ab_mover%amass(iatom)
243 : : end do
244 : : end do
245 : : end if
246 : :
247 [ - + ]: 2 : if (zDEBUG) then
248 : 0 : write (std_out,*) '3. If there is no kinetic energy, use random numbers'
249 : 0 : write (std_out,*) 'VEL'
250 [ # # ]: 0 : do kk=1,ab_mover%natom
251 : 0 : write (std_out,*) vel(:,kk)
252 : : end do
253 : 0 : write (std_out,*) 'V2NOSE=',v2nose
254 : : end if
255 : :
256 : :
257 : : ! Now, rescale the velocities to give the proper temperature
258 : 2 : rescale_vel=sqrt(3.0_dp*ab_mover%natom*(ab_mover%mdtemp(1))*kb_HaK/v2nose)
259 [ + + + + ]: 22 : vel(:,:)=vel(:,:)*rescale_vel
260 : : ! Recompute v2nose with the rescaled velocities
261 : 2 : v2nose=0.0_dp
262 [ + + ]: 7 : do iatom=1,ab_mover%natom
263 [ + + ]: 22 : do idim=1,3
264 : 20 : v2nose=v2nose+vel(idim,iatom)*vel(idim,iatom)*ab_mover%amass(iatom)
265 : : end do
266 : : end do
267 : : write(message, '(a)' )&
268 : 2 : & ' Rescaling or initializing velocities to initial temperature'
269 : 2 : call wrtout(ab_out,message,'COLL')
270 : 2 : call wrtout(std_out,message,'COLL')
271 : : write(message, '(a,D12.5,a,D12.5)' )&
272 : 2 : & ' --- Scaling factor : ',rescale_vel,' Asked T (K) ',ab_mover%mdtemp(1)
273 : 2 : call wrtout(ab_out,message,'COLL')
274 : 2 : call wrtout(std_out,message,'COLL')
275 : : write(message, '(a,D12.5)' )&
276 : 2 : & ' --- Effective temperature',v2nose/3.0_dp/(kb_HaK*ab_mover%natom)
277 : 2 : call wrtout(ab_out,message,'COLL')
278 : 2 : call wrtout(std_out,message,'COLL')
279 : : ! end if itime==0
280 : : end if
281 : :
282 : : ! This section is devoted to the optional atom permutation (JYR 001114)
283 : : ! Two input variables are needed
284 : : ! ab_mover%delayperm : is the interval (in time steps) at which
285 : : ! atoms are tentatively permuted
286 : : ! default value could be 0
287 : : ! ab_mover%signperm : is the type of bias for the permutation
288 : : ! +1 to favor alternation of species
289 : : ! -1 to favor segregation
290 : :
291 : : ! Force no permutation at initial step
292 [ + + + - : 18 : if (itime/=1 .and. ab_mover%delayperm/=0 .and. ab_mover%ntypat>2) then
- + ]
293 [ # # ]: 0 : if (mod(itime-1,ab_mover%delayperm)==0) then
294 : : ! Try commutation of atoms.
295 : 0 : write(message, '(a)')' Attempt of commutation '
296 : 0 : call wrtout(ab_out,message,'COLL')
297 : 0 : call wrtout(std_out,message,'COLL')
298 : : ! Compute a 'permutation potential'
299 [ # # ]: 0 : do iatom=1,ab_mover%natom
300 : 0 : pot_perm(iatom)=0.0_dp
301 [ # # ]: 0 : do iatom1=1,ab_mover%natom
302 [ # # ]: 0 : if (iatom1.ne.iatom) then
303 : 0 : distx=xcart(1,iatom)-xcart(1,iatom1)
304 : 0 : distx=distx-acell(1)*nint(distx/acell(1))
305 : 0 : disty=xcart(2,iatom)-xcart(2,iatom1)
306 : 0 : disty=disty-acell(2)*nint(disty/acell(2))
307 : 0 : distz=xcart(3,iatom)-xcart(3,iatom1)
308 : 0 : distz=distz-acell(3)*nint(distz/acell(3))
309 : : ! Here we count each atom below 2 angstr as 1, could be customized
310 : 0 : dist=sqrt(distx*distx+disty*disty+distz*distz)/3.7807
311 : 0 : write(std_out,*) iatom,iatom1,dist
312 [ # # ]: 0 : if (ab_mover%typat(iatom).ne.ab_mover%typat(iatom1)) then
313 : : mcfac=-1
314 : : else
315 : 0 : mcfac=1
316 : : end if
317 [ # # ]: 0 : if (dist<1.0_dp) dist=1.0_dp
318 : : pot_perm(iatom)=pot_perm(iatom)+mcfac*(ab_mover%signperm)*1.0_dp&
319 : 0 : & /exp(log(dist)*6.0_dp)
320 : : end if
321 : : end do
322 : : end do
323 : 0 : write(std_out,*) ' Perm_pot ',pot_perm(:)
324 : : ! write(message, '(a,10f12.5)' )' Perm_pot ',&
325 : : ! & (pot_perm(iatom1),iatom1=1,ab_mover%natom)
326 : : ! call wrtout(ab_out,message,'COLL')
327 : : ! call wrtout(std_out,message,'COLL')
328 : :
329 : : ! Find the two atoms, of different types, with the highest perm_pot
330 [ # # ]: 0 : max_perm(:)=-1.0d9
331 [ # # ]: 0 : do iatom=1,ab_mover%natom
332 [ # # ]: 0 : if (pot_perm(iatom) > max_perm(ab_mover%typat(iatom))) then
333 : 0 : max_perm(ab_mover%typat(iatom))=pot_perm(iatom)
334 : 0 : imax_perm(ab_mover%typat(iatom))=iatom
335 : : end if
336 : : end do
337 : :
338 [ # # ]: 0 : if(zDEBUG)then
339 : : ! write(message, '(a,10f12.5)' )' max_Perm ',&
340 : : ! & (max_perm(itypat),itypat=1,ab_mover%ntypat)
341 : : ! call wrtout(std_out,message,'COLL')
342 : : ! write(message, '(a,10i12)' )' imax_Perm ',&
343 : : ! & (imax_perm(itypat),itypat=1,ab_mover%ntypat)
344 : : ! call wrtout(std_out,message,'COLL')
345 : 0 : write(std_out,*) 'NTYPAT',ab_mover%ntypat
346 : 0 : write(message, '(a,10f12.5)' )' max_Perm ',&
347 [ # # ]: 0 : & (max_perm(:))
348 : 0 : call wrtout(std_out,message,'COLL')
349 : 0 : write(message, '(a,10i12)' )' imax_Perm ',&
350 [ # # ]: 0 : & (imax_perm(:))
351 : 0 : call wrtout(std_out,message,'COLL')
352 : : end if
353 : :
354 : : ! Loop and keep the 2 largest values
355 [ # # ]: 0 : if (max_perm(1)>max_perm(2)) then
356 : 0 : maxp1=max_perm(1)
357 : 0 : maxp2=max_perm(2)
358 : 0 : iatom1=imax_perm(1)
359 : 0 : iatom2=imax_perm(2)
360 : : else
361 : 0 : maxp1=max_perm(2)
362 : 0 : maxp2=max_perm(1)
363 : 0 : iatom1=imax_perm(2)
364 : 0 : iatom2=imax_perm(1)
365 : : end if
366 : :
367 [ # # ]: 0 : do itypat=3,ab_mover%ntypat
368 [ # # ]: 0 : if (max_perm(itypat)>maxp1) then
369 : 0 : maxp2=maxp1
370 : 0 : iatom2=iatom1
371 : 0 : maxp1=max_perm(itypat)
372 : 0 : iatom1=imax_perm(itypat)
373 [ # # ]: 0 : else if (max_perm(itypat)>maxp2) then
374 : 0 : maxp2=max_perm(itypat)
375 : 0 : iatom2=imax_perm(itypat)
376 : : end if
377 : : end do
378 : 0 : write(message, '(2(a,i5))' )' Will commute atom...',iatom1,'...of type ',&
379 : 0 : & ab_mover%typat(iatom1)
380 : 0 : call wrtout(ab_out,message,'COLL')
381 : 0 : call wrtout(std_out,message,'COLL')
382 : 0 : write(message, '(2(a,i5))' )' with atom...',iatom2,'...of type ',&
383 : 0 : & ab_mover%typat(iatom2)
384 : 0 : call wrtout(ab_out,message,'COLL')
385 : 0 : call wrtout(std_out,message,'COLL')
386 : :
387 : : ! Commute the atoms positions
388 : 0 : distx=xcart(1,iatom1)
389 : 0 : disty=xcart(2,iatom1)
390 : 0 : distz=xcart(3,iatom1)
391 : 0 : xcart(1,iatom1)=xcart(1,iatom2)
392 : 0 : xcart(2,iatom1)=xcart(2,iatom2)
393 : 0 : xcart(3,iatom1)=xcart(3,iatom2)
394 : 0 : xcart(1,iatom2)=distx
395 : 0 : xcart(2,iatom2)=disty
396 : 0 : xcart(3,iatom2)=distz
397 : : ! Convert back to xred (reduced coordinates)
398 : 0 : call xcart2xred(ab_mover%natom,rprimd,xcart,xred)
399 : :
400 : : end if ! if(mod(itime,ab_mover%delayperm)==0)
401 : :
402 : : else
403 : : ! write(std_out,*) "I will jump to the end of cycle"
404 : 18 : jump_end_of_cycle=.TRUE.
405 : :
406 : : end if ! if (itime/=1 .and. ab_mover%delayperm/=0 .and. ab_mover%ntypat>2)
407 : : ! End of the commutation section
408 : :
409 : : end if ! if (icycle==1)
410 : :
411 [ + - ]: 18 : ABI_SFREE(imax_perm)
412 : :
413 : : !write(std_out,*) 'langevin 05',jump_end_of_cycle
414 : : !##########################################################
415 : : !### 05. Compute the next values (Only for extra cycles)
416 : :
417 [ - + ]: 18 : if (icycle>1) then
418 : :
419 : : ! write(std_out,*) "Entering internal cycle 2",icycle
420 : :
421 : : ! If the energy computed is higher than the current
422 : : ! (etotal_temp) we have to discard the changes
423 : : ! and compute again
424 : :
425 : : ! write(std_out,*) ch10
426 : : ! write(std_out,*) 'EVALUATION FORCES',etotal,hist%etot(abihist_findIndex(hist,-1))
427 : : ! write(std_out,*) ch10
428 : :
429 : : ! This is the worst case (2 evaluations of SCFCV)
430 : 0 : ihist_prev = abihist_findIndex(hist,-1)
431 [ # # # # ]: 0 : if (etotal>hist%etot(ihist_prev).and.icycle==2) then
432 : :
433 : : ! Discard the changes
434 [ # # ]: 0 : acell(:) =hist%acell(:,ihist_prev)
435 [ # # # # ]: 0 : rprimd(:,:)=hist%rprimd(:,:,ihist_prev)
436 [ # # # # ]: 0 : xred(:,:) =hist%xred(:,:,ihist_prev)
437 [ # # # # ]: 0 : fcart(:,:) =hist%fcart(:,:,ihist_prev)
438 [ # # ]: 0 : strten(:) =hist%strten(:,ihist_prev)
439 [ # # # # ]: 0 : vel(:,:) =hist%vel(:,:,ihist_prev)
440 : 0 : etotal =hist%etot(ihist_prev)
441 : 0 : call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
442 : :
443 : : ! distx=xcart(1,iatom1)
444 : : ! disty=xcart(2,iatom1)
445 : : ! distz=xcart(3,iatom1)
446 : : ! xcart(1,iatom1)=xcart(1,iatom2)
447 : : ! xcart(2,iatom1)=xcart(2,iatom2)
448 : : ! xcart(3,iatom1)=xcart(3,iatom2)
449 : : ! xcart(1,iatom2)=distx
450 : : ! xcart(2,iatom2)=disty
451 : : ! xcart(3,iatom2)=distz
452 : :
453 : : ! Convert back to xred (reduced coordinates)
454 : : ! call xcart2xred(ab_mover%natom,rprimd,xcart,xred)
455 : 0 : write(message, '(a)' )' Commutation unsuccessful, recomputing the forces'
456 : 0 : call wrtout(ab_out,message,'COLL')
457 : 0 : call wrtout(std_out,message,'COLL')
458 : :
459 : : ! This is the best case (only 1 evaluation of SCFCV)
460 : : else
461 : :
462 : 0 : write(message, '(a)')' Commutation successful ! Going on'
463 : 0 : call wrtout(ab_out,message,'COLL')
464 : 0 : call wrtout(std_out,message,'COLL')
465 : :
466 : : ! In thisc case we do not need to compute again SCFCV
467 : : ! We avoid the second iteration on ii
468 : 0 : jump_end_of_cycle=.TRUE.
469 : :
470 : : end if ! etotal > etotal_temp
471 : :
472 : : end if ! if (icycle>1)
473 : :
474 : : !write(std_out,*) 'langevin 06',jump_end_of_cycle
475 : : !##########################################################
476 : : !### 06. Compute the next values (Only for the last cycle)
477 : :
478 [ + - ]: 18 : if(jump_end_of_cycle)then
479 : : ! icycle=ncycle
480 : : ! write(std_out,*) 'This is the last cycle, avoid the others and continue'
481 : 18 : skipcycle=.TRUE.
482 : : else
483 : 0 : skipcycle=.FALSE.
484 : : end if
485 : :
486 [ + + + - ]: 18 : if ((icycle==ncycle).OR.(skipcycle)) then
487 : :
488 : : ! write(std_out,*) 'ENTERING THE FINAL PART',icycle,ncycle
489 : :
490 : : ! Specific to Langevin dynamics
491 : : ! Initialize an array of random forces
492 : : ! No random force at itime=0
493 : : ! if (itime==0) then
494 [ - + ]: 18 : if (itime<0) then
495 : :
496 [ # # # # ]: 0 : ran_force(:,:)=0.0_dp
497 : :
498 : : else
499 : :
500 [ + + ]: 63 : do iatom=1,ab_mover%natom
501 : : ! sig_gauss is the std deviation of the random distribution
502 : 45 : sig_gauss=sqrt(2.0_dp*(ab_mover%friction)*ab_mover%amass(iatom)*ktemp)
503 : : ! write(std_out,*) 'sig_gauss=',sig_gauss
504 : : ! write(std_out,*) 'friction=',ab_mover%friction
505 : : ! write(std_out,*) 'ktemp=',ktemp
506 [ + + ]: 198 : do idim=1,3
507 : 135 : delxi=2.0_dp
508 [ + + ]: 306 : do while (delxi >= 1.0_dp)
509 : 171 : ran_num1=2.0_dp*uniformrandom(idum)-1.0_dp
510 : 171 : ran_num2=2.0_dp*uniformrandom(idum)-1.0_dp
511 : 171 : delxi=ran_num1*ran_num1+ran_num2*ran_num2
512 : : ! write(std_out,*) delxi,ran_num1,ran_num2
513 : : end do
514 : : ran_force(idim,iatom)=ran_num1*sqrt(-2.0_dp*log(delxi)/delxi)&
515 : 180 : & *sig_gauss/sqrt(ab_mover%dtion)
516 : : ! write(std_out,*) 'ran_force',ran_force(idim,iatom)
517 : : end do
518 : : end do
519 : :
520 [ - + ]: 18 : if (zDEBUG) then
521 : 0 : write (std_out,*) '4. Different forces computed'
522 : 0 : write (std_out,*) 'RAN_FORCE'
523 [ # # ]: 0 : do kk=1,ab_mover%natom
524 : 0 : write (std_out,*) ran_force(:,kk)
525 : : end do
526 : : end if
527 : :
528 : :
529 [ - + ]: 18 : if(zDEBUG)then
530 : : ! The distribution should be gaussian
531 : 0 : delxi=0.0_dp
532 [ # # ]: 0 : do iatom=1,ab_mover%natom
533 [ # # ]: 0 : do idim=1,3
534 : 0 : delxi=delxi+(ran_force(idim,iatom)*ab_mover%dtion)**2
535 : : end do
536 : : end do
537 : 0 : delxi=delxi/(3.0_dp*ab_mover%natom)
538 : 0 : write(message, '(2(a,es22.14))' )' variance =',delxi,' asked =',&
539 : 0 : & 2.0_dp*(ab_mover%friction)*ab_mover%amass(2)*ktemp*ab_mover%dtion
540 : 0 : call wrtout(std_out,message,'COLL')
541 : : end if
542 : : ! end if itime\=0
543 : :
544 : : end if
545 : :
546 : : ! zDEBUG
547 : : ! write(message, '(a)' )' after initializing ran_force'
548 : : ! call wrtout(ab_out,message,'COLL')
549 : : ! call wrtout(std_out,message,'COLL')
550 : : ! ENDzDEBUG
551 : :
552 [ + + ]: 63 : do iatom=1,ab_mover%natom
553 [ + + ]: 198 : do idim=1,3
554 : 135 : fcart_m(idim,iatom)=fcart(idim,iatom)/ab_mover%amass(iatom)
555 : 180 : ran_force(idim,iatom)=ran_force(idim,iatom)/ab_mover%amass(iatom)
556 : : end do
557 : : end do
558 [ + + + + ]: 198 : lang_force(:,:)=ran_force(:,:)-(ab_mover%friction)*vel(:,:)+fcart_m(:,:)
559 : :
560 [ - + ]: 18 : if (zDEBUG) then
561 : 0 : write (std_out,*) '4. Different forces computed'
562 : 0 : write (std_out,*) 'FCART_M'
563 [ # # ]: 0 : do kk=1,ab_mover%natom
564 : 0 : write (std_out,*) fcart_m(:,kk)
565 : : end do
566 : 0 : write (std_out,*) 'RAN_FORCE'
567 [ # # ]: 0 : do kk=1,ab_mover%natom
568 : 0 : write (std_out,*) ran_force(:,kk)
569 : : end do
570 : 0 : write (std_out,*) 'LANG_FORCE'
571 [ # # ]: 0 : do kk=1,ab_mover%natom
572 : 0 : write (std_out,*) lang_force(:,kk)
573 : : end do
574 : : end if
575 : :
576 : : ! zDEBUG
577 : : ! write(message, '(a)' )'before verlet'
578 : : ! call wrtout(ab_out,message,'COLL')
579 : : ! call wrtout(std_out,message,'COLL')
580 : : ! ENDzDEBUG
581 : :
582 : : ! Compute next atomic coordinates using Verlet algorithm
583 : :
584 : : ! Impose no change of acell, ucvol, rprim, and rprimd
585 : 18 : acell_next(:)=acell(:)
586 : 18 : ucvol_next=ucvol
587 : 18 : rprim_next(:,:)=rprim(:,:)
588 : 18 : rprimd_next(:,:)=rprimd(:,:)
589 : :
590 : : ! Convert input xred (reduced coordinates) to xcart (cartesian)
591 : 18 : call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
592 : : ! Uses the velocity
593 : : !
594 : : ! If an atom wants to cross the walls, velocity is reversed.
595 : : !
596 [ + + ]: 63 : do iatom=1,ab_mover%natom
597 [ + + ]: 198 : do idim=1,3
598 : : delxi=xcart(idim,iatom)+ab_mover%dtion*vel(idim,iatom)+ &
599 : 135 : & 0.5_dp*ab_mover%dtion*ab_mover%dtion*lang_force(idim,iatom)
600 [ + - - + ]: 135 : if ( (delxi > (rprimd(idim,idim)+(ab_mover%mdwall)) ) .or. &
601 : : & (delxi < - (ab_mover%mdwall) ) ) then
602 : 0 : vel(idim,iatom)=-vel(idim,iatom)
603 : : delxi=xcart(idim,iatom)+ab_mover%dtion*vel(idim,iatom)+ &
604 : 0 : & 0.5_dp*ab_mover%dtion*ab_mover%dtion*lang_force(idim,iatom)
605 : : end if
606 : 180 : xcart_next(idim,iatom)=delxi
607 : : end do
608 : : end do
609 [ + + + + ]: 198 : xcart(:,:)=xcart_next(:,:)
610 [ - + ]: 18 : if (zDEBUG) then
611 : 0 : write (std_out,*) '5. If an atom wants to cross the walls, velocity is reversed.'
612 : 0 : write (std_out,*) 'XCART'
613 [ # # ]: 0 : do kk=1,ab_mover%natom
614 : 0 : write (std_out,*) xcart(:,kk)
615 : : end do
616 : : end if
617 : :
618 : : ! Convert back to xred_next (reduced coordinates)
619 : 18 : call xcart2xred(ab_mover%natom,rprimd,xcart_next,xred_next)
620 : 18 : call xcart2xred(ab_mover%natom,rprimd,xcart,xred)
621 : :
622 [ + + ]: 18 : if (itime==1) then
623 : : ! no old forces are available at first step
624 : : ! Simple update of the velocity
625 : : ! first compute vel_nexthalf for next steps
626 [ + + + + ]: 22 : vel(:,:)=vel(:,:)+ab_mover%dtion*lang_force(:,:)
627 : : else
628 : : ! case itime /= 0 normal verlet integration
629 [ + + + + ]: 176 : vel(:,:)=vel(:,:)+0.5_dp*ab_mover%dtion*(fcart_mold(:,:)+lang_force(:,:))
630 : : end if
631 [ - + ]: 18 : if (zDEBUG) then
632 : 0 : write (std_out,*) '5. Change velocity with verlet'
633 : 0 : write (std_out,*) 'VEL'
634 [ # # ]: 0 : do kk=1,ab_mover%natom
635 : 0 : write (std_out,*) vel(:,kk)
636 : : end do
637 : : end if
638 : :
639 : : ! Store 'current force' as 'old force'
640 [ + + + + ]: 198 : fcart_mold(:,:)=lang_force(:,:)
641 : :
642 : : end if ! if (icycle==ncycle)
643 : :
644 : : !write(std_out,*) 'langevin 07',jump_end_of_cycle
645 : : !##########################################################
646 : : !### 07. Update the history with the prediction
647 : :
648 : : !Increase indexes
649 : 18 : hist%ihist = abihist_findIndex(hist,+1)
650 : :
651 : 18 : call var2hist(acell,hist,ab_mover%natom,rprimd,xred,zDEBUG)
652 [ + + + + ]: 198 : hist%vel(:,:,hist%ihist)=vel(:,:)
653 : 18 : hist%time(hist%ihist)=real(itime,kind=dp)*ab_mover%dtion
654 : :
655 [ + - + - ]: 18 : if (ab_mover%delayperm==0 .or. ab_mover%ntypat<=2) ncycle=1
656 [ + + ]: 18 : if(itime==ntime-1) ncycle=1
657 : :
658 : : end subroutine pred_langevin
659 : : !!***
660 : :
661 : : end module m_pred_langevin
662 : : !!***
|