Branch data Line data Source code
1 : : !!****m* ABINIT/m_mover
2 : : !! NAME
3 : : !! m_mover
4 : : !!
5 : : !! FUNCTION
6 : : !! Move ion or change acell according to forces and stresses
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, SE, FLambert,MT)
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_mover
23 : :
24 : : use defs_basis
25 : : use m_abicore
26 : : use m_errors
27 : : use m_profiling_abi
28 : : use m_abimover
29 : : use m_abihist
30 : : use m_dtset
31 : : use m_pimd
32 : : use m_xmpi
33 : : use m_nctk
34 : : use m_dtfil
35 : : use m_yaml
36 : : use netcdf
37 : : #if defined HAVE_LOTF
38 : : use lotfpath
39 : : use m_pred_lotf
40 : : #endif
41 : :
42 : : use defs_abitypes, only : MPI_type
43 : : use m_fstrings, only : strcat, sjoin, indent, itoa
44 : : use m_matrix, only : matr3inv
45 : : use m_symtk, only : symmetrize_xred
46 : : use m_geometry, only : fcart2gred, chkdilatmx, xred2xcart, metric
47 : : use m_time, only : abi_wtime, sec2str
48 : : use m_exit, only : get_start_time, have_timelimit_in, get_timelimit, enable_timelimit_in
49 : : use m_electronpositron, only : electronpositron_type
50 : : use m_scfcv, only : scfcv_t, scfcv_run
51 : : use m_effective_potential,only : effective_potential_type, effective_potential_evaluate
52 : : use m_initylmg, only : initylmg
53 : : use m_kg, only : getcut, getph
54 : : use m_xfpack, only : xfh_update
55 : : use m_mkrho, only : initro
56 : : use m_pawfgr, only : pawfgr_type, pawfgr_init, pawfgr_destroy
57 : : use m_precpred_1geo, only : precpred_1geo
58 : : use m_pred_simple, only : prec_simple
59 : : !use m_generate_training_set, only : generate_training_set
60 : : use m_wvl_wfsinp, only : wvl_wfsinp_reformat
61 : : use m_wvl_rho, only : wvl_mkrho
62 : : use m_effective_potential_file, only : effective_potential_file_mapHistToRef
63 : : #if defined DEV_MS_SCALEUP
64 : : use scup_global, only : global_set_parent_iter,global_set_print_parameters
65 : : #endif
66 : : use m_scup_dataset
67 : : use m_multibinit_dataset
68 : :
69 : : implicit none
70 : :
71 : : private
72 : : !!***
73 : :
74 : : public :: mover
75 : : !!***
76 : :
77 : : contains
78 : : !!***
79 : :
80 : : !!****f* ABINIT/mover
81 : : !! NAME
82 : : !! mover
83 : : !!
84 : : !! FUNCTION
85 : : !! Move ion or change acell acording to forces and stresses
86 : : !!
87 : : !! INPUTS
88 : : !! amu_curr(ntypat)=mass of each atom for the current image
89 : : !! dtfil <type(datafiles_type)>=variables related to files
90 : : !! dtset <type(dataset_type)>=all input variables for this dataset
91 : : !! | mband=maximum number of bands
92 : : !! | mgfft=maximum size of 1D FFTs
93 : : !! | mkmem =number of k points treated by this node
94 : : !! | angular momentum for nonlocal pseudopotential
95 : : !! | mpw=maximum dimensioned size of npw.
96 : : !! | natom=number of atoms in unit cell
97 : : !! | except on first call (hartree/bohr); updated on output
98 : : !! | nfft=(effective) number of FFT grid points (for this processor)
99 : : !! | for the "coarse" grid (see NOTES below)
100 : : !! | nkpt=number of k points.
101 : : !! | nspden=number of spin-density components
102 : : !! | nsppol=1 for unpolarized, 2 for spin-polarized
103 : : !! | nsym=number of symmetry elements in space group
104 : : !! itimimage_gstate= [optional] counter for the itimimage loop, in the calling routine.
105 : : !! mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
106 : : !! mpi_enreg=information about MPI parallelization
107 : : !! nfftf=(effective) number of FFT grid points (for this processor)
108 : : !! for the "fine" grid (see NOTES below)
109 : : !! npwarr(nkpt)=number of planewaves in basis and boundary at this k point.
110 : : !! nattyp(ntypat)= # atoms of each type.
111 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
112 : : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
113 : : !! | mpsang= 1+maximum angular momentum for nonlocal pseudopotentials
114 : : !! rprimd(3,3)=dimensional primitive translations (bohr)
115 : : !! scup_dtset <type(scup_dtset_type) = derived datatype holding all options
116 : : !! for the evaluation of an effective electronic model using SCALE UP
117 : : !!
118 : : !! OUTPUT
119 : : !! results_gs <type(results_gs_type)>=results (energy and its components,
120 : : !! forces and its components, the stress tensor) of a ground-state computation
121 : : !! eigen(mband*nkpt*nsppol)=array for holding eigenvalues (hartree)
122 : : !! resid(mband*nkpt*nsppol)=residuals for each band over all k points.
123 : : !!
124 : : !! SIDE EFFECTS
125 : : !! Rest of i/o is related to lda
126 : : !! acell(3)=length scales of primitive translations (bohr)
127 : : !! cg(2,mcg)=array for planewave coefficients of wavefunctions.
128 : : !! electronpositron <type(electronpositron_type)>=quantities for the electron-positron annihilation
129 : : !! initialized= if 0 the initialisation of the gstate run is not yet finished
130 : : !! irrzon(nfft**(1-1/nsym),2,(nspden/nsppol)-3*(nspden/4))=irreducible zone data
131 : : !! occ(mband*nkpt*nsppol=occupation number for each band (usually 2) at each k point.
132 : : !! rhog(2,nfftf)=array for Fourier transform of electron density
133 : : !! rhor(nfftf,nspden)=array for electron density in electrons/bohr**3.
134 : : !! scf_history <type(scf_history_type)>=arrays obtained from previous SCF cycles
135 : : !! symrec(3,3,nsym)=symmetry operations in reciprocal space
136 : : !! taug(2,nfftf*dtset%usekden)=array for Fourier transform of kinetic energy density
137 : : !! taur(nfftf,nspden*dtset%usekden)=array for kinetic energy density
138 : : !! vel(3,natom)=old value of velocity; updated on output
139 : : !! vel_cell(3,3)=old value of cell parameters velocity; updated on output
140 : : !! xred(3,natom)=reduced dimensionless atomic coordinates; updated on output
141 : : !! xred_old(3,natom)=work space for old xred
142 : : !! eff_pot<type(effective_potential_type)> = optional,effective_potential datatype
143 : : !! verbose = optional, default is true, flag to disable the verbose mode
144 : : !! write_HIST = optional, default is true, flag to disble the write of the HIST file
145 : : !!
146 : : !! NOTES
147 : : !! This subroutine uses the arguments natom, xred, vel, amu_curr,
148 : : !! vis, and dtion (the last two contained in dtset) to make
149 : : !! molecular dynamics updates. The rest of the lengthy
150 : : !! argument list supports the underlying lda computation
151 : : !! of forces, returned from subroutine scfcv
152 : : !!
153 : : !! USE OF FFT GRIDS:
154 : : !! =================
155 : : !! In case of PAW:
156 : : !! ---------------
157 : : !! Two FFT grids are used:
158 : : !! - A "coarse" FFT grid (defined by ecut)
159 : : !! for the application of the Hamiltonian on the plane waves basis.
160 : : !! It is defined by nfft, ngfft, mgfft, ...
161 : : !! Hamiltonian, wave-functions, density related to WFs (rhor here), ...
162 : : !! are expressed on this grid.
163 : : !! - A "fine" FFT grid (defined) by ecutdg)
164 : : !! for the computation of the density inside PAW spheres.
165 : : !! It is defined by nfftf, ngfftf, mgfftf, ...
166 : : !! Total density, potentials, ...
167 : : !! are expressed on this grid.
168 : : !! In case of norm-conserving:
169 : : !! ---------------------------
170 : : !! - Only the usual FFT grid (defined by ecut) is used.
171 : : !! It is defined by nfft, ngfft, mgfft, ...
172 : : !! For compatibility reasons, (nfftf,ngfftf,mgfftf)
173 : : !! are set equal to (nfft,ngfft,mgfft) in that case.
174 : : !!
175 : : !! SOURCE
176 : :
177 [ - + ]: 393 : subroutine mover(scfcv_args,ab_xfh,acell,amu_curr,dtfil,&
178 : 393 : & electronpositron,rhog,rhor,rprimd,vel,vel_cell,xred,xred_old,&
179 : : & effective_potential,filename_ddb,itimimage_gstate,verbose,verbose_cycle,writeHIST,scup_dtset,sc_size,multibinit_dtset)
180 : :
181 : : !Arguments ------------------------------------
182 : : !scalars
183 : : integer, intent(in), optional :: itimimage_gstate
184 : : type(scfcv_t),intent(inout) :: scfcv_args
185 : : type(datafiles_type),intent(inout),target :: dtfil
186 : : type(electronpositron_type),pointer :: electronpositron
187 : : type(ab_xfh_type),intent(inout) :: ab_xfh
188 : : type(effective_potential_type),optional,intent(inout) :: effective_potential
189 : : logical,optional,intent(in) :: verbose
190 : : logical,optional,intent(in) :: verbose_cycle
191 : : logical,optional,intent(in) :: writeHIST
192 : : character(len=fnlen),optional,intent(in) :: filename_ddb
193 : : !arrays
194 : : real(dp),intent(inout) :: acell(3)
195 : : real(dp), intent(in),target :: amu_curr(:) !(scfcv%dtset%ntypat)
196 : : real(dp), pointer :: rhog(:,:),rhor(:,:)
197 : : real(dp), intent(inout) :: xred(3,scfcv_args%dtset%natom),xred_old(3,scfcv_args%dtset%natom)
198 : : real(dp), intent(inout) :: vel(3,scfcv_args%dtset%natom),vel_cell(3,3),rprimd(3,3)
199 : : type(scup_dtset_type),optional, intent(inout) :: scup_dtset
200 : : type(multibinit_dtset_type),optional, intent(inout) ::multibinit_dtset
201 : : integer,optional,intent(in) :: sc_size(3)
202 : :
203 : : !Local variables-------------------------------
204 : : !scalars
205 : : integer,parameter :: level=102,master=0
206 : 393 : type(abihist) :: hist,hist_prev
207 : : type(abimover) :: ab_mover
208 : : type(abimover_specs) :: specs
209 : 393 : type(abiforstr) :: preconforstr ! Preconditioned forces and stress
210 : 393 : type(delocint) :: deloc
211 : : type(pawfgr_type) :: pawfgr
212 : 393 : type(mttk_type) :: mttk_vars
213 : 393 : type(pimd_type) :: pimd_param
214 : : integer :: itime,icycle,itime_hist,iexit=0,ifirst,ihist_prev,ihist_prev2,timelimit_exit,ncycle,nhisttot,kk,jj,me
215 : : integer :: nmpi,ntime,option,comm,mgfftf,nfftf
216 : : integer :: nerr_dilatmx,my_quit,ierr,quitsum_request
217 : : integer ABI_ASYNC :: quitsum_async
218 : : character(len=500) :: msg
219 : : !character(len=500) :: dilatmx_errmsg
220 : : character(len=8) :: stat4xml
221 : : character(len=35) :: fmt
222 : : character(len=fnlen) :: filename,fname_ddb,name_file
223 : : character(len=500) :: MY_NAME = "mover"
224 : : real(dp) :: gr_avg,ecut_eff,ecutdg_eff,ucvol,boxcut,gsqcut_eff
225 : : logical :: DEBUG=.FALSE., effective_potential_verbose, need_verbose=.TRUE.,need_verbose_cycle=.TRUE.,need_writeHIST=.TRUE.
226 : : logical :: need_scfcv_cycle = .TRUE., need_elec_eval = .FALSE.
227 : : logical :: changed,useprtxfase
228 : : logical :: skipcycle,force_hist_copy=.FALSE.
229 : : integer :: minIndex,ii,similar,conv_retcode
230 : : integer :: iapp
231 : : logical :: file_exists
232 : : logical :: re_init_rho
233 : : #ifdef FC_NVHPC
234 : : logical :: wrong=.false. !Silly trick to prevent NVHPC optimization issue
235 : : #endif
236 : : real(dp) :: minE,wtime_step,now,prev
237 : : !arrays
238 : : integer :: itimes(2),ngfft(18),ngfftf(18)
239 : : real(dp) :: gprimd(3,3),rprim(3,3),rprimd_prev(3,3),gmet(3,3),rmet(3,3)
240 : 393 : real(dp),allocatable :: gred_corrected(:,:),xred_prev(:,:),ph1df(:,:),tmp(:,:),tmp_1d(:)
241 : : real(dp) :: k0(3)
242 : : ! ***************************************************************
243 : 393 : need_verbose=.TRUE.
244 [ + + ]: 393 : if(present(verbose)) need_verbose = verbose
245 : :
246 : 393 : need_verbose_cycle=.TRUE.
247 [ + + ]: 393 : if(present(verbose_cycle)) need_verbose_cycle = verbose_cycle
248 : :
249 : 393 : need_writeHIST=.TRUE.
250 [ + + ]: 393 : if(present(writeHIST)) need_writeHIST = writeHIST
251 : :
252 : : ! enable time limit handler if not done in callers.
253 [ - + ]: 393 : if (enable_timelimit_in(MY_NAME) == MY_NAME) then
254 [ - - ]: 393 : if (need_verbose) then
255 [ # # ]: 0 : write(std_out,*)"Enabling timelimit check in function: ",trim(MY_NAME)," with timelimit: ",trim(sec2str(get_timelimit()))
256 : : end if
257 : : end if
258 : :
259 : 393 : re_init_rho = .FALSE.
260 : :
261 : : !Table of contents
262 : : !(=>) Refers to an important call (scfcv,pred_*)
263 : : !
264 : : !01. Initialization of indexes and allocations of arrays
265 : : !02. Particularities of each predictor
266 : : !03. Set the number of iterations ntime
267 : : !04. Try to read history of previous calculations
268 : : !05. Allocate the hist structure
269 : : !06. First output before any itime or icycle
270 : : !07. Fill the history of the first SCFCV
271 : : !08. Loop for itime (From 1 to ntime)
272 : : !09. Loop for icycle (From 1 to ncycle)
273 : : !10. Output for each icycle (and itime)
274 : : !11. Symmetrize atomic coordinates over space group elements
275 : : !12. => Call to SCFCV routine and fill history with forces
276 : : !13. Write the history into the _HIST file
277 : : !14. Output after SCFCV
278 : : !15. => Test Convergence of forces and stresses
279 : : !16. => Precondition forces, stress and energy
280 : : !17. => Call to each predictor
281 : : !18. Use the history to extract the new values
282 : : !19. End loop icycle
283 : : !20. End loop itime
284 : : !21. Set the final values of xred
285 : : !22. XML Output at the end
286 : : !23. Deallocate hist and ab_mover datatypes
287 : : !
288 : 393 : call abimover_ini(ab_mover,amu_curr,dtfil,scfcv_args%dtset,specs)
289 : :
290 [ + + ]: 393 : if (ab_mover%ionmov==10 .or. ab_mover%ionmov==11) call delocint_ini(deloc)
291 : :
292 [ + + ]: 393 : if (ab_mover%ionmov==13 .or. ab_mover%ionmov==25)then
293 : 31 : call mttk_ini(mttk_vars,ab_mover%nnos)
294 : : end if
295 : :
296 : : !###########################################################
297 : : !### 03. Set the number of iterations ntime
298 : : !### By default ntime==1 but if the user enters a lower
299 : : !### value, mover will execute at least one iteration
300 : :
301 [ - + ]: 393 : if (scfcv_args%dtset%ntime<1)then
302 : 0 : ntime=1
303 : : else
304 : 393 : ntime=scfcv_args%dtset%ntime
305 : : end if
306 : :
307 : : !###########################################################
308 : : !### 04. Try to read history of previous calculations
309 : : !### It requires NetCDF library
310 : :
311 : : !Init MPI data
312 : 393 : comm=scfcv_args%mpi_enreg%comm_cell
313 : 393 : me=xmpi_comm_rank(comm)
314 : :
315 : :
316 [ + - + - ]: 393 : filename=trim(ab_mover%filnam_ds(4))//'_HIST.nc'
317 : :
318 : :
319 [ + + ]: 393 : if (ab_mover%restartxf<0)then
320 : : ! Read history from file (and broadcast if MPI)
321 [ + - ]: 15 : if (me==master) then
322 : 15 : call read_md_hist(filename,hist_prev,specs%isVused,specs%isARused,ab_mover%restartxf==-3)
323 : : endif
324 : :
325 : :
326 : 15 : call abihist_bcast(hist_prev,master,comm)
327 : :
328 : :
329 : : ! If restartxf specifies to reconstruct the history
330 [ + + + + ]: 15 : if (hist_prev%mxhist>0.and.ab_mover%restartxf==-1)then
331 : 1 : ntime=ntime+hist_prev%mxhist
332 : : end if
333 : :
334 : : ! If non deterministic algorithm is used, forcing reading of input hist file
335 [ - + ]: 15 : if (ab_mover%ionmov==16) then
336 : 0 : force_hist_copy=.TRUE.
337 : : end if
338 : :
339 : : ! If restartxf specifies to start from the lowest energy
340 [ + + - + ]: 15 : if (hist_prev%mxhist>0.and.ab_mover%restartxf==-2)then
341 : 0 : minE=hist_prev%etot(1)
342 : 0 : minIndex=1
343 [ # # ]: 0 : do ii=1,hist_prev%mxhist
344 [ # # ]: 0 : if(need_verbose) write(std_out,*) 'Iteration:',ii,' Total Energy:',hist_prev%etot(ii)
345 [ # # ]: 0 : if (minE>hist_prev%etot(ii))then
346 : 0 : minE=hist_prev%etot(ii)
347 : 0 : minIndex=ii
348 : : end if
349 : : end do
350 [ # # ]: 0 : if(need_verbose)write(std_out,*) 'The lowest energy occurs at iteration:',minIndex,'etotal=',minE
351 [ # # ]: 0 : acell(:) =hist_prev%acell(:,minIndex)
352 [ # # # # ]: 0 : rprimd(:,:)=hist_prev%rprimd(:,:,minIndex)
353 [ # # # # ]: 0 : xred(:,:) =hist_prev%xred(:,:,minIndex)
354 [ # # # # ]: 0 : vel(:, :) = hist_prev%vel(:, :, minIndex)
355 : 0 : call abihist_free(hist_prev)
356 : : end if
357 : : ! If restarxf specifies to start to the last iteration
358 [ + + + + ]: 15 : if (hist_prev%mxhist>0.and.ab_mover%restartxf==-3)then
359 [ + - ]: 3 : if(present(effective_potential))then
360 : 3 : call effective_potential_file_mapHistToRef(effective_potential,hist_prev,comm,scfcv_args%dtset%iatfix,need_verbose,sc_size) ! Map Hist to Ref to order atoms
361 : : !xred(:,:) = hist_prev%xred(:,:,1) ! Fill xred with new ordering
362 : 3 : hist%ihist = 1
363 : : end if
364 [ + + ]: 12 : acell(:) =hist_prev%acell(:,hist_prev%mxhist)
365 [ + + + + ]: 39 : rprimd(:,:)=hist_prev%rprimd(:,:,hist_prev%mxhist)
366 [ + + + + ]: 323 : xred(:,:) =hist_prev%xred(:,:,hist_prev%mxhist)
367 [ + + + + ]: 323 : vel(:, :) = hist_prev%vel(:, :, hist_prev%mxhist)
368 : 3 : call abihist_free(hist_prev)
369 : : end if
370 : :
371 : : end if !if (ab_mover%restartxf<=0)
372 : :
373 : : !###########################################################
374 : : !### 05. Allocate the hist structure
375 : :
376 : 393 : iexit=0; timelimit_exit=0
377 : 393 : ncycle=specs%ncycle
378 : :
379 [ + + + - ]: 393 : if(ab_mover%ionmov==25.and.scfcv_args%dtset%hmctt>=0)then
380 : 2 : ncycle=scfcv_args%dtset%hmctt
381 [ - + - - ]: 2 : if(scfcv_args%dtset%hmcsst>0.and.ab_mover%optcell/=0)then
382 : 0 : ncycle=ncycle+scfcv_args%dtset%hmcsst
383 : : endif
384 : : endif
385 : :
386 [ + + ]: 393 : nhisttot=ncycle*ntime;if (scfcv_args%dtset%nctime>0) nhisttot=nhisttot+1
387 : : !AM_2017 New version of the hist, we just store the needed history step not all of them...
388 [ + - ]: 393 : if(specs%nhist/=-1)then
389 : 393 : nhisttot = specs%nhist! We don't need to store all the history
390 : : endif
391 : :
392 : 393 : call abihist_init(hist,ab_mover%natom,nhisttot,specs%isVused,specs%isARused)
393 : 393 : call abiforstr_ini(preconforstr,ab_mover%natom)
394 : :
395 : : !###########################################################
396 : : !### 06. First output before any itime or icycle iteration
397 : :
398 : : !If effective potential is present forces will be compute with it
399 [ + + ]: 393 : if (present(effective_potential))then
400 : 44 : need_scfcv_cycle = .FALSE.
401 [ + - ]: 44 : if(need_verbose)then
402 : : write(msg,'(2a,i2,5a,80a)')&
403 : 44 : & ch10,'=== [ionmov=',ab_mover%ionmov,'] ',trim(specs%method),' with effective potential',&
404 [ + - + + ]: 3608 : & ch10,('=',kk=1,80)
405 [ + + ]: 132 : call wrtout([std_out, ab_out], msg)
406 : : end if
407 : 44 : need_elec_eval = .FALSE.
408 [ + - ]: 44 : if(present(scup_dtset))then
409 : 44 : need_elec_eval = scup_dtset%scup_elec_model
410 : : endif
411 : : else
412 [ + - ]: 349 : if(need_verbose)then
413 : : write(msg,'(a,a,i2,a,a,a,80a)')&
414 : 349 : & ch10,'=== [ionmov=',ab_mover%ionmov,'] ',trim(specs%method),&
415 [ + - + + ]: 28618 : & ch10,('=',kk=1,80)
416 [ + + ]: 1047 : call wrtout([std_out, ab_out], msg)
417 : : end if
418 : : end if
419 : :
420 : : !Format for printing on each cycle
421 : : write(fmt,'(a6,i2,a4,i2,a4,i2,a4,i2,a9)')&
422 : 393 : '(a,a,i',int(log10(real(ntime))+1),&
423 : 393 : ',a,i',int(log10(real(ntime))+1),&
424 : 393 : ',a,i',int(log10(real(ncycle))+1),&
425 : 393 : ',a,i',int(log10(real(ncycle))+1),&
426 : 786 : ',a,a,80a)'
427 : :
428 : : !###########################################################
429 : : !### 07. Fill the history of the first SCFCV
430 : :
431 [ + - ]: 393 : if (ab_mover%ionmov==26)then
432 : :
433 : : !Tdep call need to merge with adewandre branch
434 [ - + ]: 393 : else if (ab_mover%ionmov==27)then
435 [ # # ]: 0 : if(present(filename_ddb))then
436 : 0 : fname_ddb = trim(filename_ddb)
437 : : else
438 [ # # # # ]: 0 : fname_ddb = trim(ab_mover%filnam_ds(3))//'_DDB'
439 : : end if
440 : 0 : INQUIRE(FILE=filename, EXIST=file_exists)
441 : :
442 : 0 : ABI_ERROR("This section has been disabled, ph_freez_disp is not defined in main ABINIT")
443 : :
444 : : ! XG 20200322 : The input variables ph_freez_disp are not documented neither tested, so they
445 : : ! have been removed from the allowed list in the parser. Also, you should not be here !
446 : : ! call generate_training_set(acell,ab_mover%ph_freez_disp_addStrain==1,ab_mover%ph_freez_disp_ampl,&
447 : : !& fname_ddb,hist,ab_mover%natom,ab_mover%ph_freez_disp_nampl,ntime,&
448 : : !& ab_mover%ph_ngqpt,ab_mover%ph_nqshift,ab_mover%ph_freez_disp_option,&
449 : : !& ab_mover%ph_qshift,scfcv_args%dtset%supercell_latt,&
450 : : !& rprimd,ab_mover%mdtemp(2),xred,comm,DEBUG)
451 : :
452 : :
453 : : !Fill history with the values of xred, acell and rprimd of the first configuration
454 [ # # ]: 0 : acell(:) =hist%acell(:,1)
455 [ # # # # ]: 0 : rprimd(:,:)=hist%rprimd(:,:,1)
456 [ # # # # ]: 0 : xred(:,:) =hist%xred(:,:,1)
457 : :
458 : : else
459 : :
460 : : ! Fill history with the values of xred, acell and rprimd
461 : 393 : call var2hist(acell,hist,ab_mover%natom,rprimd,xred,DEBUG)
462 : :
463 : :
464 : : ! Fill velocities and ionic kinetic energy
465 : 393 : call vel2hist(ab_mover%amass,hist,vel,vel_cell)
466 : 393 : hist%time(hist%ihist)=zero
467 : :
468 : : end if
469 : :
470 : : !Decide if prtxfase will be called
471 : 393 : useprtxfase=.FALSE.
472 [ + + ]: 5276 : do ii=1,ab_mover%natom
473 [ + + ]: 5276 : if (ab_mover%prtatlist(ii)/=0)then
474 : : useprtxfase=.TRUE.; exit
475 : : end if
476 : : end do
477 : :
478 : : !At beginning no error
479 : 393 : nerr_dilatmx = 0
480 : : !Copy the number of degrees of freedom in hist structure
481 : 393 : hist%ndof=ab_mover%ndof
482 : :
483 [ - + + - : 1179 : ABI_MALLOC(xred_prev,(3,scfcv_args%dtset%natom))
+ - + - -
+ - + ]
484 : :
485 [ + + + - : 393 : if (present(effective_potential) .and. need_verbose .and. .not.need_verbose_cycle .and. ab_mover%ionmov==25) then
+ + + - ]
486 [ + - + + ]: 162 : write(msg,'(3a,80a)') ch10,'--- Initial state',ch10,('-',kk=1,80)
487 [ + + ]: 6 : call wrtout([std_out, ab_out], msg)
488 [ + - ]: 2 : if(present(multibinit_dtset))then
489 : : call effective_potential_evaluate( &
490 : : & effective_potential,scfcv_args%results_gs%etotal,scfcv_args%results_gs%fcart,scfcv_args%results_gs%gred,&
491 : : & scfcv_args%results_gs%strten,ab_mover%natom,rprimd,xred=xred,verbose=need_verbose,&
492 : : & elec_eval=need_elec_eval,efield_type=multibinit_dtset%efield_type,efield=multibinit_dtset%efield,&
493 : : & efield_lambda=multibinit_dtset%efield_lambda,nefield=multibinit_dtset%nefield,&
494 : : & efield_period=multibinit_dtset%efield_period,efield_phase=multibinit_dtset%efield_phase,&
495 : : & efield_gmean=multibinit_dtset%efield_gmean,efield_gvel=multibinit_dtset%efield_gvel,efield_sigma=multibinit_dtset%efield_sigma,&
496 : 2 : & efield_background=multibinit_dtset%efield_background,time=zero)
497 : : else
498 : : call effective_potential_evaluate( &
499 : : & effective_potential,scfcv_args%results_gs%etotal,scfcv_args%results_gs%fcart,scfcv_args%results_gs%gred,&
500 : : & scfcv_args%results_gs%strten,ab_mover%natom,rprimd,xred=xred,verbose=need_verbose,&
501 : 0 : & elec_eval=need_elec_eval,time=zero)
502 : : end if
503 : : end if
504 : :
505 : : !###########################################################
506 : : !### 08. Loop for itime (From 1 to ntime)
507 : 393 : quitsum_request = xmpi_request_null
508 : :
509 [ - + ]: 3655 : do itime=1,ntime
510 : :
511 : 3655 : call yaml_iterstart("itime", itime, dev_null, scfcv_args%dtset%use_yaml)
512 : :
513 : : ! Handle time limit condition.
514 [ + + ]: 3655 : if (itime == 1) prev = abi_wtime()
515 [ + + ]: 3655 : if (itime > 1) then
516 : 3262 : now = abi_wtime()
517 : 3262 : wtime_step = now - prev
518 : 3262 : prev = now
519 : 3262 : write(msg,*)sjoin("{mover_itime:", itoa(itime - 1), ", wall_time: '", sec2str(wtime_step), "'} <<< TIME")
520 [ + - ]: 3262 : if(need_verbose)call wrtout(std_out, msg)
521 [ - + ]: 3262 : if (have_timelimit_in(MY_NAME)) then
522 [ # # ]: 0 : if (itime > 2) then
523 : 0 : call xmpi_wait(quitsum_request,ierr)
524 [ # # ]: 0 : if (quitsum_async > 0) then
525 [ # # ]: 0 : write(msg,"(3a)")"Approaching time limit ",trim(sec2str(get_timelimit())), ". Will exit itime loop in mover."
526 [ # # ]: 0 : if(need_verbose) ABI_COMMENT(msg)
527 [ # # ]: 0 : if(need_verbose) call wrtout(ab_out, msg)
528 : : timelimit_exit = 1
529 : : exit
530 : : end if
531 : : end if
532 : :
533 [ # # ]: 0 : my_quit = 0; if (now - get_start_time() + 2.15 * wtime_step > get_timelimit()) my_quit = 1
534 : 0 : call xmpi_isum(my_quit,quitsum_async,comm,quitsum_request,ierr)
535 : : end if
536 : : end if
537 : :
538 : 3655 : skipcycle=.FALSE.
539 : : #if defined HAVE_LOTF
540 : : if(ab_mover%ionmov==23 .and. .not. lotf_extrapolation(itime)) skipcycle=.True.
541 : : #endif
542 : :
543 : : ! If RMM-DIIS is used, decrease the number of NSCF steps done with wfoptalg before activating RMM-DIIS.
544 : : ! In vtowfk we have the condition: istep > 3 + dtset%rmm_diis
545 : : ! so setting rmm_diis = 1 gives:
546 : : ! 4 NSCF iterations for itime == 1
547 : : ! 1 NSCF iterations for itime >= 2.
548 [ - + - - ]: 3655 : if (scfcv_args%dtset%rmm_diis /= 0 .and. itime == 2) then
549 : 0 : scfcv_args%dtset%rmm_diis = scfcv_args%dtset%rmm_diis - 3
550 [ # # ]: 0 : if (scfcv_args%dtset%rmm_diis == 0) scfcv_args%dtset%rmm_diis = 1
551 : 0 : call wrtout(std_out, sjoin(" itime == 2 with RMM-DIIS --> setting rmm_diis to:", itoa(scfcv_args%dtset%rmm_diis)))
552 : : end if
553 : :
554 [ + - + + ]: 3655 : if (need_verbose .and. .not.need_verbose_cycle) then
555 [ + - + + ]: 16524 : write(msg,'(2a,i0,a,i0,2a,80a)') ch10,'--- Iteration: (',itime,'/',ntime,')',ch10,('-',kk=1,80)
556 [ + + ]: 612 : call wrtout([std_out, ab_out], msg)
557 : : end if
558 : :
559 : : ! ###########################################################
560 : : ! ### 09. Loop for icycle (From 1 to ncycle)
561 [ + + ]: 12503 : do icycle=1,ncycle
562 : :
563 : 11496 : call yaml_iterstart("icycle", icycle, dev_null, scfcv_args%dtset%use_yaml)
564 : :
565 : 11496 : itime_hist = (itime-1)*ncycle + icycle ! Store the time step in the history
566 : :
567 : : ! ###########################################################
568 : : ! ### 10. Output for each icycle (and itime)
569 [ + - + + ]: 11496 : if(need_verbose.and.need_verbose_cycle)then
570 : : write(msg,fmt)&
571 [ + - + + ]: 282204 : ch10,'--- Iteration: (',itime,'/',ntime,') Internal Cycle: (',icycle,'/',ncycle,')',ch10,('-',kk=1,80)
572 [ + + ]: 10452 : call wrtout([std_out, ab_out], msg)
573 : : end if
574 [ + + ]: 11496 : if (useprtxfase) call prtxfase(ab_mover,hist,itime_hist,std_out,mover_BEFORE)
575 : :
576 [ + + + + ]: 35517980 : xred_prev(:,:)=xred(:,:)
577 : 11496 : rprimd_prev(:,:)=rprimd(:,:)
578 : :
579 : : ! ###########################################################
580 : : ! ### 11. Symmetrize atomic coordinates over space group elements
581 : :
582 : : call symmetrize_xred(ab_mover%natom,&
583 [ + - - - : 11496 : scfcv_args%dtset%nsym,scfcv_args%dtset%symrel,scfcv_args%dtset%tnons,xred,indsym=scfcv_args%indsym)
- - - - -
- - + ]
584 : :
585 [ + + + + : 35516132 : changed = any(xred /= xred_prev)
+ + ]
586 [ + + ]: 11496 : if (changed)then
587 [ + + + + ]: 1909 : hist%xred(:,:,hist%ihist)=xred(:,:)
588 [ + - ]: 49 : if(need_verbose) then
589 : 49 : write(std_out,*) 'WARNING: ATOMIC COORDINATES WERE SYMMETRIZED'
590 : 49 : write(std_out,*) 'DIFFERENCES:'
591 [ + + ]: 514 : do kk=1,ab_mover%natom
592 [ + + ]: 1909 : write(std_out,*) xred(:,kk)-xred_prev(:,kk)
593 : : end do
594 : : end if
595 [ + + + + ]: 1909 : xred_prev(:,:)=xred(:,:)
596 : : end if
597 : :
598 : : ! ###########################################################
599 : : ! ### 12. => Call to SCFCV routine and fill history with forces
600 [ + - + + ]: 11496 : if (need_verbose.and.need_verbose_cycle) then
601 [ + + ]: 3484 : if (need_scfcv_cycle) then
602 : : write(msg,'(a,3a,33a,44a)')&
603 [ + - + + : 78432 : ch10,('-',kk=1,3),'SELF-CONSISTENT-FIELD CONVERGENCE',('-',kk=1,44)
+ - + + ]
604 : : else
605 : : write(msg,'(a,3a,33a,44a)')&
606 [ + - + + : 88800 : ch10,('-',kk=1,3),'EFFECTIVE POTENTIAL CALCULATION',('-',kk=1,44)
+ - + + ]
607 : : end if
608 [ + + ]: 10452 : call wrtout([std_out, ab_out], msg)
609 : : end if
610 : :
611 [ + + + + : 11496 : if(hist_prev%mxhist>0.and.ab_mover%restartxf==-1.and.hist_prev%ihist<=hist_prev%mxhist)then
+ + ]
612 : :
613 : 2 : call abihist_compare_and_copy(hist_prev,hist,ab_mover%natom,similar,tol8,specs%nhist==nhisttot,force_hist_copy)
614 : 2 : hist_prev%ihist=hist_prev%ihist+1
615 : :
616 [ + + ]: 2 : if (hist_prev%ihist==hist_prev%mxhist) re_init_rho=.TRUE.
617 : :
618 : : else
619 : 11494 : scfcv_args%ndtpawuj=0
620 : 11494 : iapp=itime
621 [ + + + + ]: 11494 : if(icycle>1.and.icycle/=ncycle) iapp=-1
622 [ + + + + ]: 11494 : if(itime==1 .and. icycle/=ncycle ) iapp=-icycle-1
623 [ + + + + ]: 11494 : if (ab_mover%ionmov==14.and.(icycle<ncycle)) iapp=-1
624 : :
625 : : #if defined HAVE_LOTF
626 : : if (ab_mover%ionmov/=23 .or.(lotf_extrapolation(itime).and.(icycle/=1.or.itime==1)))then
627 : : #endif
628 : : !call scfcv_new2(scfcv_args,electronpositron,rhog,rhor,rprimd,xred,xred_old,conv_retcode)
629 : :
630 : : !WVL - reformat the wavefunctions in the case of xred != xred_old
631 [ + + + + : 35517946 : if (scfcv_args%dtset%usewvl == 1 .and. maxval(xred_old - xred) > zero) then
+ + + - -
+ - - - +
- - ]
632 : : ! Before running scfcv, on non-first geometry step iterations,
633 : : ! we need to reformat the wavefunctions, taking into acount the new
634 : : ! coordinates. We prepare to change rhog (to be removed) and rhor.
635 [ # # ]: 0 : ABI_FREE(rhog)
636 [ # # ]: 0 : ABI_FREE(rhor)
637 : : call wvl_wfsinp_reformat(scfcv_args%dtset, scfcv_args%mpi_enreg,&
638 : 0 : & scfcv_args%psps, rprimd, scfcv_args%wvl, xred, xred_old)
639 : 0 : scfcv_args%nfftf = scfcv_args%dtset%nfft
640 [ # # # # : 0 : ABI_MALLOC(rhog,(2, scfcv_args%dtset%nfft))
# # # # #
# # # ]
641 [ # # # # : 0 : ABI_MALLOC(rhor,(2, scfcv_args%dtset%nfft))
# # # # #
# # # ]
642 : : call wvl_mkrho(scfcv_args%dtset, scfcv_args%irrzon, scfcv_args%mpi_enreg,&
643 [ # # # # : 0 : & scfcv_args%phnons, rhor,scfcv_args%wvl%wfs,scfcv_args%wvl%den)
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
644 : : end if
645 : :
646 : : !Do another initialization of rho using the last atomic positions
647 : : !to avoid potential problems during restart of MD
648 [ + + ]: 11494 : if (re_init_rho) then
649 : : !Recompute some local quantities required by initro
650 : 1 : call pawfgr_init(pawfgr,scfcv_args%dtset,mgfftf,nfftf,ecut_eff,ecutdg_eff,ngfft,ngfftf)
651 [ + - - + : 3 : ABI_MALLOC(ph1df,(2,3*(2*mgfftf+1)*scfcv_args%dtset%natom))
+ - + - +
- - + - +
- + ]
652 [ + - - - : 1 : call getph(scfcv_args%atindx,scfcv_args%dtset%natom,ngfftf(1),ngfftf(2),ngfftf(3),ph1df,xred)
- - - + ]
653 : 1 : call metric(gmet,gprimd,ab_out,rmet,rprimd,ucvol)
654 : 1 : k0(:)=0.0_dp
655 : 1 : call getcut(boxcut,ecutdg_eff,gmet,gsqcut_eff,scfcv_args%dtset%iboxcut,ab_out,k0,ngfftf)
656 : : !Reinitialise density from current xred
657 : : call initro(scfcv_args%atindx,scfcv_args%dtset%densty,gmet,gsqcut_eff,&
658 : : & scfcv_args%psps%usepaw,mgfftf,scfcv_args%mpi_enreg,scfcv_args%psps%mqgrid_vl,&
659 : : & scfcv_args%dtset%natom,scfcv_args%nattyp,nfftf,ngfftf,scfcv_args%dtset%nspden,&
660 : : & scfcv_args%psps%ntypat,scfcv_args%psps,scfcv_args%pawtab,ph1df,&
661 : : & scfcv_args%psps%qgrid_vl,rhog,rhor,scfcv_args%dtset%spinat,ucvol,&
662 [ + - - - : 1 : & scfcv_args%psps%usepaw,scfcv_args%dtset%ziontypat,scfcv_args%dtset%znucl)
- - + - -
- - - + -
- - - - -
+ - + - +
- + - + ]
663 : 1 : call pawfgr_destroy(pawfgr)
664 [ - + ]: 1 : ABI_FREE(ph1df)
665 : 1 : re_init_rho = .FALSE.
666 : : ! Also update scf_history with the correct density for density prediction if required
667 [ - + - - ]: 3 : if (scfcv_args%scf_history%history_size>0) scfcv_args%scf_history%atmrho_last(:)=rhor(:,1)
668 : : end if
669 : :
670 : : ! MAIN CALL TO SELF-CONSISTENT FIELD ROUTINE
671 [ + + ]: 11494 : if (need_scfcv_cycle) then
672 : :
673 : 1632 : call dtfil%init_time(iapp)
674 : 1632 : itimes(1)=itime; itimes(2)=1
675 [ + - ]: 1632 : if(present(itimimage_gstate))then
676 : 1632 : itimes(2)=itimimage_gstate
677 : : endif
678 : :
679 : : !DEBUG
680 : : ! write(std_out,'(a,5i4)')' m_mover, before scfcv_run : itimes(1:2)=',itimes(1:2)
681 : : !ENDDEBUG
682 : 1632 : call scfcv_run(scfcv_args, electronpositron, itimes, rhog, rhor, rprimd, xred, xred_old, conv_retcode)
683 [ - + ]: 1632 : if (conv_retcode == -1) then
684 : 0 : msg = "Scf cycle returned conv_retcode == -1 (timelimit is approaching), this should not happen inside mover"
685 : 0 : ABI_WARNING(msg)
686 : : end if
687 : :
688 : : else
689 : : ! For monte carlo don't need to recompute energy here (done in pred_montecarlo)
690 : 9862 : name_file='MD_anharmonic_terms_energy.dat'
691 [ + + + + ]: 9862 : if(itime == 1 .and. ab_mover%restartxf==-3)then
692 [ + - ]: 9 : if(icycle==1)call effective_potential_file_mapHistToRef(effective_potential,hist,comm,scfcv_args%dtset%iatfix,&
693 [ + - - + ]: 9 : & need_verbose.and.need_verbose_cycle,sc_size=sc_size)!Map Hist to Ref to order atoms
694 [ + + + + ]: 2249 : xred(:,:) = hist%xred(:,:,1) ! Fill xred with new ordering
695 : 9 : hist%ihist = 1
696 : : end if
697 : :
698 : : #if defined DEV_MS_SCALEUP
699 : : !If we a SCALE UP effective electron model give the iteration and set print-options
700 : : if(need_elec_eval)then
701 : : call global_set_parent_iter(itime)
702 : : ! Set all print options to false.
703 : : call global_set_print_parameters(geom=.FALSE.,eigvals=.FALSE.,eltic=.FALSE.,&
704 : : & orbocc=.FALSE.,bands=.FALSE.)
705 : : if(itime == 1 .or. modulo(itime,scup_dtset%scup_printniter) == 0)then
706 : : call global_set_print_parameters(scup_dtset%scup_printgeom,scup_dtset%scup_printeigv,scup_dtset%scup_printeltic,&
707 : : & scup_dtset%scup_printorbocc,scup_dtset%scup_printbands)
708 : : end if
709 : : end if
710 : : #endif
711 : :
712 [ + - + + : 9862 : effective_potential_verbose = need_verbose .and. (need_verbose_cycle .or. icycle == ncycle)
+ + ]
713 [ + - ]: 9862 : if(present(multibinit_dtset))then
714 : : !TODO: use multibinit_dtset to set the parameters of the effective potential
715 : : call effective_potential_evaluate( &
716 : : & effective_potential,scfcv_args%results_gs%etotal,scfcv_args%results_gs%fcart,scfcv_args%results_gs%gred,&
717 : : & scfcv_args%results_gs%strten,ab_mover%natom,rprimd,xred=xred,verbose=effective_potential_verbose,&
718 : : & filename=name_file,elec_eval=need_elec_eval,efield_type=multibinit_dtset%efield_type,efield=multibinit_dtset%efield,&
719 : : & efield_lambda=multibinit_dtset%efield_lambda,nefield=multibinit_dtset%nefield,&
720 : : & efield_period=multibinit_dtset%efield_period,efield_phase=multibinit_dtset%efield_phase,&
721 : : & efield_gmean=multibinit_dtset%efield_gmean,efield_gvel=multibinit_dtset%efield_gvel,efield_sigma=multibinit_dtset%efield_sigma,&
722 : 9862 : & efield_background=multibinit_dtset%efield_background,time=itime*ab_mover%dtion)
723 : : else
724 : : call effective_potential_evaluate( &
725 : : & effective_potential,scfcv_args%results_gs%etotal,scfcv_args%results_gs%fcart,scfcv_args%results_gs%gred,&
726 : : & scfcv_args%results_gs%strten,ab_mover%natom,rprimd,xred=xred,verbose=effective_potential_verbose,&
727 : 0 : & filename=name_file,elec_eval=need_elec_eval,time=itime*ab_mover%dtion)
728 : : end if
729 : :
730 : :
731 : :
732 : :
733 : : ! Check if the simulation did not diverge...
734 [ + + - + ]: 9862 : if(itime > 3 .and.ABS(scfcv_args%results_gs%etotal - hist%etot(1)) > 1E5)then
735 : : ! We set to false the flag corresponding to the bound
736 : 0 : effective_potential%anharmonics_terms%bounded = .FALSE.
737 [ # # # # ]: 0 : if(need_verbose.and.me==master)then
738 : 0 : ABI_WARNING("The simulation is diverging, please check your effective potential")
739 : : end if
740 : : ! Set the flag to finish the simulation
741 : 0 : iexit=1
742 : 0 : stat4xml="Failed"
743 : : else
744 : : ! We set to true the flag corresponding to the bound
745 : 9862 : effective_potential%anharmonics_terms%bounded = .TRUE.
746 : : end if
747 : : end if
748 : : #if defined HAVE_LOTF
749 : : end if
750 : : #endif
751 : : ! ANOMALOUS SITUATION
752 : : ! This is the only case where rprimd could change inside scfcv
753 : : ! It generates a weird condition, we start with a certain
754 : : ! value for rprimd before scfcv and after we finish with a different value.
755 : : ! Notice that normally scfcv should not change rprimd
756 : : ! And even worse if optcell==0
757 : : ! The solution here is to recompute acell and store these value
758 : : ! in the present record even if initially it was not exactly
759 : : ! the value entering in scfcv
760 : : ! One test case with these condition is bigdft/t10
761 [ + + + + : 149422 : if (any(rprimd(:,:)/=rprimd_prev(:,:))) then
+ - - + ]
762 [ # # ]: 0 : hist%acell(:,hist%ihist)=acell(:)
763 [ # # # # ]: 0 : hist%rprimd(:,:,hist%ihist)=rprimd(:,:)
764 : : end if
765 : :
766 : : ! ANOMALOUS SITUATIONS
767 : : ! * In ionmov 4 & 5 xred could change inside SCFCV
768 : : ! So we need to take the values from the output
769 : : !
770 : : ! * Inside scfcv_core.F90 there is a call to symmetrize_xred.F90
771 : : ! for the first SCF cycle symmetrize_xred could change xred
772 [ + + ]: 11494 : if (ab_mover%ionmov<10)then
773 [ + + + + : 17439 : changed = any(xred /= xred_prev)
+ + ]
774 [ + + ]: 1411 : if (changed)then
775 [ + + + + ]: 168 : hist%xred(:,:,hist%ihist)=xred(:,:)
776 [ + - ]: 16 : if(need_verbose)then
777 : 16 : write(std_out,*) 'WARNING: ATOMIC COORDINATES WERE SYMMETRIZED AFTER SCFCV'
778 : 16 : write(std_out,*) 'DIFFERENCES:'
779 [ + + ]: 54 : do kk=1,ab_mover%natom
780 [ + + ]: 168 : write(std_out,*) xred(:,kk)-xred_prev(:,kk)
781 : : end do
782 : : end if
783 : : end if
784 : : end if
785 : :
786 : : ! Fill velocities and ionic kinetic energy
787 : 11494 : call vel2hist(ab_mover%amass,hist,vel,vel_cell)
788 : :
789 [ + + + + ]: 35517946 : hist%fcart(:,:,hist%ihist)=scfcv_args%results_gs%fcart(:,:)
790 [ + + ]: 80458 : hist%strten(:,hist%ihist) =scfcv_args%results_gs%strten(:)
791 : 11494 : hist%etot(hist%ihist) =scfcv_args%results_gs%etotal
792 : 11494 : hist%entropy(hist%ihist) =scfcv_args%results_gs%energies%entropy
793 : 11494 : hist%time(hist%ihist) =real(itime,kind=dp)
794 : :
795 : : ! !######################################################################
796 : : end if ! if(hist_prev%mxhist>0.and.ab_mover%restartxf==-1.and.hist_prev%ihist<=hist_prev%mxhist)then
797 : :
798 : : ! Store trajectory in xfh file
799 [ + + + - ]: 11496 : if((ab_xfh%nxfh==0.or.itime/=1)) then
800 [ - + + - : 34488 : ABI_MALLOC(gred_corrected,(3,scfcv_args%dtset%natom))
+ - + - -
+ - + ]
801 : 11496 : call fcart2gred(hist%fcart(:,:,hist%ihist),gred_corrected,rprimd,ab_mover%natom)
802 : : ! Get rid of mean force on whole unit cell,
803 : : ! but only if no generalized constraints are in effect
804 [ + + ]: 11496 : if (ab_mover%nconeq==0)then
805 [ + + ]: 45668 : do ii=1,3
806 [ + + + + ]: 45668 : if (ii/=3.or.ab_mover%jellslab==0) then
807 [ + + ]: 26663404 : gr_avg=sum(gred_corrected(ii,:))/dble(ab_mover%natom)
808 [ + + ]: 26663405 : gred_corrected(ii,:)=gred_corrected(ii,:)-gr_avg
809 : : end if
810 : : end do
811 : : end if
812 [ + + + + ]: 11496 : if (ncycle<10.and.ab_mover%restartxf>=0) then
813 [ + + ]: 13192 : do ii=1,3
814 [ + + ]: 42874 : rprim(ii,1:3)=rprimd(ii,1:3)/acell(1:3)
815 : : end do
816 : :
817 : : ! The size of ab_xfh%xfhist is to big for very large supercell.
818 : : ! Call it only for specific ionmov
819 [ + + + + : 14561 : if(any((/2,3,10,11,22/)==ab_mover%ionmov)) then
+ + ]
820 : 1158 : call xfh_update(ab_xfh,acell,gred_corrected,ab_mover%natom,rprim,hist%strten(:,hist%ihist),xred)
821 : : end if
822 : : end if
823 [ - + ]: 11496 : ABI_FREE(gred_corrected)
824 : : end if
825 : :
826 : : ! ###########################################################
827 : : ! ### 13. Write the history into the _HIST file
828 : : ! ###
829 : :
830 [ + - + + ]: 11496 : if (need_writeHIST.and.me==master) then
831 [ + + + + ]: 10394 : ifirst=merge(0,1,(itime>1.or.icycle>1))
832 : : call write_md_hist(hist,filename,ifirst,itime_hist,ab_mover%natom,scfcv_args%dtset%nctime,&
833 [ + - - - : 10394 : & ab_mover%ntypat,ab_mover%typat,amu_curr,ab_mover%znucl,ab_mover%dtion,scfcv_args%dtset%mdtemp)
- - - + -
- - - - +
- + ]
834 : : end if
835 : :
836 : : ! ###########################################################
837 : : ! ### 14. Output after SCFCV
838 [ + - + + : 11496 : if(need_verbose.and.need_verbose_cycle.and.need_scfcv_cycle)then
+ + ]
839 [ + - + + : 122550 : write(msg,'(a,3a,a,72a)')ch10,('-',kk=1,3),'OUTPUT',('-',kk=1,71)
+ - + + ]
840 [ + + ]: 4902 : call wrtout([std_out, ab_out], msg)
841 : : end if
842 [ + + + + ]: 11496 : if (useprtxfase.and..not.ab_mover%use_pimd_routine) then
843 : 1624 : call prtxfase(ab_mover,hist,itime_hist,ab_out,mover_AFTER)
844 : 1624 : call prtxfase(ab_mover,hist,itime_hist,std_out,mover_AFTER)
845 : : end if
846 : :
847 : : ! ###########################################################
848 : : ! ### 15. => Test Convergence of forces and stresses
849 : :
850 [ + + + + ]: 11496 : if (itime==ntime.and.icycle==ncycle)then
851 : 183 : iexit=1
852 : 183 : stat4xml="Failed"
853 : : else
854 : 11313 : stat4xml="Succeded"
855 : : end if
856 : :
857 : : ! Only if convergence is needed
858 [ + + ]: 11496 : if(specs%isFconv)then
859 [ + + + + ]: 1344 : if ((ab_mover%ionmov/=4.and.ab_mover%ionmov/=5).or.mod(itime,2)==1)then
860 [ + + ]: 1330 : if (scfcv_args%dtset%tolmxf/=0)then
861 : :
862 : : call fconv(hist%fcart(:,:,hist%ihist),&
863 : : & scfcv_args%dtset%iatfix, &
864 : : & iexit,itime,&
865 : : & ab_mover%natom,&
866 : : & ntime,&
867 : : & ab_mover%optcell,&
868 : : & scfcv_args%dtset%strfact,&
869 : : & scfcv_args%dtset%strtarget,&
870 : : & hist%strten(:,hist%ihist),&
871 : : & rprim,&
872 : 1326 : & scfcv_args%dtset%tolmxf)
873 : : else
874 : 4 : call erlxconv(hist,iexit,itime,itime_hist,ntime,scfcv_args%dtset%tolmxde)
875 : : end if
876 : : end if
877 : : end if
878 : :
879 [ + + + + ]: 11496 : if (itime==ntime.and.icycle==ncycle) iexit=1
880 : :
881 : : ! ###########################################################
882 : : ! ### 16. => Precondition forces, stress and energy
883 : : ! ### 17. => Call to each predictor
884 : : ! Some MOLDYN algorithms require pimd_param to be initialized
885 [ + + ]: 11496 : if(ab_mover%use_pimd_routine) then
886 : 10 : call pimd_init(scfcv_args%dtset,pimd_param,me==master,force_imgmov=9)
887 : : end if
888 : :
889 : : call precpred_1geo(ab_mover,ab_xfh,amu_curr,deloc,&
890 : : & scfcv_args%dtset%chkdilatmx,&
891 : : & scfcv_args%mpi_enreg%comm_cell,&
892 : : & scfcv_args%dtset%dilatmx,dtfil%filnam_ds(4),&
893 : : & hist,scfcv_args%dtset%hmctt,&
894 : : & icycle,iexit,itime,mttk_vars,&
895 : : & scfcv_args%dtset%nctime,ncycle,nerr_dilatmx,scfcv_args%dtset%npsp,ntime,&
896 [ - + - - : 11496 : & pimd_param,scfcv_args%dtset%rprimd_orig,skipcycle,scfcv_args%dtset%usewvl)
- - - + ]
897 : :
898 : : ! Write MOLDYN netcdf and POSABIN files (done every dtset%nctime time step)
899 : : ! This file is not created for multibinit run
900 [ + + - + : 11496 : if(need_scfcv_cycle .and. (ab_mover%ionmov/=23 .or. icycle==1))then
- - ]
901 [ + + ]: 1634 : if (scfcv_args%dtset%nctime>0) then
902 [ + + + - ]: 34 : jj=itime; if(hist_prev%mxhist>0.and.ab_mover%restartxf==-1) jj=jj-hist_prev%mxhist
903 [ + + ]: 34 : if (jj>0) then
904 : 32 : option=3
905 : 32 : ihist_prev = abihist_findIndex(hist,-1)
906 : : call wrt_moldyn_netcdf(ab_mover%amass,scfcv_args%dtset,jj,option,dtfil%fnameabo_moldyn,&
907 : : & scfcv_args%mpi_enreg,scfcv_args%results_gs,&
908 : : & hist%rprimd(:,:,ihist_prev),dtfil%unpos,hist%vel(:,:,hist%ihist),&
909 [ + - - - : 32 : & hist%xred(:,:,ihist_prev))
- - - + ]
910 : : end if
911 [ + + ]: 34 : if (iexit==1) hist%ihist=ihist_prev
912 : : end if
913 : : end if
914 [ + + ]: 11496 : if(iexit/=0) exit
915 : :
916 : : ! ###########################################################
917 : : ! ### 18. Use the history to extract the new values of acell, rprimd and xred
918 : :
919 : 11103 : call hist2var(acell,hist,ab_mover%natom,rprimd,xred,DEBUG)
920 : : ! /!\ ---- DO NOT CHANGE THESE LINES WITHOUT CORE DEVELOPERS PERMISSION ---- /!\
921 : : ! LB-03/2026:
922 : : ! A noise can accumulate in acell,rprimd and xred after each iterations,
923 : : ! resulting in different results for different MPI processes.
924 : : ! This has been observed using threads, but could happen in other contexts.
925 : : ! This slowly worsens the ionic dynamics, leading to wrong results after many iterations.
926 : : ! So here we compute the mean over all MPI processes to reduce the noise.
927 : : ! This error is difficult to test as it is observed in long runs only, so BE VERY CAREFUL.
928 : : ! Note : the cost of these MPI communications is negligible.
929 : : ! comm = comm_cell
930 : 11103 : nmpi = xmpi_comm_size(comm)
931 [ + + ]: 11103 : if (nmpi>1) then
932 [ - + + - : 4518 : ABI_MALLOC(tmp,(size(xred,1),size(xred,2)))
+ - + - -
+ - + -
+ ]
933 [ + + + + ]: 287690 : tmp(:,:) = xred(:,:) / nmpi
934 : 1506 : call xmpi_sum(tmp,comm,ierr)
935 [ - + ]: 1506 : if (ierr/=0) then
936 : 0 : ABI_ERROR("Error in mpi sum (tmp)")
937 : : end if
938 [ + + + + ]: 287690 : xred(:,:) = tmp(:,:)
939 [ - + ]: 1506 : ABI_FREE(tmp)
940 [ - + ]: 1506 : ABI_MALLOC(tmp,(size(rprimd,1),size(rprimd,2)))
941 [ + + + + ]: 19578 : tmp(:,:) = rprimd(:,:) / nmpi
942 : 1506 : call xmpi_sum(tmp,comm,ierr)
943 [ - + ]: 1506 : if (ierr/=0) then
944 : 0 : ABI_ERROR("Error in mpi sum (tmp)")
945 : : end if
946 [ + + + + ]: 19578 : rprimd(:,:) = tmp(:,:)
947 [ - + ]: 1506 : ABI_FREE(tmp)
948 [ - + - + ]: 1506 : ABI_MALLOC(tmp_1d,(size(acell)))
949 [ + + ]: 6024 : tmp_1d(:) = acell(:) / nmpi
950 : 1506 : call xmpi_sum(tmp_1d,comm,ierr)
951 [ - + ]: 1506 : if (ierr/=0) then
952 : 0 : ABI_ERROR("Error in mpi sum (tmp)")
953 : : end if
954 [ + + ]: 6024 : acell(:) = tmp_1d(:)
955 [ - + ]: 6024 : ABI_FREE(tmp_1d)
956 : : end if
957 : : ! /!\--------------------/!\
958 : :
959 [ + + ]: 11103 : if (ab_mover%optcell/=0) then
960 : : ! Cell may change
961 : :
962 : : #ifdef FC_NVHPC
963 : : ! Yet another wild NVHPC bug (only on eos_nvhpc_23.9_elpa)
964 : : if(wrong) write(100,*) xred
965 : : #endif
966 : 1295 : call matr3inv(rprimd,gprimd)
967 : :
968 : : ! If metric has changed since the initialization, update the Ylm's
969 [ + + ]: 1295 : if (scfcv_args%psps%useylm==1)then
970 : 100 : option=0
971 [ + - ]: 100 : if (scfcv_args%dtset%iscf>0) option=1
972 : : call initylmg(gprimd,&
973 : : & scfcv_args%kg,&
974 : : & scfcv_args%dtset%kptns,&
975 : : & scfcv_args%dtset%mkmem,&
976 : : & scfcv_args%mpi_enreg,&
977 : : & scfcv_args%psps%mpsang,&
978 : : & scfcv_args%dtset%mpw,&
979 : : & scfcv_args%dtset%nband,&
980 : : & scfcv_args%dtset%nkpt,&
981 : : & scfcv_args%npwarr,&
982 : : & scfcv_args%dtset%nsppol,&
983 : : & option,rprimd,&
984 : : & scfcv_args%ylm,&
985 [ + - - - : 100 : & scfcv_args%ylmgr)
- - - - +
- - - - -
+ - - - +
- - - - +
- + - + -
- - - - +
- - - - -
- ]
986 : : end if
987 : :
988 : : end if
989 : :
990 [ + + + + ]: 35494135 : vel(:,:)=hist%vel(:,:,hist%ihist)
991 : :
992 : : ! vel_cell(3,3)= velocities of cell parameters
993 : : ! Not yet used here but compute it for consistency
994 [ + + + + ]: 144339 : vel_cell(:,:)=hist%vel_cell(:,:,hist%ihist)
995 [ + + + - ]: 11103 : if (ab_mover%ionmov==13 .and. hist%mxhist >= 2) then
996 [ + + ]: 1026 : if (itime_hist>2) then
997 : 968 : ihist_prev2 = abihist_findIndex(hist,-2)
998 [ + + + + ]: 12584 : vel_cell(:,:)=(hist%rprimd(:,:,hist%ihist)- hist%rprimd(:,:,ihist_prev2))/(two*ab_mover%dtion)
999 [ + + ]: 58 : else if (itime_hist>1) then
1000 : 29 : ihist_prev = abihist_findIndex(hist,-1)
1001 [ + + + + ]: 377 : vel_cell(:,:)=(hist%rprimd(:,:,hist%ihist)-hist%rprimd(:,:,ihist_prev))/(ab_mover%dtion)
1002 : : end if
1003 : : end if
1004 : :
1005 : : ! This is needed for some compilers such as
1006 : : ! pathscale, g95, xlf that do not exit
1007 : : ! from a loop if you change the upper limit
1008 : : ! inside
1009 [ + + + + ]: 11103 : if (icycle>=ncycle .and. scfcv_args%mpi_enreg%me == 0) then
1010 [ + - + + ]: 2255 : if(need_verbose.and.need_verbose_cycle)write(std_out,*) 'EXIT:',icycle,ncycle
1011 : : exit
1012 : : end if
1013 : :
1014 : :
1015 [ + - + + ]: 8848 : if (need_verbose.and.need_verbose_cycle) then
1016 : 1040 : write(msg,*) 'ICYCLE',icycle,skipcycle
1017 : 1040 : call wrtout(std_out,msg)
1018 : 1040 : write(msg,*) 'NCYCLE',ncycle
1019 : 1040 : call wrtout(std_out,msg)
1020 : : end if
1021 [ + - ]: 10248 : if (skipcycle) exit
1022 : :
1023 : : ! ###########################################################
1024 : : ! ### 19. End loop icycle
1025 : :
1026 : : end do ! icycle
1027 : :
1028 [ + + ]: 3655 : if(iexit/=0)exit
1029 : :
1030 : : ! ###########################################################
1031 : : ! ### 20. End loop itime
1032 : :
1033 : : end do ! itime
1034 : :
1035 : : ! Call fconv here if we exited due to wall time limit.
1036 [ # # ]: 0 : if (timelimit_exit==1 .and. specs%isFconv) then
1037 : 0 : iexit = timelimit_exit
1038 : 0 : ntime = itime-1
1039 : 0 : ihist_prev = abihist_findIndex(hist,-1)
1040 [ # # ]: 0 : if ((ab_mover%ionmov/=4.and.ab_mover%ionmov/=5)) then
1041 [ # # ]: 0 : if (scfcv_args%dtset%tolmxf/=0)then
1042 : : call fconv(hist%fcart(:,:,ihist_prev),&
1043 : : & scfcv_args%dtset%iatfix, &
1044 : : & iexit, itime,&
1045 : : & ab_mover%natom,&
1046 : : & ntime,&
1047 : : & ab_mover%optcell,&
1048 : : & scfcv_args%dtset%strfact,&
1049 : : & scfcv_args%dtset%strtarget,&
1050 : : & hist%strten(:,ihist_prev),&
1051 : : & rprim,&
1052 : 0 : & scfcv_args%dtset%tolmxf)
1053 : : else
1054 : 0 : call erlxconv(hist,iexit,itime,itime_hist,ntime,scfcv_args%dtset%tolmxde)
1055 : : end if
1056 : : end if
1057 : : end if
1058 : :
1059 : : ! Avoid pending requests if itime == ntime.
1060 : 393 : call xmpi_wait(quitsum_request,ierr)
1061 : :
1062 : : !###########################################################
1063 : : !### 21. Set the final values of xred with the last computed values (not the last predicted)
1064 : :
1065 : 393 : call hist2var(acell,hist,ab_mover%natom,rprimd,xred,DEBUG)
1066 [ + + + + ]: 23845 : vel(:,:)=hist%vel(:,:,hist%ihist)
1067 : :
1068 [ - + - - ]: 393 : if (DEBUG .and. ab_mover%ionmov==1)then
1069 : 0 : write (std_out,*) 'vel'
1070 [ # # ]: 0 : do kk=1,ab_mover%natom
1071 : 0 : write (std_out,*) hist%vel(:,kk,hist%ihist)
1072 : : end do
1073 : : end if
1074 : :
1075 : : !###########################################################
1076 : : !### 22. XML Output at the end
1077 : :
1078 : : !XML output of the status
1079 [ + + + + ]: 393 : if (scfcv_args%mpi_enreg%me == 0 .and. scfcv_args%dtset%prtxml == 1) then
1080 : 1 : write(ab_xml_out, "(3a)") ' <geometryMinimisation type="',trim(specs%type4xml),'">'
1081 : 1 : write(ab_xml_out, "(5a)") ' <status cvState="',trim(stat4xml) ,'" stop-criterion="',trim(specs%crit4xml),'" />'
1082 : 1 : write(ab_xml_out, "(3a)") ' </geometryMinimisation>'
1083 : : end if
1084 : :
1085 : : !###########################################################
1086 : : !### 23. Deallocate hist and ab_mover datatypes
1087 : :
1088 : : !This call is needed to free an internal matrix. However, this is not optimal ...
1089 : : !One should instead have a datastructure associated with the preconditioner.
1090 [ + + ]: 393 : if (ab_mover%goprecon>0) call prec_simple(ab_mover,preconforstr,hist,1,1,1)
1091 : :
1092 [ + + ]: 393 : if (ab_mover%ionmov==13 .or. ab_mover%ionmov==25)then
1093 : 31 : call mttk_fin(mttk_vars)
1094 : : end if
1095 : :
1096 [ + + ]: 393 : if (ab_mover%ionmov==10 .or. ab_mover%ionmov==11) call delocint_fin(deloc)
1097 : :
1098 [ - + ]: 393 : ABI_FREE(xred_prev)
1099 : :
1100 : 393 : call abihist_free(hist)
1101 : :
1102 : 393 : call abihist_free(hist_prev)
1103 : 393 : call abimover_destroy(ab_mover)
1104 [ - + - + : 786 : call abiforstr_fin(preconforstr)
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + ]
1105 : :
1106 : : contains
1107 : : !!***
1108 : :
1109 : : !!****f* ABINIT/fconv
1110 : : !!
1111 : : !! NAME
1112 : : !! fconv
1113 : : !!
1114 : : !! FUNCTION
1115 : : !! Check maximal absolute value of force (hartree/bohr) against input tolerance; if below tolerance, return iexit=1.
1116 : : !! Takes into account the fact that the Broyden (or moldyn) step
1117 : : !! might be the last one (last itime), to print eventually modified message.
1118 : : !! Stresses are also included in the check, provided that optcell/=0.
1119 : : !!
1120 : : !! If optcell=1, takes only the trace into account
1121 : : !! optcell=2, takes all components into account
1122 : : !! optcell=3, takes traceless stress into account
1123 : : !! optcell=4, takes sigma(1,1), sigma(2,1) and sigma(3,1) into account
1124 : : !! optcell=5, takes sigma(1,2), sigma(2,2) and sigma(3,2) into account
1125 : : !! optcell=6, takes sigma(1,3), sigma(2,3) and sigma(3,3) into account
1126 : : !! optcell=7, takes sigma(2,2),(2,3) and (3 3) into account
1127 : : !! optcell=8, takes sigma(1,1),(1,3) and (3 3) into account
1128 : : !! optcell=9, takes sigma(1,1),(1,2) and (2 2) into account
1129 : : !! In the case of stresses, target the tensor strtarget, and take into account the factor strfact
1130 : : !!
1131 : : !! INPUTS
1132 : : !! fcart(3,natom)= forces on atoms in hartree/bohr in cartesian coordinates
1133 : : !! iatfix(3,natom)=1 for frozen atom, 0 for unfrozen
1134 : : !! itime=current number of Broyden/Moldyn iterations
1135 : : !! natom=number of atoms in unit cell
1136 : : !! ntime=maximum number of Broyden/Moldyn iterations allowed
1137 : : !! optcell=option for taking stresses into account (see above)
1138 : : !! strfact=factor that multiplies the stresses when they are compared to forces.
1139 : : !! strtarget(6)=components of the target stress tensor (hartree/bohr^3)
1140 : : !! strten(6)=components of the stress tensor (hartree/bohr^3)
1141 : : !! tolmxf=tolerance on maximal absolute value of components of forces
1142 : : !!
1143 : : !! OUTPUT
1144 : : !! writes to unit std_out and to ab_out, and returns
1145 : : !!
1146 : : !! SIDE EFFECTS
1147 : : !! Input/Output
1148 : : !! at input : iexit= 0 if not the last itime, 1 if the last itime
1149 : : !! at output : iexit= 0 if not below tolerance, 1 if below tolerance
1150 : : !!
1151 : : !! SOURCE
1152 : :
1153 : 1326 : subroutine fconv(fcart,iatfix,iexit,itime,natom,ntime,optcell,strfact,strtarget,strten,rprim,tolmxf)
1154 : :
1155 : : !Arguments ------------------------------------
1156 : : !scalars
1157 : : integer,intent(in) :: itime,natom,ntime,optcell
1158 : : integer,intent(inout) :: iexit
1159 : : real(dp),intent(in) :: strfact,tolmxf
1160 : : !arrays
1161 : : integer,intent(in) :: iatfix(3,natom)
1162 : : real(dp),intent(in) :: fcart(3,natom),strtarget(6),strten(6)
1163 : : real(dp), intent(in) :: rprim(3,3)
1164 : :
1165 : : !Local variables-------------------------------
1166 : : !scalars
1167 : : integer :: iatom,idir,istr
1168 : : real(dp) :: fmax,strdiag,fcell
1169 : : character(len=500) :: msg
1170 : : !arrays
1171 : : real(dp) :: dstr(6)
1172 : :
1173 : : ! *************************************************************************
1174 : :
1175 : : ABI_UNUSED(rprim)
1176 : :
1177 : : !Compute maximal component of forces, EXCLUDING any fixed components
1178 : 1326 : fmax=zero
1179 [ + + ]: 5158 : do iatom=1,natom
1180 [ + + ]: 16654 : do idir=1,3
1181 [ + + ]: 15328 : if (iatfix(idir,iatom) /= 1) then
1182 [ + + ]: 10470 : if( abs(fcart(idir,iatom)) >= fmax ) fmax=abs(fcart(idir,iatom))
1183 : : end if
1184 : : end do
1185 : : end do
1186 : :
1187 [ + + ]: 9282 : dstr(:)=strten(:)-strtarget(:)
1188 : :
1189 : : !Eventually take into account the stress
1190 [ + - + + : 1326 : if(optcell==1)then
+ + + - +
+ ]
1191 : 226 : strdiag=(dstr(1)+dstr(2)+dstr(3))/3.0_dp
1192 [ + + ]: 226 : if(abs(strdiag)*strfact >= fmax ) fmax=abs(strdiag)*strfact
1193 : : else if(optcell==2)then
1194 [ + + ]: 938 : do istr=1,6
1195 [ + + ]: 938 : if(abs(dstr(istr))*strfact >= fmax ) fmax=abs(dstr(istr))*strfact
1196 : : end do
1197 : : else if(optcell==3)then
1198 : : ! Must take away the trace from diagonal elements
1199 : 14 : strdiag=(dstr(1)+dstr(2)+dstr(3))/3.0_dp
1200 [ + + ]: 56 : do istr=1,3
1201 [ + + ]: 56 : if(abs(dstr(istr)-strdiag)*strfact >= fmax ) fmax=abs(dstr(istr)-strdiag)*strfact
1202 : : end do
1203 [ + + ]: 56 : do istr=4,6
1204 [ + + ]: 56 : if(abs(dstr(istr))*strfact >= fmax ) fmax=abs(dstr(istr))*strfact
1205 : : end do
1206 : : ! else if(optcell==4 .or. optcell==5 .or. optcell==6)then
1207 : : ! if(abs(dstr(optcell-3))*strfact >= fmax ) fmax=abs(dstr(optcell-3))*strfact
1208 : : else if(optcell==4) then
1209 : : ! Only the first lattice vector is relaxed. Check the three stress components
1210 : : ! conjugate to its generalized coordinates, consistently with xfpack_f2vout.
1211 [ - + + - : 50 : fcell = maxval(abs(dstr([1,5,6]))) * strfact
+ + ]
1212 [ + + ]: 10 : if (fcell >= fmax) fmax=fcell
1213 : : else if(optcell==5) then
1214 : : ! Only the second lattice vector is relaxed.
1215 [ # # # # : 0 : fcell = maxval(abs(dstr([2,4,6]))) * strfact
# # ]
1216 [ # # ]: 0 : if (fcell >= fmax) fmax=fcell
1217 : : else if(optcell==6) then
1218 : : ! Only the third lattice vector is relaxed.
1219 [ - + + - : 35 : fcell = maxval(abs(dstr([3,4,5]))) * strfact
+ + ]
1220 [ + - ]: 7 : if (fcell >= fmax) fmax=fcell
1221 : : else if(optcell==7)then
1222 [ + - ]: 14 : if(abs(dstr(2))*strfact >= fmax ) fmax=abs(dstr(2))*strfact
1223 [ + + ]: 14 : if(abs(dstr(3))*strfact >= fmax ) fmax=abs(dstr(3))*strfact
1224 [ + + ]: 14 : if(abs(dstr(4))*strfact >= fmax ) fmax=abs(dstr(4))*strfact
1225 : : else if(optcell==8)then
1226 [ # # ]: 0 : if(abs(dstr(1))*strfact >= fmax ) fmax=abs(dstr(1))*strfact
1227 [ # # ]: 0 : if(abs(dstr(3))*strfact >= fmax ) fmax=abs(dstr(3))*strfact
1228 [ # # ]: 0 : if(abs(dstr(5))*strfact >= fmax ) fmax=abs(dstr(5))*strfact
1229 : : else if(optcell==9)then
1230 [ + - ]: 5 : if(abs(dstr(1))*strfact >= fmax ) fmax=abs(dstr(1))*strfact
1231 [ + + ]: 5 : if(abs(dstr(2))*strfact >= fmax ) fmax=abs(dstr(2))*strfact
1232 [ - + ]: 5 : if(abs(dstr(6))*strfact >= fmax ) fmax=abs(dstr(6))*strfact
1233 : : end if
1234 : :
1235 [ + + ]: 1326 : if (fmax<tolmxf) then
1236 : 220 : write(msg, '(a,a,i4,a,a,a,es11.4,a,es11.4,a,a)' ) ch10,&
1237 : 220 : ' At Broyd/MD step',itime,', gradients are converged : ',ch10,&
1238 : 440 : ' max grad (force/stress) =',fmax,' < tolmxf=',tolmxf,' ha/bohr (free atoms)',ch10
1239 [ + + ]: 660 : call wrtout([std_out, ab_out], msg)
1240 : 220 : iexit=1
1241 : : else
1242 [ + + ]: 1106 : if(iexit==1)then
1243 : 96 : write(msg, '(a,a,a,a,i5,a,a,a,es11.4,a,es11.4,a,a)' ) ch10,&
1244 : 96 : ' fconv : WARNING -',ch10,&
1245 : 96 : ' ntime=',ntime,' was not enough Broyd/MD steps to converge gradients: ',ch10,&
1246 : 192 : ' max grad (force/stress) =',fmax,' > tolmxf=',tolmxf,' ha/bohr (free atoms)',ch10
1247 [ + + ]: 288 : call wrtout([std_out, ab_out], msg)
1248 : :
1249 : 96 : write(std_out,"(8a)")ch10,&
1250 : 96 : "--- !RelaxConvergenceWarning",ch10,&
1251 [ + - ]: 96 : "message: | ",ch10,TRIM(indent(msg)),ch10,&
1252 : 192 : "..."
1253 : :
1254 : : else
1255 : : write(msg, '(a,i4,a,a,a,es11.4,a,es11.4,a,a)' ) &
1256 : 1010 : ' fconv : at Broyd/MD step',itime,', gradients have not converged yet. ',ch10,&
1257 : 2020 : ' max grad (force/stress) =',fmax,' > tolmxf=',tolmxf,' ha/bohr (free atoms)',ch10
1258 : 1010 : call wrtout(std_out,msg,'COLL')
1259 : : end if
1260 : 1106 : iexit=0
1261 : : end if
1262 : :
1263 : 1326 : end subroutine fconv
1264 : : !!***
1265 : :
1266 : : !!****f* ABINIT/erlxconv
1267 : : !! NAME
1268 : : !! erlxconv
1269 : : !!
1270 : : !! FUNCTION
1271 : : !! FIXME: add description.
1272 : : !!
1273 : : !! INPUTS
1274 : : !!
1275 : : !! OUTPUT
1276 : : !!
1277 : : !! SOURCE
1278 : :
1279 : 4 : subroutine erlxconv(hist,iexit,itime,itime_hist,ntime,tolmxde)
1280 : :
1281 : : !Arguments ------------------------------------
1282 : : !scalars
1283 : : integer,intent(in) :: itime,itime_hist,ntime
1284 : : integer,intent(inout) :: iexit
1285 : : real(dp), intent(in) :: tolmxde
1286 : : !arrays
1287 : : type(abihist),intent(inout) :: hist
1288 : :
1289 : : !Local variables-------------------------------
1290 : : integer :: ihist,ihist_prev,ihist_prev2
1291 : : real(dp) :: ediff1,ediff2,maxediff
1292 : : character(len=500) :: msg
1293 : : ! *************************************************************************
1294 : :
1295 [ + + ]: 4 : if (itime_hist<3) then
1296 : 2 : write(msg, '(a,a,a)' ) ch10,&
1297 : 4 : ' erlxconv : minimum 3 Broyd/MD steps to check convergence of energy in relaxations',ch10
1298 : 2 : call wrtout(std_out,msg,'COLL')
1299 : : else
1300 : 2 : ihist = hist%ihist
1301 : 2 : ihist_prev = abihist_findIndex(hist,-1)
1302 : 2 : ihist_prev2 = abihist_findIndex(hist,-2)
1303 : 2 : ediff1 = hist%etot(ihist) - hist%etot(ihist_prev)
1304 : 2 : ediff2 = hist%etot(ihist) - hist%etot(ihist_prev2)
1305 [ + - + + ]: 2 : if ((abs(ediff1)<tolmxde).and.(abs(ediff2)<tolmxde)) then
1306 : 1 : write(msg, '(a,a,i4,a,a,a,a,a,es11.4,a,a)' ) ch10,&
1307 : 1 : ' At Broyd/MD step',itime,', energy is converged : ',ch10,&
1308 : 1 : ' the difference in energy with respect to the two ',ch10,&
1309 : 2 : ' previous steps is < tolmxde=',tolmxde,' ha',ch10
1310 [ + + ]: 3 : call wrtout([std_out, ab_out], msg)
1311 : 1 : iexit=1
1312 : : else
1313 : 1 : maxediff = max(abs(ediff1),abs(ediff2))
1314 [ - + ]: 1 : if(iexit==1)then
1315 : 0 : write(msg, '(a,a,a,a,i5,a,a,a,es11.4,a,es11.4,a,a)' ) ch10,&
1316 : 0 : ' erlxconv : WARNING -',ch10,&
1317 : 0 : ' ntime=',ntime,' was not enough Broyd/MD steps to converge energy: ',ch10,&
1318 : 0 : ' max difference in energy =',maxediff,' > tolmxde=',tolmxde,' ha',ch10
1319 [ # # ]: 0 : call wrtout([std_out, ab_out], msg)
1320 : :
1321 : 0 : write(std_out,"(8a)")ch10,&
1322 : 0 : "--- !RelaxConvergenceWarning",ch10,&
1323 [ # # ]: 0 : "message: | ",ch10,TRIM(indent(msg)),ch10,&
1324 : 0 : "..."
1325 : : else
1326 : 1 : write(msg, '(a,a,i4,a,a,a,es11.4,a,es11.4,a,a)' ) ch10,&
1327 : 1 : ' erlxconv : at Broyd/MD step',itime,', energy has not converged yet. ',ch10,&
1328 : 2 : ' max difference in energy=',maxediff,' > tolmxde=',tolmxde,' ha',ch10
1329 : 1 : call wrtout(std_out,msg,'COLL')
1330 : : end if
1331 : : end if
1332 : : end if
1333 : :
1334 : 4 : end subroutine erlxconv
1335 : : !!***
1336 : :
1337 : : end subroutine mover
1338 : : !!***
1339 : :
1340 : : !!****f* ABINIT/prtxfase
1341 : : !!
1342 : : !! NAME
1343 : : !! prtxfase
1344 : : !!
1345 : : !! FUNCTION
1346 : : !! Print the values of xcart (X), forces (F) acell (A), Stresses (S), and energy (E)
1347 : : !! All values come from the history hist
1348 : : !! Also compute and print max and rms forces.
1349 : : !! Also compute absolute and relative differences with previous calculation
1350 : : !!
1351 : : !! INPUTS
1352 : : !! ab_mover<type abimover>=Subset of dtset only related with movement of ions and acell, contains:
1353 : : !! | dtion: Time step
1354 : : !! ! natom: Number of atoms
1355 : : !! | vis: viscosity
1356 : : !! | iatfix: Index of atoms and directions fixed
1357 : : !! | amass: Mass of ions
1358 : : !! hist<type abihist>=Historical record of positions, forces, stresses, cell and energies,
1359 : : !! itime= time step
1360 : : !! iout=unit number for printing
1361 : : !!
1362 : : !! OUTPUT
1363 : : !! (only writing)
1364 : : !!
1365 : : !! SOURCE
1366 : :
1367 : 4882 : subroutine prtxfase(ab_mover,hist,itime,iout,pos)
1368 : :
1369 : : !Arguments ------------------------------------
1370 : : !scalars
1371 : : type(abimover),intent(in) :: ab_mover
1372 : : type(abihist),intent(in),target :: hist
1373 : : integer,intent(in) :: itime,iout
1374 : : integer,intent(in) :: pos
1375 : : !arrays
1376 : :
1377 : : !Local variables-------------------------------
1378 : : !scalars
1379 : : integer :: jj,kk,unfixd,iprt
1380 : : real(dp) :: val_max,val_rms,ucvol ! Values maximal and RMS, Volume of Unitary cell
1381 : : real(dp) :: dEabs,dErel ! Diff of energy absolute and relative
1382 : : real(dp) :: ekin
1383 : : real(dp) :: angle(3),rmet(3,3)
1384 : : !character(len=80*(max(ab_mover%natom,3)+1)) :: msg
1385 : : !MGNAG: This is not very safe. One should use line-based output istead of appending chars
1386 : : ! and then outputting everything! For the time being I use this temporary hack to solve the problem with NAG
1387 : 4882 : character(len=max(80*(max(ab_mover%natom,3)+1),50000)) :: msg
1388 : : character(len=18) :: fmt1
1389 : : logical :: prtallatoms
1390 : : !arrays
1391 : 9764 : logical :: atlist(ab_mover%natom)
1392 : 4882 : real(dp),allocatable :: gred(:,:),xcart(:,:)
1393 : 4882 : real(dp),pointer :: acell(:),fcart(:,:),rprimd(:,:),strten(:),vel(:,:),xred(:,:)
1394 : :
1395 : : ! ***********************************************************
1396 : :
1397 : 4882 : fmt1='(a,a,1p,3e22.14)'
1398 : :
1399 : : !##########################################################
1400 : : !### 1. Organize list of atoms to print
1401 : :
1402 : 4882 : prtallatoms=.TRUE.
1403 [ + + ]: 29185 : do kk=1,ab_mover%natom
1404 [ + + ]: 29185 : if (ab_mover%prtatlist(kk)/=kk) prtallatoms=.FALSE.
1405 : : end do
1406 : :
1407 [ + + ]: 29185 : atlist(:)=.FALSE.
1408 [ + + ]: 29185 : do iprt=1,ab_mover%natom
1409 [ + + + - ]: 29185 : if (ab_mover%prtatlist(iprt)>0.and.ab_mover%prtatlist(iprt)<=ab_mover%natom) atlist(ab_mover%prtatlist(iprt))=.TRUE.
1410 : : end do
1411 : :
1412 : 4882 : acell => hist%acell(:,hist%ihist)
1413 : 4882 : rprimd => hist%rprimd(:,:,hist%ihist)
1414 : 4882 : xred => hist%xred(:,:,hist%ihist)
1415 : 4882 : fcart => hist%fcart(:,:,hist%ihist)
1416 : 4882 : strten => hist%strten(:,hist%ihist)
1417 : 4882 : vel => hist%vel(:,:,hist%ihist)
1418 : :
1419 : : !###########################################################
1420 : : !### 1. Positions
1421 : :
1422 [ - + + - : 14646 : ABI_MALLOC(xcart,(3,ab_mover%natom))
+ - + - -
+ - + ]
1423 [ - + - + ]: 4882 : call xred2xcart(ab_mover%natom,rprimd,xcart,xred)
1424 : :
1425 : 4882 : write(msg, '(a,a)' )ch10,' Cartesian coordinates (xcart) [bohr]'
1426 : 4882 : call prtnatom(atlist,iout,msg,ab_mover%natom,prtallatoms,xcart)
1427 : :
1428 : 4882 : write(msg, '(a)' )' Reduced coordinates (xred)'
1429 [ - + ]: 4882 : call prtnatom(atlist,iout,msg,ab_mover%natom,prtallatoms,xred)
1430 : :
1431 [ - + ]: 4882 : ABI_FREE(xcart)
1432 : :
1433 : : !###########################################################
1434 : : !### 2. Forces
1435 : :
1436 [ + + ]: 4882 : if(pos==mover_AFTER)then
1437 : :
1438 [ - + + - : 9744 : ABI_MALLOC(gred,(3,ab_mover%natom))
+ - + - -
+ - + ]
1439 [ - + - + ]: 3248 : call fcart2gred(fcart,gred,rprimd,ab_mover%natom)
1440 : :
1441 : : ! Compute max |f| and rms f,
1442 : : ! EXCLUDING the components determined by iatfix
1443 : 3248 : val_max=0.0_dp
1444 : 3248 : val_rms=0.0_dp
1445 : 3248 : unfixd=0
1446 [ + + ]: 19410 : do kk=1,ab_mover%natom
1447 [ + + ]: 67896 : do jj=1,3
1448 [ + + ]: 64648 : if (ab_mover%iatfix(jj,kk) /= 1) then
1449 : 45690 : unfixd=unfixd+1
1450 : 45690 : val_rms=val_rms+fcart(jj,kk)**2
1451 : 45690 : val_max=max(val_max,abs(fcart(jj,kk)**2))
1452 : : end if
1453 : : end do
1454 : : end do
1455 [ + - ]: 3248 : if ( unfixd /= 0 ) val_rms=sqrt(val_rms/dble(unfixd))
1456 : :
1457 : 3248 : write(msg, '(a,1p,2e12.5,a)' ) ' Cartesian forces (fcart) [Ha/bohr]; max,rms=',sqrt(val_max),val_rms,' (free atoms)'
1458 [ - + ]: 3248 : call prtnatom(atlist,iout,msg,ab_mover%natom,prtallatoms,fcart)
1459 : :
1460 : 3248 : write(msg, '(a)' )' Gradient of E wrt nuclear positions in reduced coordinates (gred)'
1461 : 3248 : call prtnatom(atlist,iout,msg,ab_mover%natom,prtallatoms,gred)
1462 [ - + ]: 3248 : ABI_FREE(gred)
1463 : : end if
1464 : :
1465 : : !###########################################################
1466 : : !### 3. Velocities
1467 : :
1468 : : !Only if the velocities are being used
1469 [ + + ]: 4882 : if (hist%isVused)then
1470 : : ! Only if velocities are recorded in a history
1471 [ + - ]: 1219 : if (allocated(hist%vel))then
1472 : : ! Compute max |v| and rms v,
1473 : : ! EXCLUDING the components determined by iatfix
1474 : 1219 : val_max=0.0_dp
1475 : 1219 : val_rms=0.0_dp
1476 : 1219 : unfixd=0
1477 [ + + ]: 17038 : do kk=1,ab_mover%natom
1478 [ + + ]: 64495 : do jj=1,3
1479 [ + + ]: 63276 : if (ab_mover%iatfix(jj,kk) /= 1) then
1480 : 45864 : unfixd=unfixd+1
1481 : 45864 : val_rms=val_rms+vel(jj,kk)**2
1482 : 45864 : val_max=max(val_max,abs(vel(jj,kk)**2))
1483 : : end if
1484 : : end do
1485 : : end do
1486 [ + - ]: 1219 : if ( unfixd /= 0 ) val_rms=sqrt(val_rms/dble(unfixd))
1487 : :
1488 : : write(msg, '(a,1p,2e12.5,a)' ) &
1489 : 1219 : & ' Cartesian velocities (vel) [bohr*Ha/hbar]; max,rms=',sqrt(val_max),val_rms,' (free atoms)'
1490 [ - + ]: 1219 : call prtnatom(atlist,iout,msg,ab_mover%natom,prtallatoms,vel)
1491 : :
1492 : : ! Compute the ionic kinetic energy (no cell shape kinetic energy yet)
1493 : 1219 : ekin=0.0_dp
1494 [ + + ]: 17038 : do kk=1,ab_mover%natom
1495 [ + + ]: 64495 : do jj=1,3
1496 : : ! Warning : the fixing of atoms is implemented in reduced
1497 : : ! coordinates, so that this expression is wrong
1498 [ + + ]: 63276 : if (ab_mover%iatfix(jj,kk) == 0) then
1499 : 45864 : ekin=ekin+0.5_dp*ab_mover%amass(kk)*vel(jj,kk)**2
1500 : : end if
1501 : : end do
1502 : : end do
1503 : 1219 : write(msg, '(a,1p,e22.14,a)' )' Kinetic energy of ions (ekin) [Ha]=',ekin
1504 : 1219 : call wrtout(iout,msg,'COLL')
1505 : : end if
1506 : : end if
1507 : :
1508 : : !###########################################################
1509 : : !### 3. ACELL
1510 : :
1511 : : !Only if the acell is being used
1512 [ + + ]: 4882 : if (hist%isARused)then
1513 : : ! Only if acell is recorded in a history
1514 [ + - ]: 1286 : if (allocated(hist%acell))then
1515 : 1286 : write(msg, '(a)' )' Scale of Primitive Cell (acell) [bohr]'
1516 : 1286 : write(msg,fmt1)TRIM(msg),ch10,acell(:)
1517 : 1286 : call wrtout(iout,msg,'COLL')
1518 : : end if
1519 : : end if
1520 : :
1521 : : !###########################################################
1522 : : !### 4. RPRIMD
1523 : :
1524 : : !Only if the acell is being used
1525 [ + + ]: 4882 : if (hist%isARused)then
1526 : : ! Only if rprimd is recorded in a history
1527 [ + - ]: 1286 : if (allocated(hist%rprimd))then
1528 : 1286 : write(msg, '(a)' )' Real space primitive translations (rprimd) [bohr]'
1529 [ + + ]: 5144 : do kk=1,3
1530 : 5144 : write(msg,fmt1)TRIM(msg),ch10,rprimd(:,kk)
1531 : : end do
1532 : 1286 : call wrtout(iout,msg,'COLL')
1533 : : end if
1534 : : end if
1535 : :
1536 : : !###########################################################
1537 : : !### 5. Unitary cell volume
1538 : :
1539 [ + + ]: 4882 : if (ab_mover%optcell/=0)then
1540 : :
1541 : : ucvol=&
1542 : : & rprimd(1,1)*(rprimd(2,2)*rprimd(3,3)-rprimd(3,2)*rprimd(2,3))+&
1543 : : & rprimd(2,1)*(rprimd(3,2)*rprimd(1,3)-rprimd(1,2)*rprimd(3,3))+&
1544 : 1223 : & rprimd(3,1)*(rprimd(1,2)*rprimd(2,3)-rprimd(2,2)*rprimd(1,3))
1545 : :
1546 : 1223 : write(msg, '(a,1p,e22.14)' )' Unitary Cell Volume (ucvol) [Bohr^3]=',ucvol
1547 : 1223 : call wrtout(iout,msg,'COLL')
1548 : :
1549 : : ! ###########################################################
1550 : : ! ### 5. Angles and lengths
1551 : :
1552 : : ! Compute real space metric.
1553 [ + - + + : 81941 : rmet = MATMUL(TRANSPOSE(rprimd),rprimd)
+ + + + +
- + - ]
1554 : :
1555 : 1223 : angle(1)=acos(rmet(2,3)/sqrt(rmet(2,2)*rmet(3,3)))/two_pi*360.0d0
1556 : 1223 : angle(2)=acos(rmet(1,3)/sqrt(rmet(1,1)*rmet(3,3)))/two_pi*360.0d0
1557 : 1223 : angle(3)=acos(rmet(1,2)/sqrt(rmet(1,1)*rmet(2,2)))/two_pi*360.0d0
1558 : :
1559 : 1223 : write(msg, '(a)' )' Angles (23,13,12)= [degrees]'
1560 : 1223 : write(msg,fmt1)TRIM(msg),ch10,angle(:)
1561 : 1223 : call wrtout(iout,msg,'COLL')
1562 : :
1563 : 1223 : write(msg, '(a)' ) ' Lengths [Bohr]'
1564 : 1223 : write(msg,fmt1)TRIM(msg),ch10,sqrt(rmet(1,1)),sqrt(rmet(2,2)),sqrt(rmet(3,3))
1565 : 1223 : call wrtout(iout,msg,'COLL')
1566 : :
1567 : : ! ###########################################################
1568 : : ! ### 5. Stress Tensor
1569 : :
1570 [ + + ]: 1223 : if(pos==mover_AFTER)then
1571 : : ! Only if strten is recorded in a history
1572 [ + - ]: 812 : if (allocated(hist%strten))then
1573 : :
1574 : 812 : write(msg, '(a)' ) ' Stress tensor in cartesian coordinates (strten) [Ha/bohr^3]'
1575 : :
1576 : 812 : write(msg,fmt1)TRIM(msg),ch10,strten(1),strten(6),strten(5)
1577 : 812 : write(msg,fmt1)TRIM(msg),ch10,strten(6),strten(2),strten(4)
1578 : 812 : write(msg,fmt1)TRIM(msg),ch10,strten(5),strten(4),strten(3)
1579 : 812 : call wrtout(iout,msg,'COLL')
1580 : : end if
1581 : : end if
1582 : : end if
1583 : :
1584 : : !###########################################################
1585 : : !### 6. Energy
1586 : :
1587 [ + + ]: 9764 : if(pos==mover_AFTER)then
1588 : 3248 : write(msg, '(a,1p,e22.14)' )' Total energy (etotal) [Ha]=',hist%etot(hist%ihist)
1589 : :
1590 [ + + ]: 3248 : if (itime>1)then
1591 : 2554 : jj = abihist_findIndex(hist,-1)
1592 : 2554 : dEabs=hist%etot(hist%ihist)-hist%etot(jj)
1593 : 2554 : dErel=2*dEabs/(abs(hist%etot(hist%ihist))+abs(hist%etot(jj)))
1594 : 2554 : write(msg, '(a,a,a,a)' )TRIM(msg),ch10,ch10,' Difference of energy with previous step (new-old):'
1595 : : write(msg, '(a,a,10a,a,1p,e12.5,a,10a,a,1p,e12.5)')&
1596 : 2554 : TRIM(msg),ch10,&
1597 [ + + ]: 30648 : (' ',jj=1,10),' Absolute (Ha)=',dEabs,ch10,&
1598 [ + - + - : 58742 : (' ',jj=1,10),' Relative =',dErel
+ + ]
1599 : : end if
1600 : 3248 : call wrtout(iout,msg,'COLL')
1601 : : end if
1602 : :
1603 : : contains
1604 : : !!***
1605 : :
1606 : : !!****f* ABINIT/gettag
1607 : : !!
1608 : : !! NAME
1609 : : !! gettag
1610 : : !!
1611 : : !! FUNCTION
1612 : : !! Set the tag associated to each atom,
1613 : : !!
1614 : : !! INPUTS
1615 : : !! prtallatoms = Logical for PRTint ALL ATOMS
1616 : : !! atlist = ATom LIST
1617 : : !! index = index for each atom
1618 : : !! natom = Number of ATOMs
1619 : : !!
1620 : : !! OUTPUT
1621 : : !! tag = The string to put for each atom
1622 : : !!
1623 : : !! SOURCE
1624 : :
1625 : 86999 : subroutine gettag(atlist,index,natom,prtallatoms,tag)
1626 : :
1627 : : !Arguments ------------------------------------
1628 : : !scalars
1629 : : logical,intent(in) :: prtallatoms
1630 : : integer,intent(in) :: natom
1631 : : logical,intent(in) :: atlist(natom)
1632 : : integer,intent(in) :: index
1633 : : character(len=7),intent(out) :: tag
1634 : :
1635 : : ! *********************************************************************
1636 : : !The numbering will be from (1) to (9999)
1637 : :
1638 [ + + ]: 86999 : if (prtallatoms)then
1639 : 84269 : tag=''
1640 [ + - ]: 2730 : elseif (atlist(index)) then
1641 [ - + ]: 2730 : if (natom<10) then
1642 : 0 : write(tag, '(a,I1.1,a)') ' (',index,')'
1643 [ + - ]: 2730 : elseif (natom<100) then
1644 : 2730 : write(tag, '(a,I2.2,a)') ' (',index,')'
1645 [ # # ]: 0 : elseif (natom<1000) then
1646 : 0 : write(tag, '(a,I3.3,a)') ' (',index,')'
1647 [ # # ]: 0 : elseif (natom<10000) then
1648 : 0 : write(tag, '(a,I4.4,a)') ' (',index,')'
1649 : : end if
1650 : : end if
1651 : :
1652 : 86999 : end subroutine gettag
1653 : : !!***
1654 : :
1655 : : !!****f* ABINIT/prtnatom
1656 : : !!
1657 : : !! NAME
1658 : : !! prtnatom
1659 : : !!
1660 : : !! FUNCTION
1661 : : !! Print information for N atoms
1662 : : !!
1663 : : !! INPUTS
1664 : : !! prtallatoms = Logical for PRTint ALL ATOMS
1665 : : !! atlist = ATom LIST
1666 : : !! index = index for each atom
1667 : : !! natom = Number of ATOMs
1668 : : !!
1669 : : !! OUTPUT
1670 : : !! tag = The string to put for aech atom
1671 : : !!
1672 : : !! SOURCE
1673 : :
1674 : :
1675 : 17479 : subroutine prtnatom(atlist,iout,message,natom,prtallatoms,thearray)
1676 : :
1677 : : !Arguments ------------------------------------
1678 : : !scalars
1679 : : logical,intent(in) :: prtallatoms
1680 : : integer,intent(in) :: natom
1681 : : logical,intent(in) :: atlist(natom)
1682 : : integer,intent(in) :: iout
1683 : : character(len=*),intent(inout) :: message
1684 : : !arrays
1685 : : real(dp) :: thearray(3,natom)
1686 : :
1687 : : !Local variables-------------------------------
1688 : : !scalars
1689 : : integer :: kk
1690 : : character(len=7) :: tag ! Maximal ' (9999)'
1691 : : character(len=18) :: fmt
1692 : :
1693 : : ! *********************************************************************
1694 : :
1695 : 17479 : fmt='(a,a,1p,3e22.14,a)'
1696 : :
1697 [ + + ]: 114228 : do kk=1,natom
1698 [ + + ]: 114228 : if (atlist(kk)) then
1699 : 86999 : call gettag(atlist,kk,natom,prtallatoms,tag)
1700 : 86999 : write(message,fmt)TRIM(message),ch10,thearray(:,kk),tag
1701 : : end if
1702 : : end do
1703 : 17479 : call wrtout(iout,message,'COLL')
1704 : :
1705 : 17479 : end subroutine prtnatom
1706 : : !!***
1707 : :
1708 : : end subroutine prtxfase
1709 : : !!***
1710 : :
1711 : : !!****f* ABINIT/wrt_moldyn_netcdf
1712 : : !! NAME
1713 : : !! wrt_moldyn_netcdf
1714 : : !!
1715 : : !! FUNCTION
1716 : : !! Write two files for later molecular dynamics analysis:
1717 : : !! - MOLDYN.nc (netcdf format) : evolution of key quantities with time (pressure, energy, ...)
1718 : : !! - POSABIN : values of coordinates and velocities for the next time step
1719 : : !!
1720 : : !! INPUTS
1721 : : !! amass(natom)=mass of each atom, in unit of electronic mass (=amu*1822...)
1722 : : !! dtset <type(dataset_type)>=all input variables for this dataset
1723 : : !! itime=time step index
1724 : : !! option=1: write MOLDYN.nc file (netcdf format)
1725 : : !! 2: write POSABIN file
1726 : : !! 3: write both
1727 : : !! moldyn_file=name of the MD netcdf file
1728 : : !! mpi_enreg=information about MPI parallelization
1729 : : !! results_gs <type(results_gs_type)>=results (energy and its components,
1730 : : !! forces and its components, the stress tensor) of a ground-state computation
1731 : : !! rprimd(3,3)=real space primitive translations
1732 : : !! unpos=unit number for POSABIN file
1733 : : !! vel(3,natom)=velocities of atoms
1734 : : !! xred(3,natom)=reduced coordinates of atoms
1735 : : !!
1736 : : !! OUTPUT
1737 : : !! -- only printing --
1738 : : !!
1739 : : !! SIDE EFFECTS
1740 : : !!
1741 : : !! SOURCE
1742 : :
1743 : 32 : subroutine wrt_moldyn_netcdf(amass,dtset,itime,option,moldyn_file,mpi_enreg,&
1744 : 32 : & results_gs,rprimd,unpos,vel,xred)
1745 : :
1746 : : use defs_basis
1747 : : use defs_abitypes
1748 : : use m_results_gs
1749 : : use m_abicore
1750 : : use m_errors
1751 : : use netcdf
1752 : :
1753 : : use m_io_tools, only : open_file, get_unit
1754 : : use m_geometry, only : xcart2xred, xred2xcart, metric
1755 : :
1756 : : !Arguments ------------------------------------
1757 : : !scalars
1758 : : integer,intent(in) :: itime,option,unpos
1759 : : character(fnlen),intent(in) :: moldyn_file
1760 : : type(dataset_type),intent(in) :: dtset
1761 : : type(MPI_type),intent(in) :: mpi_enreg
1762 : : type(results_gs_type),intent(in) :: results_gs
1763 : : !arrays
1764 : : real(dp),intent(in) :: amass(dtset%natom),rprimd(3,3)
1765 : : real(dp),intent(in),target :: vel(3,dtset%natom)
1766 : : real(dp),intent(in) :: xred(3,dtset%natom)
1767 : :
1768 : : !Local variables-------------------------------
1769 : : !scalars
1770 : : integer,save :: ipos=0
1771 : : integer :: iatom,ii
1772 : : character(len=500) :: msg
1773 : : integer :: AtomNumDimid,AtomNumId,CelId,CellVolumeId,DimCoordid,DimScalarid,DimVectorid
1774 : : integer :: EkinDimid,EkinId,EpotDimid,EpotId,EntropyDimid,EntropyId,MassDimid,MassId,NbAtomsid
1775 : : integer :: ncerr,ncid,PosId,StressDimid,StressId,TensorSymDimid
1776 : : integer :: TimeDimid,TimestepDimid,TimestepId
1777 : : logical :: atom_fix
1778 : : real(dp) :: ekin,ucvol
1779 : : character(len=fnlen) :: ficname
1780 : : character(len=16) :: chain
1781 : : !arrays
1782 : : integer :: PrimVectId(3)
1783 : : real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3)
1784 : 32 : real(dp),allocatable :: xcart(:,:)
1785 : 32 : real(dp),pointer :: vcart(:,:),vred(:,:),vtmp(:,:)
1786 : : ! *************************************************************************
1787 : :
1788 : : !Only done by master processor, every nctime step
1789 [ + - ]: 26 : if (mpi_enreg%me==0.and.dtset%nctime>0) then
1790 : :
1791 : : ! Netcdf file name
1792 [ + - ]: 26 : ficname = trim(moldyn_file)//'.nc'
1793 : :
1794 : : ! Xcart from Xred
1795 [ - + + - : 78 : ABI_MALLOC(xcart,(3,dtset%natom))
+ - + - -
+ - + -
+ ]
1796 : 26 : call xred2xcart(dtset%natom,rprimd,xcart,xred)
1797 : :
1798 : : ! ==========================================================================
1799 : : ! First time step: write header of netcdf file
1800 : : ! ==========================================================================
1801 [ + + + - ]: 26 : if (itime==1.and.(option==1.or.option==3)) then
1802 : :
1803 : 5 : ipos=0
1804 : :
1805 : : ! Write message
1806 : 5 : write(msg,'(4a)')ch10,' Open file ',trim(ficname),' to store molecular dynamics information.'
1807 : 5 : call wrtout(std_out,msg,'COLL')
1808 : :
1809 : : ! Create netcdf file
1810 : 5 : ncerr = nf90_create(ficname, NF90_CLOBBER , ncid)
1811 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_create')
1812 : :
1813 : : ! Dimension time for netcdf (time dim is unlimited)
1814 : 5 : ncerr = nf90_def_dim(ncid, "time", nf90_unlimited, TimeDimid)
1815 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_dim')
1816 : :
1817 : : ! Symetric Tensor Dimension
1818 : 5 : ncerr = nf90_def_dim(ncid, "DimTensor", size(results_gs%strten), TensorSymDimid)
1819 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_dim')
1820 : :
1821 : : ! Coordinates Dimension
1822 : 5 : ncerr = nf90_def_dim(ncid, "DimCoord", size(xcart,1), DimCoordid)
1823 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_dim')
1824 : :
1825 : : ! Atoms Dimensions
1826 : 5 : ncerr = nf90_def_dim(ncid, "NbAtoms", dtset%natom, NbAtomsid)
1827 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_dim')
1828 : :
1829 : : ! Vector Dimension
1830 : 5 : ncerr = nf90_def_dim(ncid, "DimVector", 3 , DimVectorid)
1831 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_dim')
1832 : :
1833 : : ! Scalar Dimension
1834 : 5 : ncerr = nf90_def_dim(ncid, "DimScalar", 1 , DimScalarid)
1835 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_dim')
1836 : :
1837 : : ! Time step and time unit
1838 : 5 : ncerr = nf90_def_var(ncid, "Time_step", nf90_double , DimScalarid, TimestepDimid)
1839 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1840 : 5 : ncerr = nf90_put_att(ncid, TimestepDimid, "units", "atomic time unit")
1841 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_put_att')
1842 : :
1843 : : ! Ionic masses
1844 : 5 : ncerr = nf90_def_var(ncid, "Ionic_Mass", nf90_double , NbAtomsid, MassDimid)
1845 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1846 : 5 : ncerr = nf90_put_att(ncid, MassDimid, "units", "atomic mass unit")
1847 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_put_att')
1848 : :
1849 : : ! Ionic atomic numbers
1850 : 5 : ncerr = nf90_def_var(ncid, "Ionic_Atomic_Number", nf90_double , NbAtomsid, AtomNumDimid)
1851 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1852 : :
1853 : : ! E_pot
1854 : 5 : ncerr = nf90_def_var(ncid, "E_pot", nf90_double , TimeDimid, EpotDimid)
1855 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1856 : 5 : ncerr = nf90_put_att(ncid, EpotDimid, "units", "hartree")
1857 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_put_att')
1858 : :
1859 : : ! E_kin
1860 : 5 : ncerr = nf90_def_var(ncid, "E_kin", nf90_double , TimeDimid, EkinDimid)
1861 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1862 : 5 : ncerr = nf90_put_att(ncid, EkinDimid, "units", "hartree")
1863 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_put_att')
1864 : :
1865 : : ! Entropy
1866 : 5 : ncerr = nf90_def_var(ncid, "Entropy", nf90_double , TimeDimid, EntropyDimid)
1867 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1868 : 5 : ncerr = nf90_put_att(ncid, EntropyDimid, "units", "")
1869 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_put_att')
1870 : :
1871 : : ! Stress tensor
1872 [ + + ]: 15 : ncerr = nf90_def_var(ncid, "Stress", nf90_double , (/TensorSymDimid,TimeDimid/), StressDimid)
1873 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1874 : 5 : ncerr = nf90_put_att(ncid, StressDimid, "units", "hartree/bohr^3")
1875 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_put_att')
1876 : :
1877 : : ! Positions
1878 [ + + ]: 20 : ncerr = nf90_def_var(ncid, "Position", nf90_double ,(/DimCoordid,NbAtomsid,TimeDimid/), PosId)
1879 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1880 : 5 : ncerr = nf90_put_att(ncid, PosId, "units", "bohr")
1881 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_put_att')
1882 : :
1883 : : ! Celerities
1884 [ + + ]: 20 : ncerr = nf90_def_var(ncid, "Celerity", nf90_double ,(/DimCoordid,NbAtomsid,TimeDimid/), CelId)
1885 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1886 : 5 : ncerr = nf90_put_att(ncid, CelId, "units", "bohr/(atomic time unit)")
1887 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_put_att')
1888 : :
1889 : : ! In case of volume cell constant
1890 [ + - ]: 5 : if (dtset%optcell==0) then
1891 : : ! Primitive vectors
1892 [ + + ]: 20 : do ii = 1,3
1893 : 15 : write(unit=chain,fmt='(a15,i1)') "PrimitiveVector",ii
1894 : 15 : ncerr = nf90_def_var(ncid, trim(chain), nf90_double , DimVectorid, PrimVectId(ii))
1895 [ - + ]: 20 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1896 : : end do
1897 : : ! Cell Volume
1898 : 5 : ncerr = nf90_def_var(ncid, "Cell_Volume", nf90_double , DimScalarid, CellVolumeId)
1899 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_def_var')
1900 : 5 : ncerr = nf90_put_att(ncid, CellVolumeId, "units", "bohr^3")
1901 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_put_att')
1902 : : end if
1903 : :
1904 : : ! Leave define mode and close file
1905 : 5 : ncerr = nf90_enddef(ncid)
1906 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_enddef')
1907 : 5 : ncerr = nf90_close(ncid)
1908 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_close')
1909 : : end if
1910 : :
1911 : : ! ==========================================================================
1912 : : ! Write data to netcdf file (every nctime time step)
1913 : : ! ==========================================================================
1914 [ + + + - ]: 26 : if (mod(itime, dtset%nctime)==0.and.(option==1.or.option==3)) then
1915 : :
1916 : 10 : ipos=ipos+1
1917 : :
1918 : : ! Write message
1919 : 10 : write(msg,'(3a)')ch10,' Store molecular dynamics information in file ',trim(ficname)
1920 : 10 : call wrtout(std_out,msg,'COLL')
1921 : :
1922 : : ! Open netcdf file
1923 : 10 : ncerr = nf90_open(ficname, nf90_write, ncid)
1924 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_open')
1925 : :
1926 : : ! Time step
1927 : 10 : ncerr = nf90_inq_varid(ncid, "Time_step", TimestepId)
1928 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
1929 : 10 : ncerr = nf90_put_var(ncid, TimestepId, dtset%dtion)
1930 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
1931 : :
1932 : : ! Ionic masses
1933 : 10 : ncerr = nf90_inq_varid(ncid, "Ionic_Mass", MassId)
1934 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
1935 [ + + ]: 20 : ncerr = nf90_put_var(ncid, MassId, amass, start = (/ 1 /), count=(/dtset%natom/))
1936 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
1937 : :
1938 : : ! Ionic atomic numbers
1939 : 10 : ncerr = nf90_inq_varid(ncid, "Ionic_Atomic_Number", AtomNumId)
1940 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
1941 [ + - + + : 100 : ncerr = nf90_put_var(ncid, AtomNumId, dtset%znucl(dtset%typat(:)),start=(/1/),count=(/dtset%natom/))
+ - + + +
+ ]
1942 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
1943 : :
1944 : : ! Epot
1945 : 10 : ncerr = nf90_inq_varid(ncid, "E_pot", EpotId)
1946 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
1947 [ + + + + ]: 30 : ncerr = nf90_put_var(ncid, EpotId, (/results_gs%etotal/), start=(/ipos/),count=(/1/))
1948 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
1949 : :
1950 : : ! Ekin
1951 [ + + + + ]: 170 : ekin=zero;atom_fix=(maxval(dtset%iatfix)>0)
1952 [ + - + - ]: 10 : if (dtset%ionmov==1.or.(.not.atom_fix)) then
1953 : 10 : vcart => vel
1954 : : else
1955 [ # # # # : 0 : ABI_MALLOC(vcart,(3,dtset%natom))
# # # # ]
1956 [ # # # # : 0 : ABI_MALLOC(vred,(3,dtset%natom))
# # # # ]
1957 : 0 : vtmp => vel
1958 [ # # # # ]: 0 : call xcart2xred(dtset%natom,rprimd,vtmp,vred)
1959 [ # # ]: 0 : do iatom=1,dtset%natom
1960 [ # # ]: 0 : do ii=1,3
1961 [ # # ]: 0 : if (dtset%iatfix(ii,iatom)==1) vred(ii,iatom)=zero
1962 : : end do
1963 : : end do
1964 [ # # # # ]: 0 : call xred2xcart(dtset%natom,rprimd,vcart,vred)
1965 [ # # ]: 0 : ABI_FREE(vred)
1966 : : end if
1967 [ + + ]: 50 : do iatom=1,dtset%natom
1968 [ + + ]: 170 : do ii=1,3
1969 : 160 : ekin=ekin+half*amass(iatom)*vcart(ii,iatom)**2
1970 : : end do
1971 : : end do
1972 [ + - - + ]: 10 : if (dtset%ionmov/=1.and.atom_fix) then
1973 [ # # ]: 0 : ABI_FREE(vcart)
1974 : : end if
1975 : 10 : ncerr = nf90_inq_varid(ncid, "E_kin", EkinId)
1976 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
1977 [ + + + + ]: 30 : ncerr = nf90_put_var(ncid, EkinId, (/ekin/), start = (/ipos/),count=(/1/))
1978 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
1979 : :
1980 : : ! EntropyDimid
1981 : 10 : ncerr = nf90_inq_varid(ncid, "Entropy", EntropyId)
1982 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
1983 [ + + + + ]: 30 : ncerr = nf90_put_var(ncid, EntropyId, (/results_gs%energies%entropy/),start = (/ipos/),count=(/1/))
1984 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
1985 : :
1986 : : ! Stress tensor
1987 : 10 : ncerr = nf90_inq_varid(ncid, "Stress", StressId)
1988 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
1989 : : ncerr = nf90_put_var(ncid, StressId, results_gs%strten, &
1990 [ + + ]: 30 : & start=(/1,ipos/),count=(/size(results_gs%strten)/))
1991 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
1992 : :
1993 : : ! Positions
1994 : 10 : ncerr = nf90_inq_varid(ncid, "Position", PosId)
1995 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
1996 : : ncerr = nf90_put_var(ncid, PosId, xcart, start=(/1,1,ipos/), &
1997 [ + + + + ]: 70 : & count=(/size(xcart,1),dtset%natom,1/))
1998 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
1999 : :
2000 : : ! Celerities
2001 : 10 : ncerr = nf90_inq_varid(ncid, "Celerity", CelId)
2002 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
2003 : : ncerr = nf90_put_var(ncid, CelId, vel, start=(/1,1,ipos/), &
2004 [ + + + + ]: 70 : & count=(/size(vel,1),dtset%natom,1/) )
2005 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
2006 : :
2007 : : ! In case of volume cell constant
2008 [ + - + + ]: 10 : if (dtset%optcell==0.and.ipos==1) then
2009 : : ! Primitive vectors
2010 [ + + ]: 20 : do ii = 1,3
2011 : 15 : write(unit=chain,fmt='(a15,i1)') "PrimitiveVector",ii
2012 : 15 : ncerr = nf90_inq_varid(ncid, trim(chain), PrimVectId(ii) )
2013 [ - + ]: 15 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
2014 : 15 : ncerr = nf90_put_var(ncid, PrimVectId(ii), rprimd(:,ii))
2015 [ - + ]: 20 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
2016 : : end do
2017 : : ! Cell Volume
2018 : 5 : call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
2019 : 5 : ncerr = nf90_inq_varid(ncid, "Cell_Volume" , CellVolumeId)
2020 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_inq_varid')
2021 : 5 : ncerr = nf90_put_var(ncid, CellVolumeId, ucvol)
2022 [ - + ]: 5 : NCF_CHECK_MSG(ncerr,'nf90_put_var')
2023 : : end if
2024 : :
2025 : : ! Close file
2026 : 10 : ncerr = nf90_close(ncid)
2027 [ - + ]: 10 : NCF_CHECK_MSG(ncerr,'nf90_close')
2028 : : end if
2029 : :
2030 : : ! ==========================================================================
2031 : : ! Write data to POSABIN file (every nctime time step if option=3)
2032 : : ! ==========================================================================
2033 [ + + - + : 26 : if ((mod(itime, dtset%nctime)==0.and.option==3).or.(option==2)) then
- + ]
2034 : :
2035 : : ! Open file for writing
2036 [ - + ]: 10 : if (open_file('POSABIN',msg,unit=unpos,status='replace',form='formatted') /= 0 ) then
2037 : 0 : ABI_ERROR(msg)
2038 : : end if
2039 : :
2040 : : ! Write Positions
2041 [ + - ]: 10 : if (dtset%natom>=1) write(unpos,'(a7,3d18.5)') 'xred ',(xred(ii,1),ii=1,3)
2042 [ + - ]: 10 : if (dtset%natom>1) then
2043 [ + + ]: 40 : do iatom=2,dtset%natom
2044 : 40 : write(unpos,'(7x,3d18.5)') (xred(ii,iatom),ii=1,3)
2045 : : end do
2046 : : end if
2047 : :
2048 : : ! Write Velocities
2049 [ + - ]: 10 : if (dtset%natom>=1) write(unpos,'(a7,3d18.5)') 'vel ',(vel(ii,1),ii=1,3)
2050 [ + - ]: 10 : if (dtset%natom>1) then
2051 [ + + ]: 40 : do iatom=2,dtset%natom
2052 : 40 : write(unpos,'(7x,3d18.5)') (vel(ii,iatom),ii=1,3)
2053 : : end do
2054 : : end if
2055 : :
2056 : : ! Close file
2057 : 10 : close(unpos)
2058 : : end if
2059 : :
2060 [ - + ]: 26 : ABI_FREE(xcart)
2061 : :
2062 : : ! ==========================================================================
2063 : : ! End if master proc
2064 : : end if
2065 : :
2066 [ + + - + ]: 58 : end subroutine wrt_moldyn_netcdf
2067 : : !!***
2068 : :
2069 : : end module m_mover
2070 : : !!***
|