Line data Source code
1 : !!****m* ABINIT/m_common
2 : !! NAME
3 : !! m_common
4 : !!
5 : !! FUNCTION
6 : !! This module gathers routines used by higher-level procedures.
7 : !! Mainly printing routines.
8 : !!
9 : !! COPYRIGHT
10 : !! Copyright (C) 1998-2026 ABINIT group (DCA, XG, AF, GMR, LBoeri, MT)
11 : !! This file is distributed under the terms of the
12 : !! GNU General Public License, see ~abinit/COPYING
13 : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : !!
15 : !! SOURCE
16 :
17 : #if defined HAVE_CONFIG_H
18 : #include "config.h"
19 : #endif
20 :
21 : #include "abi_common.h"
22 :
23 : module m_common
24 :
25 : use defs_basis
26 : use m_errors
27 : use m_abicore
28 : use m_exit
29 : use m_fftcore
30 : use m_fock
31 : use m_io_tools
32 : #if defined DEV_YP_VDWXC
33 : use m_xc_vdw
34 : #endif
35 : use netcdf
36 : use m_nctk
37 : use m_crystal
38 : use m_wfk
39 : use m_ebands
40 : use m_hdr
41 : use m_xmpi
42 : use m_dtset
43 : use m_xpapi
44 : use m_yaml
45 : use m_invars2
46 : use m_dtset
47 :
48 : use m_rcpaw, only : rcpaw_type
49 : use m_fstrings, only : indent, endswith, sjoin, itoa
50 : use m_electronpositron, only : electronpositron_type
51 : use m_energies, only : energies_type
52 : use m_pair_list, only : pair_list
53 : use m_geometry, only : mkrdim, metric
54 : use m_kg, only : getcut
55 : use m_parser, only : parsefile, ab_dimensions
56 : use m_invars1, only : invars0, invars1m, indefo
57 : use m_time, only : timab, time_set_papiopt
58 : use defs_abitypes, only : MPI_type
59 : use defs_datatypes, only : pspheader_type
60 : use m_pspheads, only : inpspheads, pspheads_comm
61 : use m_kpts, only : kpts_timrev_from_kptopt
62 : use m_dft_energy, only : entropy
63 :
64 : use m_xg, only : SPACE_CR,SPACE_C
65 : use m_hamiltonian, only : gs_hamiltonian_type
66 : use m_chebfi2, only : chebfi_memInfo
67 : use m_lobpcg2, only : lobpcg_memInfo
68 : use m_invovl, only : invovl_ompgpu_static_mem,invovl_ompgpu_work_mem
69 : use m_gemm_nonlop, only : gemm_nonlop_ompgpu_static_mem,gemm_nonlop_ompgpu_work_mem
70 : use m_gemm_nonlop_projectors, only : gemm_nonlop_split_choice23
71 : use m_getghc, only : getghc_ompgpu_work_mem
72 : use, intrinsic :: iso_c_binding, only : c_size_t
73 :
74 : #if defined(HAVE_GPU)
75 : use m_gpu_toolbox
76 : #endif
77 :
78 : implicit none
79 :
80 : private
81 : !!***
82 :
83 : public :: scprqt
84 : public :: setup1
85 : public :: prteigrs
86 : public :: prtene
87 : public :: get_dtsets_pspheads ! Parse input file, get list of pseudos for files file and build list of datasets
88 : ! pseudopotential headers, maxval of dimensions needed in outvars
89 : public :: ebands_from_file ! Build an ebands_t object from file. Supports Fortran and netcdf files
90 : public :: crystal_from_file ! Build a crystal_t object from netcdf or Fortran file with Header
91 : public :: get_gemm_nonlop_ompgpu_blocksize ! Set OpenMP GPU GEMM nonlop blocksize
92 :
93 : !!***
94 :
95 : contains
96 : !!***
97 :
98 : !!****f* ABINIT/scprqt
99 : !! NAME
100 : !! scprqt
101 : !!
102 : !! FUNCTION
103 : !! Conducts printing inside the scfcv.F90 routine, according to the value of choice.
104 : !! Also checks the convergence with respect to the different criteria.
105 : !! Eventually send a signal to quit the SCF cycle.
106 : !!
107 : !! INPUTS
108 : !! choice= if 1 => called at the initialisation of scfcv.f
109 : !! if 2 => called during the loop in scfcv.f
110 : !! if 3 => called at the end of scfcv.f
111 : !! cpus=cpu time limit in seconds
112 : !! deltae=change in energy between the previous and present SCF cycle
113 : !! diffor=maximum absolute change in component of fcart between present and previous SCF cycle.
114 : !! difmagsph=maximum absolute change in magnetization between present and previous SCF cycle.
115 : !! dtset <type(dataset_type)>=all input variables in this dataset
116 : !! | chkexit= if non-zero, check whether the user wishes to exit
117 : !! | enunit=parameter determining units of output energies
118 : !! | ionmov=governs the movement of atoms (see help file)
119 : !! | kptopt=option for the generation of k points
120 : !! | mband=maximum number of bands
121 : !! | natom=number of atoms in cell.
122 : !! | nnsclo_now=number of non-self-consistent loops for the current vtrial
123 : !! | (often 1 for SCF calculation, =nstep for non-SCF calculations)
124 : !! | nsppol=1 for unpolarized, 2 for spin-polarized
125 : !! | occopt=option for occupancies
126 : !! | prtxml=1 if values have to be stored in an XML file.
127 : !! | prteig=
128 : !! | prtstm=print STM input variable
129 : !! | prtvol= control print volume
130 : !! | usedmatpu=DFT+U: number of SCF steps keeping occ. matrix fixed
131 : !! | usefock=1 if Fock operator is present (hence possibility of a double loop)
132 : !! | usepawu=0 if no DFT+U; /=0 if DFT+U
133 : !! eigen(mband*nkpt*nsppol)=array for holding eigenvalues (hartree)
134 : !! electronpositron <type(electronpositron_type)>=quantities for the electron-positron annihilation (optional argument)
135 : !! etotal=total energy (hartree)
136 : !! favg(3)=average of forces (ha/bohr)
137 : !! fcart(3,natom)=cartesian forces (hartree/bohr)
138 : !! fermie=fermi energy (Hartree) / for electrons thermalized in the conduction bands when occopt==9
139 : !! fermih=fermi energy (Hartree) for holes thermalized in the VB when occopt==9
140 : !! fname_eig=filename for printing of the eigenenergies
141 : !! fock <type(fock_type)>=quantities for the fock operator (optional argument)
142 : !! character(len=fnlen) :: filnam1=character strings giving input file name
143 : !! initGS= 1 if one GS SCF cycle has already be done
144 : !! iscf=( <= 0 =>non-SCF), >0 => SCF)
145 : !! iscf =1 => determination of the largest eigenvalue of the SCF cycle
146 : !! iscf =2 => SCF cycle, simple mixing
147 : !! iscf =3 => SCF cycle, anderson mixing
148 : !! iscf =5 => SCF cycle, CG based on estimations of gradients of the energy
149 : !! iscf =6 => SCF cycle, CG based on true minimization of the energy
150 : !! iscf =-3, although non-SCF, the energy is computed, so print it here.
151 : !! istep=number of the SCF iteration (needed if choice=2)
152 : !! istep_fock_outer=number of outer SCF iteration in the double loop approach
153 : !! istep_mix=number of inner SCF iteration in the double loop approach
154 : !! kpt(3,nkpt)=reduced coordinates of k points.
155 : !! maxfor=maximum absolute value of fcart
156 : !! maxmagsph=maximum absolute value of magnetization among all atoms.
157 : !! moved_atm_inside: if==1, the atoms are allowed to move.
158 : !! mpi_enreg=information about MPI parallelization
159 : !! nband(nkpt*nsppol)=number of bands at each k point, for each polarization
160 : !! nkpt=number of k points
161 : !! nstep=number of steps expected in iterations.
162 : !! occ(mband*nkpt*nsppol)=occupation number for each band at each k point.
163 : !! optres=0 if the residual (res2) is a POTENTIAL residual
164 : !! 1 if the residual (res2) is a DENSITY residual
165 : !! prtfor=1 only if forces have to be printed (0 otherwise)
166 : !! prtxml=1 if XML file has to be output
167 : !! res2=square of the density/potential residual
168 : !! resid(mband*nkpt*nsppol)=residuals for each band over all k points and spins
169 : !! residm=maximum value from resid array (except for nbdbuf highest bands)
170 : !! in Wavelets mode, it is used as the maximum value for the gradient norm.
171 : !! response= if 0, GS case, if 1, RF case.
172 : !! tollist(12)=tolerance list. Presently, the following are defined :
173 : !! tollist(1)=tolmxf ; tollist(2)=tolwfr ; tollist(3)=toldff
174 : !! tollist(4)=toldfe ; tollist(5)=toleig ; tollist(6)=tolvrs
175 : !! tollist(7)=tolrff ; tollist(9)=toldmag
176 : !! usepaw= 0 for non paw calculation; =1 for paw calculation
177 : !! vxcavg=mean of the vxc potential
178 : !! wtk(nkpt)=weight assigned to each k point.
179 : !! xred(3,natom)=reduced dimensionless atomic coordinates
180 : !!
181 : !! OUTPUT
182 : !! quit= 0 if the SCF cycle is not finished; 1 otherwise.
183 : !! conv_retcode=Only if choice==3, != 0 if convergence is not achieved.
184 : !!
185 : !! SOURCE
186 :
187 83892 : subroutine scprqt(choice,cpus,deltae,diffor,maxmagsph,difmagsph,dtset,&
188 83892 : & eigen,etotal,favg,fcart,fermie,fermih,fname_eig,filnam1,initGS,&
189 83892 : & iscf,istep,istep_fock_outer,istep_mix,kpt,maxfor,moved_atm_inside,mpi_enreg,&
190 83892 : & nband,nkpt,nstep,occ,optres,&
191 83892 : & prtfor,prtxml,quit,res2,resid,residm,response,tollist,usepaw,&
192 83892 : & vxcavg,wtk,xred,conv_retcode,&
193 : & electronpositron, fock,rcpaw) ! optional arguments)
194 :
195 : !Arguments ------------------------------------
196 : !scalars
197 : integer,intent(in) :: choice,initGS,iscf,istep,istep_fock_outer,istep_mix
198 : integer,intent(in) :: moved_atm_inside,nkpt,nstep
199 : integer,intent(in) :: optres,prtfor,prtxml,response,usepaw
200 : integer,intent(out) :: quit,conv_retcode
201 : real(dp),intent(in) :: cpus,deltae,diffor,etotal,fermie,fermih,maxfor,res2,residm,maxmagsph,difmagsph
202 : real(dp),intent(in) :: vxcavg
203 : character(len=fnlen),intent(in) :: fname_eig,filnam1
204 : type(electronpositron_type),pointer,optional :: electronpositron
205 : type(fock_type),pointer,optional :: fock
206 : type(MPI_type),intent(in) :: mpi_enreg
207 : type(dataset_type),intent(in) :: dtset
208 : type(rcpaw_type),intent(inout),optional,pointer :: rcpaw
209 : !arrays
210 : integer,intent(in) :: nband(nkpt*dtset%nsppol)
211 : real(dp),intent(in) :: eigen(dtset%mband*nkpt*dtset%nsppol),favg(3)
212 : real(dp),intent(in) :: fcart(3,dtset%natom),kpt(3,nkpt)
213 : real(dp),intent(in) :: occ(dtset%mband*nkpt*dtset%nsppol)
214 : real(dp),intent(in) :: resid(dtset%mband*nkpt*dtset%nsppol),tollist(12)
215 : real(dp),intent(in) :: wtk(nkpt),xred(3,dtset%natom)
216 :
217 : !Local variables-------------------------------
218 : !scalars
219 : integer,parameter :: master=0
220 : !integer,save :: toldfe_ok,toldff_ok,tolrff_ok,ttoldfe,ttoldff,ttolrff,ttolvrs,ttolwfr
221 : integer,save :: toldfe_ok,toldff_ok,tolrff_ok,toldmag_ok,ttoldfe,ttoldff,ttolrff,ttolvrs,ttolwfr,ttoldmag
222 : integer :: iatom,iband,iexit,ikpt,ii,ishift,isppol,my_rank
223 : integer :: nband_index,nband_k,nnsclohf
224 : integer :: openexit,option,tmagnet,usefock
225 : #if defined DEV_YP_VDWXC
226 : integer :: ivdw
227 : #endif
228 : !real(dp),save :: toldfe,toldff,tolrff,tolvrs,tolwfr,vdw_df_threshold
229 : real(dp),save :: toldfe,toldff,tolrff,tolvrs,tolwfr,vdw_df_threshold, toldmag
230 : real(dp) :: diff_e,diff_f,magnet,rhodn,rhoup
231 : logical :: noquit,use_dpfft
232 : character(len=500) :: message, message2, message3
233 : character(len=2) :: format_istep
234 : !character(len=5) :: format_magnet
235 : character(len=8) :: colname
236 : character(len=1) :: firstchar
237 : type(yamldoc_t) :: ydoc
238 : !arrays
239 167784 : real(dp) :: residm_band(dtset%mband,dtset%nsppol), f_tmp(3)
240 :
241 : ! *********************************************************************
242 :
243 : DBG_ENTER("COLL")
244 :
245 83892 : my_rank = mpi_enreg%me_cell
246 :
247 83892 : quit=0; conv_retcode=0
248 83892 : usefock=dtset%usefock
249 83892 : nnsclohf=dtset%nnsclohf
250 83892 : use_dpfft = .False.
251 :
252 83892 : tmagnet=0
253 60648 : if(response==0.and.(iscf>0.or.iscf==-3).and.dtset%nsppol==2.and.dtset%occopt>2) tmagnet=1
254 83892 : if((iscf>0.or.iscf==-3).and.(dtset%nsppol==2.or.dtset%nspden>1)) tmagnet=2
255 :
256 83892 : ishift=0
257 1013037 : residm_band = zero
258 175634 : do isppol=1, dtset%nsppol
259 2072859 : do ikpt=1, nkpt
260 12782935 : do iband=1, nband(ikpt+(isppol-1)*nkpt)
261 10793968 : ishift = ishift+1
262 12691193 : residm_band(iband, isppol) = max (resid(ishift), residm_band(iband, isppol))
263 : end do
264 : end do
265 : end do
266 :
267 93152 : select case (choice)
268 : case (1)
269 : ! choice= if 1 => called at the initialisation of scfcv.f
270 : ! Examine tolerance criteria
271 : ! NB: The tests on tolwfr and the presence of tolerances in the SCF case are
272 : ! also done at the level of the parser in chkinp.
273 9260 : tolwfr=tollist(2)
274 9260 : toldff=tollist(3)
275 9260 : toldfe=tollist(4)
276 9260 : tolvrs=tollist(6)
277 9260 : tolrff=tollist(7)
278 9260 : vdw_df_threshold=tollist(8)
279 9260 : toldmag=tollist(9)
280 9260 : ttolwfr=0 ; ttoldff=0 ; ttoldfe=0 ; ttolvrs=0; ttolrff=0; ttoldmag=0 ;
281 9260 : if(abs(tolwfr)>tiny(zero))ttolwfr=1
282 9260 : if(abs(toldff)>tiny(zero))ttoldff=1
283 9260 : if(abs(tolrff)>tiny(zero))ttolrff=1
284 9260 : if(abs(toldfe)>tiny(zero))ttoldfe=1
285 9260 : if(abs(tolvrs)>tiny(zero))ttolvrs=1
286 9260 : if(abs(toldmag)>tiny(zero))ttoldmag=1
287 : ! If non-scf calculations, tolwfr must be defined
288 9260 : if(ttolwfr /= 1 .and. (iscf<0 .and. iscf/=-3) )then
289 : write(message,'(a,a,a,es14.6,a,a)')&
290 0 : 'when iscf <0 and /= -3, tolwfr must be strictly',ch10,&
291 0 : 'positive, while it is ',tolwfr,ch10,&
292 0 : 'Action: change tolwfr in your input file and resubmit the job.'
293 0 : ABI_ERROR(message)
294 : end if
295 : ! toldff only allowed when prtfor==1
296 : ! FIXME: this test should be done on input, not during calculation
297 9260 : if((ttoldff == 1 .or. ttolrff == 1) .and. prtfor==0 )then
298 0 : ABI_ERROR('toldff only allowed when prtfor=1!')
299 : end if
300 : ! If SCF calculations, one and only one of these can differ from zero
301 : !if( (iscf>0 .or. iscf==-3) .and.(ttolwfr==1.and.ttoldff+ttoldfe+ttolvrs+ttolrff>1) &
302 : if( (iscf>0 .or. iscf==-3) .and.(ttolwfr==1.and.ttoldff+ttoldfe+ttolvrs+ttolrff+ttoldmag>1) &
303 : .and. (ttolwfr==0.and.ttoldff+ttoldfe+ttolvrs+ttolrff+ttoldmag/=1) ) then
304 : !.and. (ttolwfr==0.and.ttoldff+ttoldfe+ttolvrs+ttolrff/=1) ) then
305 : write(message,'(6a,es14.6,a,es14.6,a,es14.6,a,a,es14.6,a,a,a)' )&
306 : & 'For the SCF case, one and only one of the input tolerance criteria ',ch10,&
307 : & 'toldff, tolrff, toldfe, toldmag or tolvrs ','must differ from zero, while they are',ch10,&
308 : & 'toldff=',toldff,', tolrff=',tolrff,', toldfe=',toldfe,ch10,&
309 : !& 'and tolvrs=',tolvrs,' .',ch10,&
310 : & 'toldmag=',toldmag,' and tolvrs=',tolvrs,' .',ch10,&
311 : & 'Action: change your input file and resubmit the job.'
312 : ABI_ERROR(message)
313 : end if
314 :
315 9260 : if (dtset%usewvl == 1) then
316 0 : write(colname, "(A)") "grdnorm "
317 : else
318 9260 : write(colname, "(A)") "residm "
319 : end if
320 9260 : if (nstep>0 .and. (iscf>=0 .or.iscf==-3) .and. dtset%prtstm==0) then
321 8622 : if(tmagnet==2 .and. response==0)then
322 779 : if (prtfor==0) then
323 667 : if (optres==0) then
324 455 : write(message, '(4a)' ) ch10,&
325 910 : ' iter Etot(hartree) deltaE(h) ',colname, ' vres2 difmagsph maxmagsph'
326 : else
327 212 : write(message, '(4a)' ) ch10,&
328 424 : ' iter Etot(hartree) deltaE(h) ',colname, ' nres2 difmagsph maxmagsph'
329 : end if
330 : else
331 112 : if (optres==0) then
332 83 : write(message, '(4a)' ) ch10,&
333 166 : ' iter Etot(hartree) deltaE(h) ',colname, ' vres2 diffor maxfor difmagsph maxmagsph'
334 : else
335 29 : write(message, '(4a)' ) ch10,&
336 58 : ' iter Etot(hartree) deltaE(h) ',colname, ' nres2 diffor maxfor difmagsph maxmagsph'
337 : end if
338 : end if
339 : else
340 7843 : if(response==0)then
341 5625 : if (prtfor==0) then
342 2709 : if (optres==0) then
343 2110 : write(message, '(4a)' ) ch10,&
344 4220 : ' iter Etot(hartree) deltaE(h) ', colname, ' vres2'
345 : else
346 599 : write(message, '(4a)' ) ch10,&
347 1198 : ' iter Etot(hartree) deltaE(h) ', colname, ' nres2'
348 : end if
349 : else
350 2916 : if (optres==0) then
351 2349 : write(message, '(4a)' ) ch10,&
352 4698 : ' iter Etot(hartree) deltaE(h) ',colname,' vres2 diffor maxfor '
353 : else
354 567 : write(message, '(4a)' ) ch10,&
355 1134 : ' iter Etot(hartree) deltaE(h) ',colname,' nres2 diffor maxfor '
356 : end if
357 : end if
358 : else
359 2218 : if(tmagnet==2 .and. iscf>0 )then
360 108 : if (optres==0) then
361 108 : write(message, '(4a)' ) ch10,&
362 216 : ' iter 2DEtotal(Ha) deltaE(Ha) ', colname, ' vres2 difmagsph maxmagsph'
363 : else
364 0 : write(message, '(4a)' ) ch10,&
365 0 : ' iter 2DEtotal(Ha) deltaE(Ha) ', colname, ' nres2 difmagsph maxmagsph'
366 : end if
367 : else
368 2110 : if (optres==0) then
369 2110 : write(message, '(4a)' ) ch10,&
370 4220 : ' iter 2DEtotal(Ha) deltaE(Ha) ', colname, ' vres2 '
371 : else
372 0 : write(message, '(4a)' ) ch10,&
373 0 : ' iter 2DEtotal(Ha) deltaE(Ha) ', colname, ' nres2 '
374 : end if
375 : end if
376 : end if
377 : end if
378 :
379 8622 : ydoc = yamldoc_open('BeginCycle')
380 : ! If wfoptalg=1 or 111 or 112, we should write mdeg_filter
381 : call ydoc%add_ints("iscf, nstep, nline, wfoptalg", &
382 43110 : [dtset%iscf, dtset%nstep, dtset%nline, dtset%wfoptalg], dict_key="solver")
383 : call ydoc%add_reals("tolwfr, toldff, toldfe, tolvrs, tolrff, toldmag", & ! , vdw_df_threshold", &
384 : [tolwfr, toldff, toldfe, tolvrs, tolrff, toldmag], & !, vdw_df_threshold], &
385 : !call ydoc%add_reals("tolwfr, toldff, toldfe, tolvrs, tolrff", & ! , vdw_df_threshold", &
386 : ! [tolwfr, toldff, toldfe, tolvrs, tolrff], & !, vdw_df_threshold], &
387 60354 : real_fmt="(es8.2)", dict_key="tolerances", ignore=zero)
388 :
389 8622 : call ydoc%write_and_free(ab_out, newline=.False.)
390 8622 : call wrtout(ab_out, message)
391 : end if
392 :
393 : case (2)
394 :
395 : ! Examine tolerance criteria
396 65372 : tolwfr=tollist(2)
397 65372 : toldff=tollist(3)
398 65372 : toldfe=tollist(4)
399 65372 : tolvrs=tollist(6)
400 65372 : tolrff=tollist(7)
401 65372 : vdw_df_threshold=tollist(8)
402 65372 : toldmag=tollist(9)
403 65372 : ttolwfr=0 ; ttoldff=0 ; ttoldfe=0 ; ttolvrs=0; ttolrff=0; ttoldmag=0;
404 : !ttolwfr=0 ; ttoldff=0 ; ttoldfe=0 ; ttolvrs=0; ttolrff=0;
405 65372 : if(abs(tolwfr)>tiny(0.0_dp))ttolwfr=1
406 65372 : if(abs(toldff)>tiny(0.0_dp))ttoldff=1
407 65372 : if(abs(tolrff)>tiny(0.0_dp))ttolrff=1
408 65372 : if(abs(toldfe)>tiny(0.0_dp))ttoldfe=1
409 65372 : if(abs(tolvrs)>tiny(0.0_dp))ttolvrs=1
410 65372 : if(abs(toldmag)>tiny(0.0_dp))ttoldmag=1
411 :
412 : ! Conduct printing. If extra output follows, then put a blank line into the output here
413 73468 : if (dtset%prtvol>=10) call wrtout([std_out, ab_out], ' ')
414 :
415 : ! Calculate up and down charge and magnetization
416 65372 : if(tmagnet==1 ) then
417 0 : rhoup = zero
418 0 : rhodn = zero
419 0 : nband_index = 1
420 0 : do isppol=1,dtset%nsppol
421 0 : do ikpt=1,nkpt
422 0 : nband_k=nband(ikpt+(isppol-1)*nkpt)
423 0 : do iband=1,nband_k
424 0 : if(isppol==1) rhoup = rhoup + wtk(ikpt)*occ(nband_index)
425 0 : if(isppol==2) rhodn = rhodn + wtk(ikpt)*occ(nband_index)
426 0 : nband_index = nband_index + 1
427 : end do
428 : end do
429 : end do
430 0 : magnet = abs(rhoup - rhodn)
431 : end if
432 :
433 65372 : if (prtxml == 1) then
434 26 : write(ab_xml_out, "(A)", advance = "NO") ' <scfcvStep'
435 26 : write(message, "(es22.10)") etotal
436 26 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' eTotal="', trim(message) ,'"'
437 26 : write(message, "(es20.8)") deltae
438 26 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' deltaETotal="', trim(message) ,'"'
439 26 : write(message, "(es20.8)") residm
440 26 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' maxResid="', trim(message) ,'"'
441 26 : write(message, "(es20.8)") res2
442 26 : if (optres == 0) then
443 26 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' potResid="', trim(message) ,'"'
444 : else
445 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' denResid="', trim(message) ,'"'
446 : end if
447 26 : if (tmagnet== 1) then
448 0 : write(message, "(es20.8)") magnet
449 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' magn="', trim(message) ,'"'
450 : end if
451 26 : if (prtfor == 1) then
452 0 : write(message, "(es20.8)") diffor
453 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' deltaForces="', trim(message) ,'"'
454 0 : write(message, "(es20.8)") maxfor
455 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' maxForces="', trim(message) ,'"'
456 : end if
457 26 : write(ab_xml_out, "(A)") " />"
458 : end if
459 :
460 : ! Print total (free) energy (hartree) and other convergence measures
461 65372 : if(dtset%prtstm==0)then
462 65369 : format_istep='i3'
463 65369 : if(istep>99)format_istep='i5'
464 65369 : if(istep>9999)format_istep='i7'
465 : !if(tmagnet==1)then
466 65369 : if(tmagnet==2 .and. response==0)then
467 : ! if(magnet<10)then
468 : ! format_magnet='f6.3)'
469 : ! else if(magnet<100)then
470 : ! format_magnet='f6.2)'
471 : ! else
472 : ! format_magnet='f6.1)'
473 : ! end if
474 7534 : if (prtfor==0) then
475 : !write(message, '(a,'//format_istep//',1p,g22.14,3es9.2,0p,'//format_magnet ) &
476 : write(message, '(a,'//format_istep//',1p,g22.14,5es10.3)' ) &
477 : !' ETOT',istep,etotal,deltae,residm,res2,magnet
478 6720 : ' ETOT',istep,etotal,deltae,residm,res2,difmagsph,maxmagsph
479 : else
480 : write(message, '(a,'//format_istep//',1p,g22.14,7es10.3)' ) &
481 814 : ' ETOT',istep,etotal,deltae,residm,res2,diffor,maxfor,difmagsph,maxmagsph
482 : end if
483 : else
484 57835 : firstchar=' '
485 57835 : if (response/=0.and.istep==1) firstchar="-"
486 57835 : if (response==0) then
487 39275 : if (prtfor==0) then
488 : write(message, '(2a,'//format_istep//',1p,g22.14,3es10.3)' ) &
489 19597 : firstchar,'ETOT',istep,etotal,deltae,residm,res2
490 : else
491 : write(message, '(2a,'//format_istep//',1p,g22.14,5es10.3)' ) &
492 19678 : firstchar,'ETOT',istep,etotal,deltae,residm,res2,diffor,maxfor
493 : end if
494 : else
495 18560 : if(tmagnet==2 .and. iscf>0 )then
496 : write(message, '(2a,'//format_istep//',1p,g22.14,1x,5es10.3)' ) &
497 1568 : firstchar,'ETOT',istep,etotal,deltae,residm,res2,difmagsph,maxmagsph
498 : else
499 : write(message, '(2a,'//format_istep//',1p,g22.14,1x,3es10.3)' ) &
500 16992 : firstchar,'ETOT',istep,etotal,deltae,residm,res2
501 : end if
502 : end if
503 : end if
504 : !if (etot_yaml_doc%stream%length /= 0) call etot_yaml_doc%add_tabular_line(' '//message(6:))
505 65369 : call wrtout(ab_out,message)
506 :
507 65369 : if(mpi_enreg%paral_pert==1) then
508 337 : call wrtout(std_out, message,'PERS')
509 65032 : elseif(mpi_enreg%paral_pert==0) then
510 65032 : call wrtout(std_out, message,'COLL')
511 : end if
512 :
513 : end if ! dtset%prtstm==0
514 :
515 : ! Print positions/forces every step if dtset%prtvol>=10 and iscf>0 or -3 and GS case
516 65372 : if (dtset%prtvol>=10.and.(iscf>=0.or.iscf==-3).and.response==0.and.dtset%prtstm==0) then
517 1657 : call wrtout(ab_out," ")
518 :
519 : ! Print up and down charge and magnetization
520 1657 : if(tmagnet==1) then
521 : write(message,'(a,f11.6,a,f11.6,a,f10.6)')&
522 0 : ' #electrons spin up=',rhoup,', spin down=',rhodn,', magnetization=',magnet
523 0 : call wrtout([std_out, ab_out], message)
524 : end if
525 :
526 : ! Moreover, print atomic positions if dtset%ionmov==4, and moved_atm_inside==1
527 1657 : if (dtset%ionmov==4 .and. moved_atm_inside==1)then
528 255 : call wrtout([std_out, ab_out], ' reduced coordinates :')
529 255 : do iatom=1,dtset%natom
530 170 : write(message, '(i5,1x,3es21.11)' ) iatom,xred(:,iatom)
531 595 : call wrtout([std_out, ab_out], message)
532 : end do
533 : end if
534 :
535 : ! Slightly change favg for printing reasons
536 1657 : if (prtfor>0) then
537 529 : f_tmp(:)=favg(:)
538 529 : if(abs(favg(1))<1.0d-13)f_tmp(1)=zero
539 529 : if(abs(favg(2))<1.0d-13)f_tmp(2)=zero
540 529 : if(abs(favg(3))<1.0d-13)f_tmp(3)=zero
541 529 : write(message, '(a,3es10.2)' )' cartesian forces (ha/bohr); non-corrected avg=',f_tmp(:)
542 1587 : call wrtout([std_out, ab_out], message)
543 2599 : do iatom=1,dtset%natom
544 8280 : f_tmp(:)=fcart(:,iatom)
545 2070 : if(abs(fcart(1,iatom))<1.0d-13)f_tmp(1)=zero
546 2070 : if(abs(fcart(2,iatom))<1.0d-13)f_tmp(2)=zero
547 2070 : if(abs(fcart(3,iatom))<1.0d-13)f_tmp(3)=zero
548 2070 : write(message, '(i5,1x,3es21.11)' ) iatom,f_tmp(:)
549 6739 : call wrtout([std_out, ab_out], message)
550 : end do
551 : end if
552 :
553 : end if
554 :
555 : ! Print eigenvalues every step if dtset%prtvol>=10 and GS case
556 65372 : if (my_rank == master .and. (dtset%prtvol>=10 .and. response==0 .and. dtset%tfkinfunc==0 .and. dtset%usewvl==0)) then
557 1525 : option=1
558 : call prteigrs(eigen,dtset%enunit,fermie,fermih,fname_eig,ab_out,iscf,kpt,dtset%kptopt,dtset%mband,&
559 1525 : nband,dtset%nbdbuf,nkpt,dtset%nnsclo,dtset%nsppol,occ,dtset%occopt,option,dtset%prteig,dtset%prtvol,resid,tolwfr,vxcavg,wtk)
560 : call prteigrs(eigen,dtset%enunit,fermie,fermih,fname_eig,std_out,iscf,kpt,dtset%kptopt,dtset%mband,&
561 1525 : nband,dtset%nbdbuf,nkpt,dtset%nnsclo,dtset%nsppol,occ,dtset%occopt,option,dtset%prteig,dtset%prtvol,resid,tolwfr,vxcavg,wtk)
562 : end if
563 :
564 65372 : if(response==0)then
565 46812 : write(message, '(a,1p,e15.7,a)' ) ' scprqt: <Vxc>=',vxcavg,' Hartree'
566 46812 : call wrtout(std_out,message)
567 : end if
568 :
569 : ! Check whether exiting was required by the user.
570 65372 : openexit=1 ; if(dtset%chkexit==0) openexit=0
571 65372 : call exit_check(cpus,filnam1,iexit,ab_out,mpi_enreg%comm_cell,openexit)
572 65372 : if (iexit/=0) quit=1
573 :
574 : ! In special cases, do not quit even if convergence is reached
575 : noquit=((istep<nstep).and.(usepaw==1).and.(dtset%usepawu/=0).and.&
576 : (dtset%usedmatpu/=0).and.(istep<=abs(dtset%usedmatpu)).and.&
577 65372 : (dtset%usedmatpu<0.or.initGS==0))
578 :
579 : ! Additional stuff for electron/positron
580 65372 : if (present(electronpositron)) then
581 46812 : if (associated(electronpositron)) then
582 562 : if (electronpositron%istep_scf==1) then
583 79 : toldff_ok=0;tolrff_ok=0;toldfe_ok=0; toldmag_ok=0;
584 : end if
585 : end if
586 : end if
587 :
588 : ! Stopping criteria in the SCF case
589 65372 : if(iscf>1 .or. iscf==-3 .or. iscf == 0) then
590 : ! Here treat the vdw_df_threshold criterion : if the change of energy is less than
591 : ! input vdw_df_threshold, trigger the calculation of vdW interactions
592 : ! write(message,'(1x,a,e10.3,1x,a,e10.3,1x,l1,a)') &
593 : ! & '[vdW-DF][DEBUG] deltae=',deltae,'vdw_df_threshold=',vdw_df_threshold, &
594 : ! & (abs(deltae)<vdw_df_threshold),ch10
595 : ! call wrtout(std_out,message)
596 : #if defined DEV_YP_VDWXC
597 : call xc_vdw_trigger( (abs(deltae)<vdw_df_threshold) )
598 : #endif
599 : ! Here treat the tolwfr criterion: if maximum residual is less than
600 : ! input tolwfr, stop steps (exit loop here)
601 65325 : if (ttolwfr == 1 .and. (ttolvrs+ttoldfe+ttoldff+ttolrff+ttoldmag==0) .and. .not. noquit) then
602 : !if (ttolwfr == 1 .and. (ttolvrs+ttoldfe+ttoldff+ttolrff==0) .and. .not. noquit) then
603 15165 : if (residm < tolwfr) then
604 1633 : if (dtset%usewvl == 0) then
605 1633 : write(message, '(a,a,i5,a,1p,e10.2,a,e10.2,a,a)' )ch10, &
606 3266 : ' At SCF step',istep,' max residual=',residm,' < tolwfr=',tolwfr,' =>converged.'
607 : else
608 0 : write(message, '(a,a,i5,a,1p,e10.2,a,e10.2,a,a)' )ch10, &
609 0 : ' At SCF step',istep,' max grdnorm=',residm,' < tolwfr=',tolwfr,' =>converged.'
610 : end if
611 4899 : call wrtout([std_out, ab_out], message)
612 1633 : quit=1
613 : else
614 13532 : use_dpfft = residm < tol7
615 : end if
616 15165 : if(present(rcpaw)) then
617 917 : if (associated(rcpaw).and.residm < (tolwfr)**third) then
618 0 : if(rcpaw%updatepaw(1)==0.and.rcpaw%updatepaw(2)==0) then
619 0 : rcpaw%updatepaw(:)=istep
620 : endif
621 : endif
622 : endif
623 : end if
624 :
625 : ! Here treat the toldff criterion: if maximum change of fcart is less than
626 : ! input toldff twice consecutively, stop steps (exit loop here)
627 65325 : if (ttoldff==1) then
628 16395 : if (istep==1) then
629 2673 : toldff_ok=0
630 13722 : else if (diffor < toldff) then
631 4354 : toldff_ok=toldff_ok+1
632 : ! add warning for forces which are 0 by symmetry. Also added Matteo check below that the wave
633 : ! functions are relatively converged as well
634 4354 : if (diffor < tol12) then
635 1 : write (message,'(3a)') ' toldff criterion is satisfied, but your forces are suspiciously low.', ch10,&
636 2 : ' Check if the forces are 0 by symmetry: in that case you can not use the toldff convergence criterion!'
637 1 : ABI_WARNING(message)
638 1 : if (maxfor < tol16 .and. res2 > tol9) tolrff_ok=0
639 : end if
640 : else
641 9368 : toldff_ok=0
642 9368 : use_dpfft = diffor < tol6
643 : end if
644 16395 : if(present(rcpaw)) then
645 3147 : if (associated(rcpaw).and.diffor < (toldff)**third) then
646 0 : if(rcpaw%updatepaw(1)==0.and.rcpaw%updatepaw(2)==0) then
647 0 : rcpaw%updatepaw(:)=istep
648 : endif
649 : endif
650 : endif
651 :
652 16395 : if(toldff_ok>=2 .and..not.noquit)then
653 2141 : if (ttolwfr==0) then
654 2135 : write(message, '(a,a,i5,a,a,a,es11.3,a,es11.3)' ) ch10, &
655 2135 : ' At SCF step',istep,', forces are converged : ',ch10,&
656 4270 : ' for the second time, max diff in force=',diffor,' < toldff=',toldff
657 6405 : call wrtout([std_out, ab_out], message)
658 2135 : quit=1
659 6 : else if (ttolwfr==1 .and. residm < tolwfr )then
660 2 : write(message, '(a,a,i5,a,1p,e10.2,a,e10.2,a,a,a,es11.3,a,es11.3)' ) ch10, &
661 2 : ' At SCF step',istep,', max residual=',residm,' < tolwfr=',tolwfr,' AND forces are converged : ',ch10,&
662 4 : ' for the second time, max diff in force=',diffor,' < toldff=',toldff
663 6 : call wrtout([std_out, ab_out], message)
664 2 : quit=1
665 : end if
666 : end if
667 : end if
668 :
669 : ! HEREEEE
670 65325 : if (ttoldmag==1) then
671 30 : if (istep==1) then
672 2 : toldmag_ok=0
673 28 : else if (difmagsph < toldmag) then
674 4 : toldmag_ok=toldmag_ok+1
675 : ! add warning for magnetizations which are 0 . Check below that the wave
676 : ! functions are relatively converged as well
677 4 : if (maxmagsph < tol8) then
678 0 : write (message,'(3a)') ' toldmag criterion is satisfied, but your magnetizations are suspiciously low.', ch10,&
679 0 : ' Check if the magnetizations are 0 : in that case you can not use the toldmag convergence criterion!'
680 0 : ABI_WARNING(message)
681 : ! HEREE ??
682 : end if
683 4 : if (res2 > tol9) toldmag_ok=0
684 : else
685 24 : toldmag_ok=0
686 24 : use_dpfft = difmagsph < tol6
687 : end if
688 :
689 30 : if(toldmag_ok>=2 .and..not.noquit)then
690 2 : if (ttolwfr==0) then
691 2 : write(message, '(a,a,i5,a,a,a,es11.3,a,es11.3)' ) ch10, &
692 2 : ' At SCF step',istep,', magnetizations are converged : ',ch10,&
693 4 : ' for the second time, max diff in magnetization=',difmagsph,' < toldmag=',toldmag
694 6 : call wrtout([std_out, ab_out], message)
695 2 : quit=1
696 0 : else if (ttolwfr==1 .and. residm < tolwfr )then
697 0 : write(message, '(a,a,i5,a,1p,e10.2,a,e10.2,a,a,a,es11.3,a,es11.3)' ) ch10, &
698 0 : ' At SCF step',istep,', max residual=',residm,' < tolwfr=',tolwfr,' AND magnetizations are converged : ',ch10,&
699 0 : ' for the second time, max diff in magnetization=',difmagsph,' < toldmag=',toldmag
700 0 : call wrtout([std_out, ab_out], message)
701 0 : quit=1
702 : end if
703 : end if
704 : end if
705 :
706 : ! Here treat the tolrff criterion: if maximum change of fcart is less than
707 : ! input tolrff times fcart itself twice consecutively, stop steps (exit loop here)
708 65325 : if (ttolrff==1) then
709 867 : if (istep==1) then
710 132 : tolrff_ok=0
711 : ! 27/7/2009: added test for absolute value of maxfor, otherwise if it is 0 this never exits the scf loop.
712 735 : else if (diffor < tolrff*maxfor .or. (maxfor < tol16 .and. diffor < tol16)) then
713 255 : tolrff_ok=tolrff_ok+1
714 : ! Thu Mar 12 19:01:40 MG: added additional check on res2 to make sure the SCF cycle is close to convergence.
715 : ! Needed for structural relaxations otherwise the stress tensor is wrong and the relax algo makes wrong moves.
716 255 : if (maxfor < tol16 .and. res2 > tol9) tolrff_ok=0
717 : else
718 480 : tolrff_ok=0
719 480 : use_dpfft = diffor < tolrff * maxfor * five
720 : end if
721 867 : if(present(rcpaw)) then
722 134 : if (associated(rcpaw).and.(diffor < ( tolrff*maxfor)**third.or.(maxfor < tol6 .and. diffor < tol6))) then
723 0 : if(rcpaw%updatepaw(1)==0.and.rcpaw%updatepaw(2)==0) then
724 0 : rcpaw%updatepaw(:)=istep
725 : endif
726 : endif
727 : endif
728 867 : if(tolrff_ok>=2 .and. (.not.noquit))then
729 119 : if (ttolwfr==0) then
730 113 : write(message, '(a,a,i5,a,a,a,es11.3,a,es11.3,a)' ) ch10, &
731 113 : ' At SCF step',istep,', forces are sufficiently converged : ',ch10,&
732 113 : ' for the second time, max diff in force=',diffor,&
733 226 : ' is less than < tolrff=',tolrff, ' times max force'
734 339 : call wrtout([std_out, ab_out], message)
735 113 : quit=1
736 6 : else if (ttolwfr==1 .and. residm < tolwfr) then
737 2 : write(message, '(a,a,i5,a,1p,e10.2,a,e10.2,a,a,a,es11.3,a,es11.3,a)' ) ch10, &
738 2 : ' At SCF step',istep,', max residual=',residm,' < tolwfr=',tolwfr,' AND forces are sufficiently converged : ',ch10,&
739 2 : ' for the second time, max diff in force=',diffor,&
740 4 : ' is less than < tolrff=',tolrff, ' times max force'
741 6 : call wrtout([std_out, ab_out], message)
742 2 : quit=1
743 : end if
744 : end if
745 : end if
746 :
747 : ! Here treat the toldfe criterion: if the change of energy is less than
748 : ! input toldfe twice consecutively, stop steps (exit loop here)
749 65325 : if (ttoldfe==1) then
750 8893 : if (istep==1) then
751 1263 : toldfe_ok=0
752 7630 : else if (abs(deltae)<toldfe) then
753 2173 : toldfe_ok=toldfe_ok+1
754 : else
755 5457 : toldfe_ok=0
756 5457 : use_dpfft = abs(deltae) < tol8
757 : end if
758 8893 : if(present(rcpaw)) then
759 2483 : if (associated(rcpaw).and.abs(deltae) < (toldfe)**third) then
760 7 : if(rcpaw%updatepaw(1)==0.and.rcpaw%updatepaw(2)==0) then
761 6 : rcpaw%updatepaw(:)=istep
762 : endif
763 : endif
764 : endif
765 : ! Fock : tolwfr not taken into account
766 8893 : if(usefock/=0.and.nnsclohf>=2) then
767 197 : if (toldfe_ok==2 .and. (.not.noquit))then
768 : write(message, '(a,i3,a,i3,a,a,a,es11.3,a,es11.3)' ) &
769 11 : ' Outer loop step',istep_fock_outer,' - inner step',istep_mix,' - frozen Fock etot converged : ',ch10,&
770 22 : ' for the second time, diff in etot=',abs(deltae),' < toldfe=',toldfe
771 33 : call wrtout([std_out, ab_out], message)
772 11 : quit=1
773 : end if
774 : ! No Fock : take into account tolwfr if ttolwfr/=0
775 8696 : else if(toldfe_ok>=2 .and. (.not.noquit))then
776 1060 : if (ttolwfr==0) then
777 1054 : write(message, '(a,a,i5,a,a,a,es11.3,a,es11.3)' ) ch10, &
778 1054 : ' At SCF step',istep,', etot is converged : ',ch10,&
779 2108 : ' for the second time, diff in etot=',abs(deltae),' < toldfe=',toldfe
780 3162 : call wrtout([std_out, ab_out], message)
781 1054 : quit=1
782 6 : else if (ttolwfr==1 .and. residm < tolwfr) then
783 2 : write(message, '(a,a,i5,a,1p,e10.2,a,e10.2,a,a,a,es11.3,a,es11.3)' ) ch10, &
784 2 : ' At SCF step',istep,', max residual=',residm,' < tolwfr=',tolwfr,' AND etot is converged : ',ch10,&
785 4 : ' for the second time, diff in etot=',abs(deltae),' < toldfe=',toldfe
786 6 : call wrtout([std_out, ab_out], message)
787 2 : quit=1
788 : end if
789 : end if
790 8893 : if(usefock==1 .and. nnsclohf>1)then
791 197 : if(istep_mix==1 .and. (.not.noquit))then
792 : ! The change due to the update of the Fock operator is sufficiently small. No need to meet it a second times.
793 60 : if (abs(deltae)<toldfe) then
794 : write(message, '(a,i3,a,i3,a,a,a,es11.3,a,es11.3)' ) &
795 2 : ' Outer loop step',istep_fock_outer,' - inner step',istep_mix,' - etot converged : ',ch10,&
796 4 : ' update of Fock operator yields diff in etot=',abs(deltae),' < toldfe=',toldfe
797 6 : call wrtout([std_out, ab_out], message)
798 2 : fock%fock_common%fock_converged=.true.
799 2 : quit=1
800 : endif
801 : endif
802 : !TODO: separate messages: if HF is imposing a continuation of the loop, then abs(deltae) is actually not > toldfe
803 197 : if(istep_mix==nnsclohf .and. quit==0)then
804 : write(message, '(a,i3,a,i3,a,a,a,es11.3,a,es11.3)' ) &
805 45 : ' Outer loop step',istep_fock_outer,' - inner step',istep_mix,' - frozen Fock etot NOT converged : ',ch10,&
806 90 : ' diff in etot=',abs(deltae),' > toldfe=',toldfe
807 135 : call wrtout([std_out, ab_out], message)
808 : endif
809 : endif
810 :
811 : ! Here treat the vdw_df_threshold criterion for non-SCF vdW-DF
812 : ! calculations: If input vdw_df_threshold is lesss than toldfe
813 : ! then the vdW-DF is triggered once selfconsistency criteria is
814 : ! reached for the first time.
815 : ! write(message,'(1x,a,e10.3,1x,a,e10.3,1x,l1,a)') &
816 : ! & '[vdW-DF][DEBUG] deltae=',deltae,'vdw_df_threshold=',vdw_df_threshold, &
817 : ! & (abs(deltae)<toldfe),ch10
818 : ! call wrtout(std_out,message)
819 : #if defined DEV_YP_VDWXC
820 : ivdw = 0
821 : if ( toldfe > vdw_df_threshold ) then
822 : ivdw = ivdw + 1
823 : end if
824 : call xc_vdw_trigger((toldfe_ok==1 .and. toldfe>vdw_df_threshold))
825 : if ( ivdw == 2) then
826 : quit=1
827 : end if
828 : #endif
829 : end if
830 :
831 : ! Here treat the tolvrs criterion: if density/potential residual (squared)
832 : ! is less than input tolvrs, stop steps (exit loop here)
833 65325 : if (ttolvrs==1 .and. .not. noquit) then
834 23901 : if (ttolwfr==0) then
835 23652 : if (res2 < tolvrs) then
836 1804 : if (optres==0) then
837 1562 : write(message, '(a,a,i5,a,1p,e10.2,a,e10.2,a)' ) ch10,&
838 3124 : ' At SCF step',istep,' vres2 =',res2,' < tolvrs=',tolvrs,' =>converged.'
839 : else
840 242 : write(message, '(a,a,i5,a,1p,e10.2,a,e10.2,a)' ) ch10,&
841 484 : ' At SCF step',istep,' nres2 =',res2,' < tolvrs=',tolvrs,' =>converged.'
842 : end if
843 5412 : call wrtout([std_out, ab_out], message)
844 1804 : quit=1
845 : else
846 21848 : use_dpfft = res2 < tol5
847 : end if
848 249 : else if (ttolwfr==1 .and. residm < tolwfr) then
849 18 : if (res2 < tolvrs) then
850 14 : if (optres==0) then
851 2 : write(message, '(a,a,i5,a,1p,e10.2,a,e10.2,a,e10.2,a,e10.2,a)' ) ch10,&
852 2 : ' At SCF step',istep,' max residual=',residm,' < tolwfr=',tolwfr,' AND vres2 =',res2,&
853 4 : & ' < tolvrs=',tolvrs,' =>converged.'
854 : else
855 12 : write(message, '(a,a,i5,a,1p,e10.2,a,e10.2,a,e10.2,a,e10.2,a)' ) ch10,&
856 12 : ' At SCF step',istep,' max residual=',residm,' < tolwfr=',tolwfr,' AND nres2 =',res2,&
857 24 : & ' < tolvrs=',tolvrs,' =>converged.'
858 : end if
859 42 : call wrtout([std_out, ab_out], message)
860 14 : quit=1
861 : else
862 4 : use_dpfft = res2 < tol5
863 : end if
864 : end if
865 23901 : if(present(rcpaw)) then
866 7582 : if (associated(rcpaw).and.res2 < (tolvrs)**third) then
867 0 : if(rcpaw%updatepaw(1)==0.and.rcpaw%updatepaw(2)==0) then
868 0 : rcpaw%updatepaw(:)=istep
869 : endif
870 : endif
871 : endif
872 : end if
873 :
874 65325 : if (quit==1.and.noquit) then
875 0 : write(message, '(a,a,a)' ) ch10, &
876 0 : ' SCF cycle will continue as it is in an initialization stage',' (occ. matrix was kept constant)...'
877 0 : call wrtout([std_out, ab_out], message)
878 : end if
879 :
880 : end if
881 :
882 : ! Activate FFT in double-precision.
883 65325 : if (use_dpfft) then
884 18033 : if (fftcore_mixprec == 1) call wrtout(std_out, " Approaching convergence. Activating FFT in double-precision")
885 18033 : ii = fftcore_set_mixprec(0)
886 : end if
887 :
888 : ! Additional stuff for rcpaw
889 65372 : if(present(rcpaw)) then
890 14329 : if(associated(rcpaw)) then
891 21 : if(rcpaw%updatepaw(2)>0.and.rcpaw%frocc) rcpaw%updateocc=rcpaw%updatepaw(2)
892 21 : if(rcpaw%updatetnc==0)rcpaw%updatetnc=rcpaw%updatepaw(2)
893 21 : if(quit==1.and.(rcpaw%istep<rcpaw%updatepaw(2).or.rcpaw%updatepaw(2)==0))quit=0
894 : endif
895 : endif
896 :
897 : case (3)
898 : ! If wavefunction convergence was not reached (for nstep>0) print a warning and return conv_retcode
899 :
900 : conv_retcode = 0
901 9260 : if(nstep>0) then
902 9225 : if (.not. converged()) then
903 1932 : conv_retcode = 1
904 :
905 1932 : if(iscf>=1 .or. iscf==-3 .or. iscf == 0)then
906 1817 : write(message, '(a,a,a,a,i5,a)' ) ch10,&
907 1817 : ' scprqt: WARNING -',ch10,&
908 3634 : ' nstep=',nstep,' was not enough SCF cycles to converge;'
909 :
910 1817 : write(std_out,'(6a,i0,3a)')ch10,&
911 1817 : "--- !ScfConvergenceWarning",ch10,&
912 1817 : "message: |",ch10,&
913 1817 : ' nstep ',nstep,' was not enough SCF cycles to converge.',ch10,&
914 3634 : "..."
915 : !ABI_WARNING_CLASS(message, "ScfConvergenceWarning")
916 : else
917 115 : write(message, '(a,a,a,a,i5,a)' ) ch10,&
918 115 : ' scprqt: WARNING -',ch10,&
919 230 : ' nstep=',nstep,' was not enough non-SCF iterations to converge;'
920 :
921 115 : write(std_out,'(8a)')ch10,&
922 115 : "--- !NscfConvergenceWarning",ch10,&
923 115 : "message: |",ch10,TRIM(indent(message)),ch10,&
924 230 : "..."
925 : !ABI_WARNING_CLASS(message, "NScfConvergenceWarning")
926 : end if
927 5796 : call wrtout([std_out, ab_out], message)
928 :
929 1932 : if (ttolwfr==1 .and. residm > tolwfr) then
930 681 : if (dtset%usewvl == 0) then
931 : write(message, '(a,es11.3,a,es11.3,a)' ) &
932 681 : ' maximum residual=',residm,' exceeds tolwfr=',tolwfr,ch10
933 :
934 : write(message2, '(a,es11.3,2a)' ) &
935 681 : ' maximum residual each band. tolwfr= ',tolwfr,ch10,&
936 1362 : ' iband, isppol, individual band residuals (max over all k-points):'
937 681 : call wrtout(std_out, message2)
938 1524 : do isppol = 1, dtset%nsppol
939 9281 : do iband = 1, dtset%mband
940 7757 : write(message3, '(2i6, es11.3)') iband, isppol, residm_band(iband,isppol)
941 8600 : call wrtout(std_out,message3)
942 : end do
943 : end do
944 :
945 : else
946 : write(message, '(a,es11.3,a,es11.3,a)' ) &
947 0 : ' maximum grdnorm=',residm,' exceeds tolwfr=',tolwfr,ch10
948 : end if
949 :
950 1251 : else if (ttoldff==1) then
951 : write(message, '(a,es11.3,a,es11.3,a)' ) &
952 460 : ' maximum force difference=',diffor,' exceeds toldff=',toldff,ch10
953 :
954 791 : else if (ttoldmag==1) then
955 : write(message, '(a,es11.3,a,es11.3,a)' ) &
956 0 : ' maximum magnetization difference=',difmagsph,' exceeds toldmag=',toldmag,ch10
957 :
958 791 : else if (ttolrff==1) then
959 : write(message, '(a,es11.3,a,es11.3,a)' ) &
960 11 : ' maximum force difference=',diffor,' exceeds tolrff*maxfor=',tolrff*maxfor,ch10
961 :
962 780 : else if (ttoldfe==1) then
963 : write(message, '(a,es11.3,a,es11.3,a)' ) &
964 250 : ' maximum energy difference=',abs(deltae),' exceeds toldfe=',toldfe,ch10
965 :
966 530 : else if(ttolvrs==1)then
967 530 : if (optres==0) then
968 : write(message, '(a,es11.3,a,es11.3,a)' ) &
969 174 : ' potential residual=',res2,' exceeds tolvrs=',tolvrs,ch10
970 : else
971 : write(message, '(a,es11.3,a,es11.3,a)' ) &
972 356 : ' density residual=',res2,' exceeds tolvrs=',tolvrs,ch10
973 : end if
974 : end if
975 5796 : call wrtout([std_out, ab_out], message)
976 :
977 1932 : if (prtxml == 1) then
978 0 : write(ab_xml_out, "(A)", advance = "NO") ' <status cvState="Failed"'
979 : end if
980 :
981 : else
982 : ! Convergence is OK
983 7293 : if (prtxml == 1) then
984 4 : write(ab_xml_out, "(A)", advance = "NO") ' <status cvState="Ok"'
985 : end if
986 : end if ! test for convergence reached or not
987 :
988 9225 : if (prtxml == 1) then
989 4 : if (ttoldfe == 1) then
990 4 : if (ttolwfr==0) then
991 4 : write(ab_xml_out, "(A)") ' stop-criterion="toldfe" />'
992 : else
993 0 : write(ab_xml_out, "(A)") ' stop-criterion="toldfe+tolwfr" />'
994 : end if
995 0 : else if (ttoldff == 1) then
996 0 : if (ttolwfr==0) then
997 0 : write(ab_xml_out, "(A)") ' stop-criterion="toldff" />'
998 : else
999 0 : write(ab_xml_out, "(A)") ' stop-criterion="toldff+tolwfr" />'
1000 : end if
1001 0 : else if (ttoldmag == 1) then
1002 0 : if (ttolwfr==0) then
1003 0 : write(ab_xml_out, "(A)") ' stop-criterion="toldmag" />'
1004 : else
1005 0 : write(ab_xml_out, "(A)") ' stop-criterion="toldmag+tolwfr" />'
1006 : end if
1007 0 : else if (ttolrff == 1) then
1008 0 : if (ttolwfr==0) then
1009 0 : write(ab_xml_out, "(A)") ' stop-criterion="tolrff" />'
1010 : else
1011 0 : write(ab_xml_out, "(A)") ' stop-criterion="tolrff+tolwfr" />'
1012 : end if
1013 0 : else if (ttolvrs == 1) then
1014 0 : if (ttolwfr==0) then
1015 0 : write(ab_xml_out, "(A)") ' stop-criterion="tolvrs" />'
1016 : else
1017 0 : write(ab_xml_out, "(A)") ' stop-criterion="tolvrs+tolwfr" />'
1018 : end if
1019 0 : else if (ttolwfr == 1) then
1020 0 : write(ab_xml_out, "(A)") ' stop-criterion="tolwfr" />'
1021 : else
1022 0 : write(ab_xml_out, "(A)") ' />'
1023 : end if
1024 : end if
1025 :
1026 : ! If enabled, output a YAML document with the ETOT iterations
1027 : !if (etot_yaml_doc%stream%length > 0) call etot_yaml_doc%write_and_free(ab_out)
1028 : end if ! nstep == 0 : no output
1029 :
1030 : case default
1031 0 : write(message, '(a,i0,a)' )' choice = ',choice,' is not an allowed value.'
1032 149264 : ABI_BUG(message)
1033 : end select
1034 :
1035 : ! Additional stuff for the Fock+SCF cycle
1036 83892 : if (present(fock)) then
1037 53730 : if (associated(fock)) then
1038 1498 : fock%fock_common%scf_converged=(quit==1)
1039 : ! At present, the decision that the Fock loop is converged is not taken here
1040 1498 : if (.not.fock%fock_common%fock_converged)quit=0
1041 : end if
1042 : end if
1043 :
1044 : ! Additional stuff for the two-component DFT SCF cycle (electrons+positron)
1045 83892 : if (present(electronpositron)) then
1046 53730 : if (associated(electronpositron)) then
1047 579 : electronpositron%scf_converged=(quit==1)
1048 579 : if (dtset%positron<0) then
1049 530 : diff_e=abs(etotal-electronpositron%etotal_prev)
1050 530 : diff_f=abs(maxfor-electronpositron%maxfor_prev)
1051 : end if
1052 579 : if (choice==1) then
1053 0 : ttoldff=0;ttoldfe=0
1054 0 : if(abs(dtset%postoldff)>tiny(0.0_dp))ttoldff=1
1055 0 : if(abs(dtset%postoldfe)>tiny(0.0_dp))ttoldfe=1
1056 0 : if (dtset%positron<0.and.ttoldff+ttoldfe/=1.and.iscf>0) then
1057 0 : ABI_ERROR('one and only one of toldff or toldfe must differ from zero !')
1058 : end if
1059 : end if
1060 579 : if (choice==2) then
1061 562 : if (dtset%positron<0.and.istep<=nstep) then
1062 519 : if (electronpositron%scf_converged) then
1063 81 : if (electronpositron%istep/=electronpositron%nstep) then
1064 : if ((.not.noquit).and.&
1065 75 : & (diff_e<electronpositron%postoldfe.or.diff_f<electronpositron%postoldff).and.&
1066 : & (mod(electronpositron%calctype,2)==0.or.(dtset%positron>-20.and.dtset%positron/=-2))) then
1067 5 : if (diff_e<electronpositron%postoldfe) then
1068 5 : write(message, '(2a,i5,5a,es11.3,a,es11.3)' ) ch10, &
1069 5 : & ' At SCF step',istep,', the difference between',ch10,&
1070 5 : & ' etotal from electronic calculation and etotal from positronic calculation',ch10,&
1071 10 : & ' is converged : diff(etot_el-etot_pos)=',diff_e,' < postoldfe=',electronpositron%postoldfe
1072 : else
1073 0 : write(message, '(2a,i5,5a,es11.3,a,es11.3)' ) ch10, &
1074 0 : & ' At SCF step',istep,', the difference between',ch10,&
1075 0 : & ' max. force from electronic calculation and max. force from positronic calculation',ch10,&
1076 0 : & ' is converged : diff(maxfor_el-maxfor_pos)=',diff_f,' < postoldff=',electronpositron%postoldff
1077 : end if
1078 15 : call wrtout([std_out, ab_out], message)
1079 : else
1080 70 : quit=0
1081 : end if
1082 : end if
1083 : end if
1084 : end if
1085 : end if
1086 579 : if (choice==3) then
1087 17 : if (dtset%positron<0.and.nstep>0)then
1088 11 : if (diff_e>=electronpositron%postoldfe.and.abs(dtset%postoldfe)>tiny(0.0_dp)) then
1089 5 : write(message, '(4a,i5,5a,es11.3,a,es11.3)' ) ch10,&
1090 5 : & ' scprqt: WARNING -',ch10,&
1091 5 : & ' posnstep=',dtset%posnstep,' was not enough SCF cycles to converge difference between',ch10,&
1092 5 : & ' etotal from electronic calculation and etotal from positronic calculation;',ch10,&
1093 10 : & ' diff=',diff_e,' exceeds postoldfe=',electronpositron%postoldfe
1094 15 : call wrtout([std_out, ab_out], message)
1095 : end if
1096 11 : if (diff_f>=electronpositron%postoldff.and.abs(dtset%postoldff)>tiny(0.0_dp)) then
1097 1 : write(message, '(4a,i5,5a,es11.3,a,es11.3)' ) ch10,&
1098 1 : & ' scprqt: WARNING -',ch10,&
1099 1 : & ' posnstep=',dtset%posnstep,' was not enough SCF cycles to converge difference between',ch10,&
1100 1 : & ' max. force from electronic calculation and max. force from positronic calculation;',ch10,&
1101 2 : & ' diff=',diff_e,' exceeds postoldff=',electronpositron%postoldff
1102 3 : call wrtout([std_out, ab_out], message)
1103 : end if
1104 : end if
1105 : end if
1106 : end if
1107 : end if
1108 :
1109 167784 : call flush_unit(ab_out)
1110 :
1111 : DBG_EXIT("COLL")
1112 :
1113 : contains
1114 :
1115 9225 : logical function converged()
1116 :
1117 : ! LB-02/01/2017:
1118 : ! This code avoids evaluation of undefined variables (which could happen in respfn, apparently)
1119 : logical :: loc_conv
1120 9225 : loc_conv = .true.
1121 9225 : if (ttolwfr==1) then
1122 2839 : if (residm > tolwfr) loc_conv=.false.
1123 : end if
1124 9225 : if (ttoldff==1) then
1125 2673 : if (diffor > toldff) loc_conv=.false.
1126 : end if
1127 9225 : if (ttoldmag==1) then
1128 2 : if (difmagsph > toldmag) loc_conv=.false.
1129 : end if
1130 9225 : if (ttolrff==1) then
1131 132 : if (diffor > tolrff*maxfor .and. maxfor > tol16) loc_conv=.false.
1132 : end if
1133 9225 : if (ttoldfe==1) then
1134 1266 : if (abs(deltae) > toldfe) loc_conv=.false.
1135 : end if
1136 9225 : if (ttolvrs==1) then
1137 2337 : if (res2 > tolvrs) loc_conv=.false.
1138 : end if
1139 9225 : converged = loc_conv
1140 :
1141 9225 : end function converged
1142 :
1143 : end subroutine scprqt
1144 : !!***
1145 :
1146 : !!****f* ABINIT/setup1
1147 : !! NAME
1148 : !! setup1
1149 : !!
1150 : !! FUNCTION
1151 : !! Call near top of main routine to handle setup of various arrays,
1152 : !! filenames, checking of input data, etc.
1153 : !!
1154 : !! INPUTS
1155 : !! acell(3)=length scales (bohr)
1156 : !! ecut_eff=effective energy cutoff (hartree) for planewave basis sphere
1157 : !! ecutc_eff=- PAW only - effective energy cutoff (hartree) for the coarse grid
1158 : !! natom=number of atoms
1159 : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
1160 : !! ngfftc(18)=contain all needed information about 3D FFT for the coarse grid
1161 : !! nkpt=number of k points
1162 : !! nsppol=1 for unpolarized, 2 for spin-polarized
1163 : !! ntypat=number of types of atoms
1164 : !! response=0 if called by gstate, =1 if called by respfn
1165 : !! rprim(3,3)=dimensionless real space primitive translations
1166 : !! usepaw= 0 for non paw calculation; =1 for paw calculation
1167 : !!
1168 : !! OUTPUT
1169 : !! bantot=total number of bands at all k points
1170 : !! gmet(3,3)=metric for reciprocal space inner products (bohr^-2)
1171 : !! gprimd(3,3)=dimens. primitive translations for reciprocal space (bohr**-1)
1172 : !! gsqcut_eff=Fourier cutoff on G^2 for "large sphere" of radius double
1173 : !! gsqcutc_eff=(PAW) Fourier cutoff on G^2 for "large sphere" of radius double for the coarse FFT grid
1174 : !! that of the basis sphere--appropriate for charge density rho(G),
1175 : !! Hartree potential, and pseudopotentials, corresponding to ecut_eff
1176 : !! rmet(3,3)=real space metric (bohr**2)
1177 : !! rprimd(3,3)=dimensional primitive translations in real space (bohr)
1178 : !! ucvol=unit cell volume (bohr^3)
1179 : !!
1180 : !! NOTES
1181 : !! SHOULD BE CLEANED !
1182 : !!
1183 : !! SOURCE
1184 :
1185 12880 : subroutine setup1(acell,bantot,dtset,ecut_eff,ecutc_eff,gmet,&
1186 : & gprimd,gsqcut_eff,gsqcutc_eff,ngfft,ngfftc,nkpt,nsppol,&
1187 : & response,rmet,rprim,rprimd,ucvol,usepaw)
1188 :
1189 : !Arguments ------------------------------------
1190 : !scalars
1191 : type(dataset_type),intent(in) :: dtset
1192 : integer,intent(in) :: nkpt,nsppol
1193 : integer,intent(in) :: response,usepaw
1194 : integer,intent(out) :: bantot
1195 : real(dp),intent(in) :: ecut_eff,ecutc_eff
1196 : real(dp),intent(out) :: gsqcut_eff,gsqcutc_eff,ucvol
1197 : !arrays
1198 : integer,intent(in) :: ngfft(18),ngfftc(18)
1199 : real(dp),intent(in) :: acell(3),rprim(3,3)
1200 : real(dp),intent(out) :: gmet(3,3),gprimd(3,3),rmet(3,3)
1201 : real(dp),intent(out) :: rprimd(3,3)
1202 :
1203 : !Local variables-------------------------------
1204 : !scalars
1205 : integer :: ikpt,isppol
1206 : real(dp) :: boxcut,boxcutc
1207 : character(len=500) :: msg
1208 : !arrays
1209 : real(dp) :: k0(3)
1210 :
1211 : ! ************************************************************************
1212 :
1213 : ! Compute bantot
1214 6440 : bantot=0
1215 13489 : do isppol=1,nsppol
1216 144698 : do ikpt=1,nkpt
1217 138258 : bantot=bantot+dtset%nband(ikpt+(isppol-1)*nkpt)
1218 : end do
1219 : end do
1220 :
1221 6440 : if(dtset%nqpt>1.or.dtset%nqpt<0) then
1222 : write(msg,'(a,i0,5a)')&
1223 0 : 'nqpt =',dtset%nqpt,' is not allowed',ch10,'(only 0 or 1 are allowed).',ch10,'Action: correct your input file.'
1224 0 : ABI_ERROR(msg)
1225 : end if
1226 :
1227 : ! Compute dimensional primitive translations rprimd
1228 6440 : call mkrdim(acell,rprim,rprimd)
1229 :
1230 : ! Obtain dimensional translations in reciprocal space gprimd,
1231 : ! metrics and unit cell volume, from rprimd.
1232 : ! Also output rprimd, gprimd and ucvol
1233 6440 : call metric(gmet,gprimd,ab_out,rmet,rprimd,ucvol)
1234 :
1235 : ! Get boxcut for given acell, gmet, ngfft, and ecut_eff
1236 : ! (center at 000 for groundstate, center at q for respfn):
1237 : ! boxcut=ratio of basis sphere diameter to fft box side
1238 6440 : k0(:)=0.0_dp
1239 6440 : if(response==1 .and. dtset%nqpt==1)then
1240 2408 : k0(:)=dtset%qptn(:)
1241 1806 : call wrtout([std_out, ab_out], ' setup1 : take into account q-point for computing boxcut.')
1242 : end if
1243 6440 : if (usepaw==1) then
1244 1431 : write(msg,'(2a)') ch10,' Coarse grid specifications (used for wave-functions):'
1245 4293 : call wrtout([std_out, ab_out], msg)
1246 1431 : call getcut(boxcutc,ecutc_eff,gmet,gsqcutc_eff,dtset%iboxcut,ab_out,k0,ngfftc)
1247 1431 : write(msg,'(2a)') ch10,' Fine grid specifications (used for densities):'
1248 4293 : call wrtout([std_out, ab_out], msg)
1249 1431 : call getcut(boxcut,ecut_eff,gmet,gsqcut_eff,dtset%iboxcut,ab_out,k0,ngfft)
1250 : else
1251 5009 : call getcut(boxcut,ecut_eff,gmet,gsqcut_eff,dtset%iboxcut,ab_out,k0,ngfft)
1252 5009 : gsqcutc_eff=gsqcut_eff
1253 : end if
1254 :
1255 : ! Check that boxcut>=2 if dtset%intxc=1; otherwise dtset%intxc must be set=0
1256 6440 : if (boxcut<2.0_dp.and.dtset%intxc==1) then
1257 : write(msg, '(a,es12.4,a,a,a,a,a)' )&
1258 0 : 'boxcut= ',boxcut,' is < 2.0 => intxc must be 0;',ch10,&
1259 0 : 'Need larger ngfft to use intxc=1.',ch10,&
1260 0 : 'Action: you could increase ngfft, or decrease ecut, or put intxcn=0.'
1261 0 : ABI_ERROR(msg)
1262 : end if
1263 :
1264 6440 : end subroutine setup1
1265 : !!***
1266 :
1267 : !!****f* ABINIT/prteigrs
1268 : !! NAME
1269 : !! prteigrs
1270 : !!
1271 : !! FUNCTION
1272 : !! Print out eigenvalues band by band and k point by k point.
1273 : !! If option=1, do it in a standard way, for self-consistent calculations.
1274 : !! If option=2, print out residuals and eigenvalues, in a format
1275 : !! adapted for nonself-consistent calculations, within the loops.
1276 : !! If option=3, print out eigenvalues, in a format
1277 : !! adapted for nonself-consistent calculations, at the end of the job.
1278 : !! If option=4, print out derivatives of eigenvalues (same format as option==3, except header that is printed)
1279 : !! If option=5, print out Fan contribution to zero-point motion correction to eigenvalues (averaged)
1280 : !! (same format as option==3, except header that is printed)
1281 : !! If option=6, print out DDW contribution to zero-point motion correction to eigenvalues (averaged)
1282 : !! (same format as option==3, except header that is printed)
1283 : !! If option=7, print out Fan+DDW contribution to zero-point motion correction to eigenvalues (averaged)
1284 : !! (same format as option==3, except header that is printed)
1285 : !!
1286 : !! INPUTS
1287 : !! eigen(mband*nkpt*nsppol)=eigenvalues (hartree)
1288 : !! or, if option==4, diagonal of derivative of eigenvalues
1289 : !! or, if option==5...7, zero-point motion correction to eigenvalues (averaged)
1290 : !! enunit=choice parameter: 0=>output in hartree; 1=>output in eV;
1291 : !! 2=> output in both hartree and eV
1292 : !! fermie=fermi energy (Hartree) / for electrons thermalized in the conduction bands when occopt==9
1293 : !! fermih=fermi energy (Hartree) for holes thermalized in the VB when occopt==9
1294 : !! fname_eig=filename of printing the eigenenergies
1295 : !! iout=unit number for formatted output file
1296 : !! iscf=option for self-consistency
1297 : !! kptns(3,nkpt)=k points in reduced coordinates
1298 : !! kptopt=option for the generation of k points
1299 : !! mband=maximum number of bands
1300 : !! nband(nkpt)=number of bands at each k point
1301 : !! nbdbuf= number of buffer bands
1302 : !! nkpt=number of k points
1303 : !! nnsclo_now=number of non-self-consistent loops for the current vtrial
1304 : !! (often 1 for SCF calculation, =nstep for non-SCF calculations)
1305 : !! nsppol=1 for unpolarized, 2 for spin-polarized
1306 : !! occ(maxval(nband(:))*nkpt*nsppol)=occupancies for each band and k point
1307 : !! occopt=option for occupancies
1308 : !! option= (see above)
1309 : !! prteig=control print eigenenergies
1310 : !! prtvol=control print volume and debugging
1311 : !! resid(mband*nkpt*nsppol)=residuals (hartree**2)
1312 : !! tolwfr=tolerance on band residual of wf, hartrees**2 (needed when option=2)
1313 : !! vxcavg=average of vxc potential
1314 : !! wtk(nkpt)=k-point weights
1315 : !!
1316 : !! OUTPUT
1317 : !! (only writing)
1318 : !!
1319 : !! SOURCE
1320 :
1321 12817 : subroutine prteigrs(eigen,enunit,fermie,fermih,fname_eig,iout,iscf,kptns,kptopt,mband,nband,&
1322 12817 : & nbdbuf,nkpt,nnsclo_now,nsppol,occ,occopt,option,prteig,prtvol,resid,tolwfr,vxcavg,wtk)
1323 :
1324 : !Arguments ------------------------------------
1325 : !scalars
1326 : integer,intent(in) :: enunit,iout,iscf,kptopt,mband,nbdbuf,nkpt,nnsclo_now,nsppol
1327 : integer,intent(in) :: occopt,option,prteig,prtvol
1328 : real(dp),intent(in) :: fermie,fermih,tolwfr,vxcavg
1329 : character(len=*),intent(in) :: fname_eig
1330 : !arrays
1331 : integer,intent(in) :: nband(nkpt*nsppol)
1332 : real(dp),intent(in) :: eigen(mband*nkpt*nsppol),kptns(3,nkpt)
1333 : real(dp),intent(in) :: occ(mband*nkpt*nsppol),resid(mband*nkpt*nsppol)
1334 : real(dp),intent(in) :: wtk(nkpt)
1335 :
1336 : !Local variables-------------------------------
1337 : !scalars
1338 : integer,parameter :: nkpt_max=50
1339 : integer :: band_index,iband,ienunit,ii,ikpt,isppol,nband_index,nband_k,nkpt_eff,tmagnet,tmetal,temp_unit
1340 : real(dp) :: convrt,magnet,residk,rhodn,rhoup
1341 : character(len=2) :: ibnd_fmt,ikpt_fmt
1342 : character(len=7) :: strunit1,strunit2
1343 : character(len=39) :: kind_of_output
1344 : character(len=500) :: msg
1345 :
1346 : ! *************************************************************************
1347 :
1348 12817 : if (enunit<0.or.enunit>2) then
1349 0 : ABI_BUG(sjoin('enunit must be 0, 1 or 2. Argument was:', itoa(enunit)))
1350 : end if
1351 :
1352 12817 : if (prteig > 0) then
1353 8821 : call wrtout(iout, sjoin(' prteigrs : about to open file ', fname_eig))
1354 8821 : if (open_file(fname_eig, msg, newunit=temp_unit, status='unknown', form='formatted') /= 0) then
1355 0 : ABI_ERROR(msg)
1356 : end if
1357 8821 : rewind(temp_unit) ! always rewind disk file and print latest eigenvalues
1358 : end if
1359 :
1360 12817 : kind_of_output= ' Eigenvalues '
1361 12817 : if(option==4) kind_of_output=' Expectation of eigenvalue derivatives'
1362 12817 : if(option==5) kind_of_output=' Fan corrections to eigenvalues at T=0'
1363 12817 : if(option==6) kind_of_output=' DDW corrections to eigenvalues at T=0'
1364 12817 : if(option==7) kind_of_output=' Fan+DDW corrs to eigenvalues at T=0'
1365 :
1366 12817 : nkpt_eff=nkpt
1367 :
1368 : !write(msg,'(a,5i5)')' prtvol,iscf,kptopt,nkpt_eff,nkpt_max ',prtvol,iscf,kptopt,nkpt_eff,nkpt_max
1369 : !call wrtout(iout,msg)
1370 :
1371 12817 : if( (prtvol==0.or.prtvol==1) .and. (iscf/=-2 .or. kptopt>0) .and. nkpt_eff>nkpt_max)nkpt_eff=nkpt_max
1372 12817 : if( (prtvol==0.or.prtvol==1) .and. (iscf/=-2 .or. kptopt>0) .and. nkpt_eff>1 .and. iout==ab_out)nkpt_eff=1
1373 :
1374 12817 : if(option==1 .or. (option>=3 .and. option<=7))then
1375 :
1376 37149 : do ienunit=0,1
1377 :
1378 24766 : if (enunit==1 .and. ienunit==0)cycle
1379 24488 : if (enunit==0 .and. ienunit==1)cycle
1380 : ! Print eigenvalues in hartree for enunit=0 or 2
1381 : ! The definition of two different strings is quite ridiculous. Historical reasons ...
1382 :
1383 14935 : if (ienunit==0)then
1384 12105 : convrt=one
1385 12105 : strunit1='hartree'
1386 12105 : strunit2='hartree'
1387 : end if
1388 14935 : if (ienunit==1)then
1389 2830 : convrt=Ha_eV
1390 2830 : strunit1=' eV '
1391 2830 : strunit2='eV '
1392 : end if
1393 :
1394 14935 : band_index=0
1395 :
1396 14935 : if(ienunit==0)then ! XG20140730 I do not know why this is only done when ienunit==0
1397 12105 : tmetal=0
1398 12105 : if(option==1 .and. occopt>=3 .and. occopt<=8)tmetal=1
1399 2972 : tmagnet=0
1400 2972 : if(tmetal==1 .and. nsppol==2)then
1401 290 : tmagnet=1
1402 290 : rhoup = 0._dp
1403 290 : rhodn = 0._dp
1404 290 : nband_index = 1
1405 870 : do isppol=1,nsppol
1406 5310 : do ikpt=1,nkpt
1407 4440 : nband_k=nband(ikpt+(isppol-1)*nkpt)
1408 76024 : do iband=1,nband_k
1409 71004 : if(isppol==1) rhoup = rhoup + wtk(ikpt)*occ(nband_index)
1410 71004 : if(isppol==2) rhodn = rhodn + wtk(ikpt)*occ(nband_index)
1411 75444 : nband_index = nband_index + 1
1412 : end do
1413 : end do
1414 : end do
1415 290 : magnet = abs(rhoup - rhodn)
1416 : end if
1417 : end if
1418 :
1419 14935 : if(iscf>=0 .and. (ienunit==0 .or. option==1))then
1420 13076 : if (occopt == 9) then
1421 : write(msg, '(3a,f10.5,a,f10.5,3a,f10.5)' ) &
1422 2 : ' Fermi energy for thermalized electrons and holes (',trim(strunit2),') =',&
1423 4 : convrt*fermie,', ',convrt*fermih,' Average Vxc (',trim(strunit2),')=',convrt*vxcavg
1424 : else
1425 : write(msg, '(3a,f10.5,3a,f10.5)' ) &
1426 13074 : ' Fermi (or HOMO) energy (',trim(strunit2),') =',convrt*fermie,' Average Vxc (',trim(strunit2),')=',convrt*vxcavg
1427 : end if
1428 13076 : call wrtout(iout,msg)
1429 13076 : if (prteig > 0) call wrtout(temp_unit,msg)
1430 : end if
1431 :
1432 : ! if( (iscf>=0 .or. iscf==-3) .and. ienunit==0)then ! This is the most correct
1433 14935 : if(iscf>=0 .and. ienunit==0)then ! For historical reasons
1434 10808 : if(tmagnet==1)then
1435 : write(msg, '(a,es16.8,a,a,es16.8,a,es16.8)' )&
1436 284 : ' Magnetization (Bohr magneton)=',magnet,ch10,&
1437 568 : ' Total spin up =',rhoup,' Total spin down =',rhodn
1438 284 : call wrtout(iout,msg)
1439 284 : if (prteig > 0) call wrtout(temp_unit,msg)
1440 : end if
1441 : end if
1442 :
1443 : ! Loop over spins (suppress spin data if nsppol not 2)
1444 44837 : do isppol=1,nsppol
1445 :
1446 17519 : ikpt_fmt="i4" ; if(nkpt>=10000)ikpt_fmt="i6" ; if(nkpt>=1000000)ikpt_fmt="i9"
1447 17519 : if (nsppol==2.and.isppol==1) then
1448 2584 : write(msg, '(4a,'//ikpt_fmt//',2x,a)' )trim(kind_of_output),' (',strunit1,') for nkpt=',nkpt,'k points, SPIN UP:'
1449 14935 : else if (nsppol==2.and.isppol==2) then
1450 2584 : write(msg, '(4a,'//ikpt_fmt//',2x,a)' )trim(kind_of_output),' (',strunit1,') for nkpt=',nkpt,'k points, SPIN DOWN:'
1451 : else
1452 12351 : write(msg, '(4a,'//ikpt_fmt//',2x,a)' )trim(kind_of_output),' (',strunit1,') for nkpt=',nkpt,'k points:'
1453 : end if
1454 17519 : call wrtout(iout,msg)
1455 17519 : if (prteig > 0) call wrtout(temp_unit,msg)
1456 :
1457 17519 : if(ienunit==0)then
1458 13889 : if(option>=4 .and. option<=7)then
1459 556 : msg = ' (in case of degenerate eigenvalues, averaged derivative)'
1460 556 : call wrtout(iout,msg)
1461 556 : if (prteig > 0) call wrtout(temp_unit,msg)
1462 : end if
1463 : end if
1464 :
1465 194964 : do ikpt=1,nkpt
1466 152679 : nband_k=nband(ikpt+(isppol-1)*nkpt)
1467 152679 : ikpt_fmt="i4" ; if(nkpt>=10000)ikpt_fmt="i6" ; if(nkpt>=1000000)ikpt_fmt="i9"
1468 152679 : ibnd_fmt="i3" ; if(nband_k>=1000)ibnd_fmt="i6" ; if(nband_k>=1000000)ibnd_fmt="i9"
1469 152679 : if(ikpt<=nkpt_eff)then
1470 : write(msg, '(a,'//ikpt_fmt//',a,'//ibnd_fmt//',a,f9.5,a,3f8.4,a)' ) &
1471 266116 : & ' kpt#',ikpt,', nband=',nband_k,', wtk=',wtk(ikpt)+tol10,', kpt=',kptns(1:3,ikpt)+tol10,' (reduced coord)'
1472 66529 : call wrtout(iout,msg)
1473 66529 : if (prteig > 0) call wrtout(temp_unit,msg)
1474 166370 : do ii=0,(nband_k-1)/8
1475 616773 : write(msg, '(8(f10.5,1x))' ) (convrt*eigen(iband+band_index), iband=1+ii*8,min(nband_k,8+ii*8))
1476 99841 : call wrtout(iout,msg)
1477 166370 : if (prteig > 0) call wrtout(temp_unit,msg)
1478 : end do
1479 66529 : if(ienunit==0 .and. option==1 .and. occopt>=3 .and. occopt<=8)then
1480 13848 : write(msg, '(5x,a,'//ikpt_fmt//')' ) ' occupation numbers for kpt#',ikpt
1481 13848 : call wrtout(iout,msg)
1482 41762 : do ii=0,(nband_k-1)/8
1483 203474 : write(msg, '(8(f10.5,1x))' ) (occ(iband+band_index),iband=1+ii*8,min(nband_k,8+ii*8))
1484 41762 : call wrtout(iout,msg)
1485 : end do
1486 : end if
1487 :
1488 : else
1489 86150 : if(ikpt==nkpt_eff+1)then
1490 3524 : write(msg, '(a,a)' )' prteigrs : prtvol=0 or 1, do not print more k-points.',ch10
1491 3524 : call wrtout(iout,msg)
1492 : end if
1493 86150 : if (prteig > 0) then
1494 : write(msg, '(a,'//ikpt_fmt//',a,'//ibnd_fmt//',a,f9.5,a,3f8.4,a)' ) &
1495 210972 : & ' kpt#',ikpt,', nband=',nband_k,', wtk=',wtk(ikpt)+tol10,', kpt=',kptns(1:3,ikpt)+tol10,' (reduced coord)'
1496 52743 : call wrtout(temp_unit,msg)
1497 126778 : do ii=0,(nband_k-1)/8
1498 481557 : write(msg, '(8(f10.5,1x))' ) (convrt*eigen(iband+band_index),iband=1+ii*8,min(nband_k,8+ii*8))
1499 126778 : call wrtout(temp_unit,msg)
1500 : end do
1501 : end if
1502 : end if
1503 170198 : band_index=band_index+nband_k
1504 : end do ! do ikpt=1,nkpt
1505 : end do ! do isppol=1,nsppol
1506 :
1507 : end do ! End loop over Hartree or eV
1508 :
1509 434 : else if(option==2)then
1510 :
1511 : band_index=0
1512 894 : do isppol=1,nsppol
1513 :
1514 460 : if(nsppol==2)then
1515 52 : if(isppol==1)write(msg, '(2a)' ) ch10,' SPIN UP channel '
1516 52 : if(isppol==2)write(msg, '(2a)' ) ch10,' SPIN DOWN channel '
1517 52 : call wrtout(iout,msg)
1518 52 : if(prteig>0) call wrtout(temp_unit,msg)
1519 : end if
1520 :
1521 15169 : do ikpt=1,nkpt
1522 14275 : nband_k=nband(ikpt+(isppol-1)*nkpt)
1523 14275 : ikpt_fmt="i5" ; if(nkpt>=10000)ikpt_fmt="i7" ; if(nkpt>=1000000)ikpt_fmt="i9"
1524 :
1525 14275 : if(ikpt<=nkpt_eff)then
1526 : write(msg, '(1x,a,'//ikpt_fmt//',a,f9.5,2f9.5,a)' ) &
1527 3190 : & 'Non-SCF case, kpt',ikpt,' (',(kptns(ii,ikpt),ii=1,3),'), residuals and eigenvalues='
1528 3190 : call wrtout(iout,msg)
1529 3190 : if (prteig > 0) then
1530 : write(msg, '(1x,a,'//ikpt_fmt//',a,f9.5,2f9.5,a)' ) &
1531 3185 : & 'Non-SCF case, kpt',ikpt,' eig(',(kptns(ii,ikpt),ii=1,3),') '
1532 3185 : call wrtout(temp_unit,msg)
1533 : end if
1534 8606 : do ii=0,(nband_k-1)/8
1535 39588 : write(msg, '(1p,8e10.2)' )(resid(iband+band_index),iband=1+8*ii,min(8+8*ii,nband_k))
1536 8606 : call wrtout(iout,msg)
1537 : end do
1538 9715 : do ii=0,(nband_k-1)/6
1539 40697 : write(msg, '(1p,6e12.4)' )(eigen(iband+band_index),iband=1+6*ii,min(6+6*ii,nband_k))
1540 6525 : call wrtout(iout,msg)
1541 9715 : if (prteig > 0) call wrtout(temp_unit,msg)
1542 : end do
1543 : else
1544 11085 : if(ikpt==nkpt_eff+1)then
1545 226 : write(msg, '(a,a)' )' prteigrs : prtvol=0 or 1, do not print more k-points.',ch10
1546 226 : call wrtout(iout,msg)
1547 : end if
1548 11085 : if (prteig > 0) then
1549 9786 : write(msg, '(1x,a,i5,a,f9.5,2f9.5,a)' )'Non-SCF kpt',ikpt,' eig(',(kptns(ii,ikpt),ii=1,3),') '
1550 9786 : call wrtout(temp_unit,msg)
1551 28082 : do ii=0,(nband_k-1)/6
1552 103144 : write(msg, '(1p,6e12.4)' )(eigen(iband+band_index),iband=1+6*ii,min(6+6*ii,nband_k))
1553 28082 : call wrtout(temp_unit,msg)
1554 : end do
1555 : end if
1556 : end if
1557 :
1558 : ! Don't include the buffer in the output.
1559 14275 : if (nbdbuf>0) then
1560 99907 : residk=maxval(resid(band_index+1:band_index+nband_k-nbdbuf))
1561 : else
1562 31473 : residk=maxval(resid(band_index+1:band_index+nband_k))
1563 : end if
1564 14275 : if (residk>tolwfr) then
1565 : write(msg, '(1x,a,2i5,a,1p,e13.5)' ) &
1566 709 : ' prteigrs : nnsclo,ikpt=',nnsclo_now,ikpt,' max resid (excl. the buffer)=',residk
1567 709 : call wrtout(iout,msg)
1568 : end if
1569 :
1570 14735 : band_index=band_index+nband_k
1571 : end do
1572 : end do
1573 434 : call wrtout(iout," ")
1574 :
1575 : else
1576 0 : ABI_BUG(sjoin('option:', itoa(option),', is not allowed.'))
1577 : end if
1578 :
1579 12817 : if (prteig > 0) close (temp_unit)
1580 :
1581 12817 : end subroutine prteigrs
1582 : !!***
1583 :
1584 : !!****f* ABINIT/prtene
1585 : !!
1586 : !! NAME
1587 : !! prtene
1588 : !!
1589 : !! FUNCTION
1590 : !! Print components of total energy in nice format
1591 : !!
1592 : !! INPUTS
1593 : !! dtset <type(dataset_type)>=all input variables in this dataset
1594 : !! | berryphase
1595 : !! | kptopt
1596 : !! | occopt
1597 : !! | positron=option for electron-positron calculation
1598 : !! | tphysel="physical" electronic temperature with FD occupations
1599 : !! | tsmear=smearing energy or temperature (if metal)
1600 : !! energies <type(energies_type)>=values of parts of total energy
1601 : !! iout=unit number to which output is written
1602 : !! usepaw= 0 for non paw calculation; =1 for paw calculation
1603 : !!
1604 : !! OUTPUT
1605 : !! (only writing)
1606 : !!
1607 : !! SOURCE
1608 :
1609 5277 : subroutine prtene(dtset,energies,iout,usepaw)
1610 :
1611 : !Arguments ------------------------------------
1612 : !scalars
1613 : integer,intent(in) :: iout,usepaw
1614 : type(dataset_type),intent(in) :: dtset
1615 : type(energies_type),intent(inout) :: energies
1616 :
1617 : !Local variables-------------------------------
1618 : !scalars
1619 : integer :: ipositron,optdc
1620 : logical :: directE_avail,testdmft,write_entropy=.false.,write_totalxc=.false.,write_epaw_core=.false.
1621 : real(dp) :: eent,enevalue,etotal,etotaldc,exc_semilocal,el_temp
1622 : ! Do not modify the length of these strings
1623 : character(len=14) :: eneName
1624 : character(len=500) :: info,msg
1625 : type(yamldoc_t) :: edoc,dc_edoc,pawcore_edoc,sdoc,ftxcdoc
1626 : !arrays
1627 : !character(len=10) :: EPName(1:2)=(/"Positronic","Electronic"/)
1628 :
1629 : ! *************************************************************************
1630 :
1631 1376 : directE_avail=(usepaw==0.or.dtset%pawspnorb==0.or.dtset%pawcpxocc==2.or.dtset%kptopt==1.or.dtset%kptopt==2)
1632 :
1633 : !============= Evaluate some parts of the energy ===========
1634 :
1635 5277 : optdc=-1;ipositron=merge(0,2,dtset%positron==0)
1636 5277 : if (abs(energies%e_ewald)<1.e-15_dp.and.abs(energies%e_hartree)<1.e-15_dp) ipositron=1
1637 5277 : call energies%eval_eint(dtset,usepaw,optdc,etotal,etotaldc)
1638 :
1639 5277 : call entropy(dtset,energies)
1640 5277 : eent=energies%e_entropy
1641 :
1642 : ! If DMFT is used and DMFT Entropy is not computed, then do not print
1643 : ! non interacting entropy
1644 : testdmft=(dtset%dmftcheck>=0.and.dtset%usedmft>=1.and.(sum(dtset%upawu(:,1))>=tol8.or. &
1645 20547 : & sum(dtset%jpawu(:,1))>tol8).and.dtset%dmft_entropy==0)
1646 : if (dtset%usedmft==1.and.dtset%dmft_triqs_entropy==1.and.dtset%dmft_triqs_compute_integral>0 &
1647 5277 : & .and.(dtset%dmft_solv==6.or.dtset%dmft_solv==7)) testdmft=.false.
1648 5277 : if(testdmft) eent=zero
1649 :
1650 5277 : etotal = etotal + eent
1651 5277 : etotaldc = etotaldc + eent
1652 :
1653 : !============= Printing of Etotal by direct scheme ===========
1654 :
1655 5277 : if (dtset%icoulomb == 1) then
1656 0 : eneName = "Ion-ion energy"
1657 : else
1658 5277 : eneName = "Ewald energy"
1659 : end if
1660 5277 : enevalue = energies%e_ewald
1661 :
1662 :
1663 5277 : if (optdc==0.or.optdc==2) then
1664 :
1665 5277 : if (directE_avail) then
1666 5276 : info = 'Components of total free energy in Hartree'
1667 5276 : if(testdmft) info = 'Components of total energy in Hartree'
1668 5276 : edoc = yamldoc_open('EnergyTerms', info=trim(adjustl(info)), width=20, real_fmt='(es21.14)')
1669 5276 : call edoc%add_real('kinetic', energies%e_kinetic)
1670 5276 : if(abs(energies%e_extfpmd)>tiny(zero)) call edoc%add_real('extfpmd',energies%e_extfpmd)
1671 5276 : if (ipositron/=1) then
1672 5271 : exc_semilocal=energies%e_xc+energies%e_hybcomp_E0-energies%e_hybcomp_v0+energies%e_hybcomp_v
1673 : ! XG20181025 This should NOT be a part of the semilocal XC energy, but treated separately.
1674 : ! At present, there is still a problem with the variational formulation for the Fock term with PAW.
1675 : ! So, for the time being, keep it inside.
1676 5271 : if(usepaw==1)exc_semilocal=exc_semilocal+energies%e_fock
1677 5271 : call edoc%add_real('hartree', energies%e_hartree)
1678 5271 : call edoc%add_real('xc', exc_semilocal)
1679 5271 : call edoc%add_real(eneName, enevalue)
1680 5271 : call edoc%add_real('psp_core', energies%e_corepsp)
1681 : #if defined DEV_YP_VDWXC
1682 : if ( (dtset%vdw_xc > 0) .and. (dtset%vdw_xc < 10) .and. (xc_vdw_status()) ) then
1683 : call edoc%add_real('VdWaals_df', energies%e_xc_vdw)
1684 : end if
1685 : #endif
1686 : end if
1687 5276 : call edoc%add_real('local_psp', energies%e_localpsp)
1688 5276 : if (usepaw==0) then
1689 3901 : if(abs(energies%e_fock0)<tol8)then
1690 3812 : call edoc%add_real('non_local_psp', energies%e_nlpsp_vfock)
1691 : else
1692 89 : call edoc%add_real('non_local_psp+x', energies%e_nlpsp_vfock-energies%e_fock0)
1693 : endif
1694 : else
1695 1375 : if (dtset%use_rcpaw/=0) then
1696 3 : call edoc%add_real('PAW spherical_terms', energies%paw%epaw)
1697 3 : call edoc%add_real('PAW core', energies%paw%epaw_core)
1698 1372 : else if (dtset%paw_add_core==1) then
1699 1 : call edoc%add_real('PAW spherical_terms', energies%paw%epaw-energies%paw%epaw_core)
1700 1 : call edoc%add_real('PAW core', energies%paw%epaw_core)
1701 : else
1702 1371 : call edoc%add_real('PAW spherical_terms', energies%paw%epaw)
1703 : end if
1704 : !!!XG20181025 Does not work (yet)...
1705 : !!!if(abs(energies%e_nlpsp_vfock)>tol8)then
1706 : !!! write(msg, '(a,es21.14)' )' Fock-type term = ',energies%e_nlpsp_vfock
1707 : !!! call wrtout(iout,msg)
1708 : !!! write(msg, '(a,es21.14)' ) ' -frozen Fock en.= ',-energies%e_fock0
1709 : !!! call wrtout(iout,msg)
1710 : !!!endif
1711 : end if
1712 56256 : if (ANY(ABS(dtset%nucdipmom)>tol8)) then
1713 24 : call edoc%add_real('nucl. magn. dipoles',energies%e_nucdip)
1714 : end if
1715 5276 : if ((dtset%vdw_xc>=5.and.dtset%vdw_xc<=7).and.ipositron/=1) then
1716 4 : call edoc%add_real('VdWaals_dft_d', energies%e_vdw_dftd)
1717 : end if
1718 5276 : if (dtset%nzchempot>=1) then
1719 7 : call edoc%add_real('chem_potential', energies%e_chempot)
1720 : end if
1721 5276 : if (dtset%usedmft==1) then
1722 152 : call edoc%add_real('interaction', energies%e_hu)
1723 152 : call edoc%add_real('-double_counting', -energies%e_dc)
1724 : end if
1725 5276 : if(dtset%occopt>=3.and.dtset%occopt<=8.and.ipositron==0) then
1726 1276 : call edoc%add_real('internal', etotal-eent)
1727 1276 : if(.not.testdmft) then
1728 1159 : call edoc%add_real('-kT*entropy', eent)
1729 : end if
1730 3994 : else if (ipositron/=0) then
1731 14 : if (dtset%occopt>=3.and.dtset%occopt<=8) then
1732 6 : call edoc%add_real('-kT*entropy', eent)
1733 : end if
1734 : !write(msg, '(3a,es21.14,a)' ) &
1735 : ! ' >>> ',EPName(ipositron),' E= ',etotal-energies%e0_electronpositron -energies%e_electronpositron,ch10
1736 : !call wrtout(iout,msg)
1737 : !write(msg, '(3a,es21.14,2a,es21.14)' ) &
1738 : ! ' ',EPName(3-ipositron),' ener.= ',energies%e0_electronpositron,ch10,&
1739 : ! ' EP interaction E= ' ,energies%e_electronpositron
1740 : !call wrtout(iout,msg)
1741 14 : if(ipositron == 1) then
1742 5 : call edoc%add_real('positronic', etotal - energies%e0_electronpositron-energies%e_electronpositron)
1743 5 : call edoc%add_real('electronic', energies%e0_electronpositron)
1744 : else
1745 9 : call edoc%add_real('electronic', etotal- energies%e0_electronpositron-energies%e_electronpositron)
1746 9 : call edoc%add_real('positronic', energies%e0_electronpositron)
1747 : end if
1748 14 : call edoc%add_real('electron_positron_interaction', energies%e_electronpositron)
1749 : end if
1750 : if ((dtset%berryopt==4 .or. dtset%berryopt==6 .or. dtset%berryopt==7 .or. &
1751 5276 : dtset%berryopt==14 .or. dtset%berryopt==16 .or. dtset%berryopt==17) .and.ipositron/=1) then
1752 25 : call edoc%add_real('electric', energies%e_elecfield)
1753 25 : call edoc%add_real('kohn_sham', etotal-energies%e_elecfield)
1754 : end if
1755 5276 : call edoc%add_real('total_energy', etotal)
1756 :
1757 : else
1758 : write(msg, '(9a)' ) &
1759 1 : ' COMMENT: ',ch10,&
1760 1 : ' "Direct" decomposition of total free energy cannot be printed out !!!',ch10,&
1761 1 : ' PAW contribution due to spin-orbit coupling cannot be evaluated',ch10,&
1762 1 : ' without the knowledge of imaginary part of Rhoij atomic occupancies',ch10,&
1763 2 : ' (computed only when pawcpxocc=2).'
1764 1 : call wrtout(iout,msg)
1765 : end if
1766 : end if
1767 : !============= Printing of Etotal by double-counting scheme ===========
1768 :
1769 5277 : if (optdc>=1) then
1770 :
1771 1501 : info = '"Double-counting" decomposition of free energy'
1772 1501 : if(testdmft) info = '"Double-counting" decomposition of internal energy'
1773 : dc_edoc = yamldoc_open('EnergyTermsDC', info=trim(adjustl(info)), &
1774 1501 : width=20, real_fmt="(es21.14)")
1775 1501 : call dc_edoc%add_real('band_energy', energies%e_eigenvalues)
1776 1501 : if(abs(energies%e_extfpmd)>tiny(0.0_dp)) then
1777 7 : call dc_edoc%add_real('extfpmd_dc',energies%edc_extfpmd)
1778 : end if
1779 1501 : if (ipositron/=1) then
1780 : !write(msg, '(2(a,es21.14,a),a,es21.14)' ) &
1781 : ! ' '//eneName//' =',enevalue,ch10,&
1782 : ! ' PspCore energy = ',energies%e_corepsp-energies%e_corepspdc,ch10,&
1783 : ! ' Dble-C XC-energy= ',-energies%e_hartree+energies%e_xc-energies%e_xcdc -energies%e_fock0 + &
1784 : ! energies%e_hybcomp_E0-energies%e_hybcomp_v0
1785 : !call wrtout(iout,msg)
1786 1496 : call dc_edoc%add_real(eneName, enevalue)
1787 1496 : call dc_edoc%add_real('psp_core', energies%e_corepsp-energies%e_corepspdc)
1788 : call dc_edoc%add_real('xc_dc', -energies%e_hartree+energies%e_xc-energies%e_xcdc - energies%e_fock0 + &
1789 1496 : energies%e_hybcomp_E0-energies%e_hybcomp_v0)
1790 : end if
1791 : if ((dtset%berryopt==4 .or. dtset%berryopt==6 .or. dtset%berryopt==7 .or. &
1792 1501 : dtset%berryopt==14 .or. dtset%berryopt==16 .or. dtset%berryopt==17).and.ipositron/=1) then
1793 9 : call dc_edoc%add_real('electric_field', energies%e_elecfield)
1794 : end if
1795 1501 : if (usepaw==1) then
1796 1374 : if (dtset%use_rcpaw/=0) then
1797 3 : call dc_edoc%add_real('PAW spherical_terms', energies%paw%epaw_dc)
1798 3 : call dc_edoc%add_real('PAW core dc', energies%paw%epaw_core_dc)
1799 1371 : else if (dtset%paw_add_core==1) then
1800 1 : call dc_edoc%add_real('PAW spherical_terms', energies%paw%epaw_dc-energies%paw%epaw_core)
1801 1 : call dc_edoc%add_real('PAW core', energies%paw%epaw_core)
1802 : else
1803 1370 : call dc_edoc%add_real('PAW spherical_terms', energies%paw%epaw_dc)
1804 : end if
1805 : end if
1806 1501 : if ((dtset%vdw_xc>=5.and.dtset%vdw_xc<=7).and.ipositron/=1) then
1807 0 : call dc_edoc%add_real('VdWaals_dft_d', energies%e_vdw_dftd)
1808 : end if
1809 1501 : if (dtset%nzchempot>=1) then
1810 0 : call dc_edoc%add_real('chem_potential', energies%e_chempot)
1811 : end if
1812 1501 : if (dtset%usedmft==1) then
1813 152 : call dc_edoc%add_real('interaction', energies%e_hu)
1814 152 : call dc_edoc%add_real('-double_counting', -energies%e_dc)
1815 : end if
1816 1501 : if(dtset%occopt>=3.and.dtset%occopt<=8.and.ipositron==0) then
1817 689 : if(.not.testdmft) then
1818 : !write(msg, '(a,es21.14,a,a,a,es21.14)' ) &
1819 : ! ' >>>>> Internal E= ',etotaldc-eent,ch10,ch10,&
1820 : ! ' -kT*entropy = ',eent
1821 : !call wrtout(iout,msg)
1822 572 : call dc_edoc%add_real('internal', etotaldc-eent)
1823 572 : call dc_edoc%add_real('-kT*entropy', eent)
1824 : else
1825 117 : call dc_edoc%add_real('internal', etotaldc-eent)
1826 : end if
1827 806 : else if (ipositron/=0) then
1828 12 : if (dtset%occopt>=3 .and. dtset%occopt<=8) then
1829 6 : call dc_edoc%add_real('-kT*entropy', eent)
1830 : end if
1831 : !write(msg, '(a,es21.14,4a,es21.14,a)' ) &
1832 : ! ' - EP dble-ct En.= ',-energies%edc_electronpositron,ch10,&
1833 : ! ' >>> ',EPName(ipositron),' E= ',etotaldc-energies%e0_electronpositron -energies%e_electronpositron,ch10
1834 : !call wrtout(iout,msg)
1835 : !write(msg, '(3a,es21.14,2a,es21.14)' ) &
1836 : ! ' ',EPName(3-ipositron),' ener.= ',energies%e0_electronpositron,ch10,&
1837 : ! ' EP interaction E= ' ,energies%e_electronpositron
1838 : !call wrtout(iout,msg)
1839 12 : call dc_edoc%add_real('electron_positron_dc', -energies%edc_electronpositron)
1840 12 : if(ipositron == 1) then
1841 5 : call dc_edoc%add_real('positronic', etotaldc-energies%e0_electronpositron-energies%e_electronpositron)
1842 5 : call dc_edoc%add_real('electronic', energies%e0_electronpositron)
1843 : else
1844 7 : call dc_edoc%add_real('electronic', etotaldc-energies%e0_electronpositron-energies%e_electronpositron)
1845 7 : call dc_edoc%add_real('positronic', energies%e0_electronpositron)
1846 : end if
1847 12 : call dc_edoc%add_real('electron_positron_interaction', energies%e_electronpositron)
1848 : end if
1849 :
1850 1501 : write(msg, '(a,es21.14)' ) ' >>>> Etotal (DC)= ',etotaldc
1851 : !call wrtout(iout,msg)
1852 1501 : call dc_edoc%add_real('total_energy_dc', etotaldc)
1853 : end if
1854 :
1855 : !======= Additional printing ==========
1856 :
1857 5277 : if (usepaw==0.and.optdc==0) then
1858 3774 : call edoc%add_real('total_energy_eV', etotal*Ha_eV)
1859 3774 : call edoc%add_real('band_energy', energies%e_eigenvalues)
1860 : end if
1861 :
1862 5277 : if ((optdc==0.or.optdc==2).and.(.not.directE_avail)) then
1863 : !write(msg, '(a,a,es18.10)' ) ch10,' Band energy (Ha)= ',energies%e_eigenvalues
1864 : !call wrtout(iout,msg)
1865 1 : call edoc%add_real('band_energy', energies%e_eigenvalues)
1866 : end if
1867 :
1868 5277 : if (usepaw==1) then
1869 1376 : if ((optdc==0.or.optdc==2).and.(directE_avail)) then
1870 1375 : call edoc%add_real('total_energy_eV', etotal*Ha_eV)
1871 : end if
1872 1376 : if (optdc>=1) then
1873 : !if (optdc==1) write(msg, '(a,a,es21.14)' ) ch10,' >Total DC energy in eV = ',etotaldc*Ha_eV
1874 : !if (optdc==2) write(msg, '(a,es21.14)' ) ' >Total DC energy in eV = ',etotaldc*Ha_eV
1875 : !call wrtout(iout,msg)
1876 1374 : call dc_edoc%add_real('total_energy_dc_eV', etotaldc*Ha_eV)
1877 : end if
1878 : end if
1879 :
1880 5277 : if( dtset%icoulomb/=1.and.abs(dtset%cellcharge(1))>tol8) then
1881 : write(msg, '(6a)' ) &
1882 23 : ch10,' Calculation was performed for a charged system with PBC',&
1883 23 : ch10,' You may consider including the monopole correction to the total energy',&
1884 46 : ch10,' The correction is to be divided by the dielectric constant'
1885 23 : call wrtout(iout,msg)
1886 23 : call edoc%add_real('monopole_correction', energies%e_monopole)
1887 23 : call edoc%add_real('monopole_correction_eV', energies%e_monopole*Ha_eV)
1888 : end if
1889 :
1890 : !Print total energy including PAW core contribution
1891 5277 : if (usepaw==1) then
1892 1376 : if (dtset%paw_add_core==0.and.dtset%use_rcpaw==0) then
1893 1372 : if (abs(energies%paw%epaw_core)>tiny(zero).or.abs(energies%paw%epaw_core_dc)>tiny(zero)) then
1894 494 : write_epaw_core=.true.
1895 494 : info = 'Components of total free energy, including PAW core contributions'
1896 : pawcore_edoc = yamldoc_open('EnergyTermsWithPAWCore', info=trim(adjustl(info)), &
1897 494 : width=20, real_fmt='(es21.14)')
1898 494 : call pawcore_edoc%add_real('Total energy', etotal+energies%paw%epaw_core)
1899 494 : if(optdc>=1) call pawcore_edoc%add_real('Total energy DC', etotaldc+energies%paw%epaw_core)
1900 494 : call pawcore_edoc%add_real('Total energy (eV)', (etotal+energies%paw%epaw_core)*Ha_eV)
1901 494 : if(optdc>=1) call pawcore_edoc%add_real('Total energy DC (eV)', (etotaldc+energies%paw%epaw_core)*Ha_eV)
1902 : end if
1903 : end if
1904 : end if
1905 :
1906 : !======== In case other sources of entropies than the non-interacting entropy =========
1907 : !============= of the Kohn-Sham states come into play, print the details ==============
1908 5277 : if(dtset%occopt>=3.and.dtset%occopt<=8) then
1909 1282 : if(abs(energies%entropy)>tiny(zero).and.abs(energies%entropy-energies%entropy_ks)>tiny(zero)) then
1910 11 : write_entropy=.true.
1911 : sdoc = yamldoc_open('EntropyTerms', info='Components of total entropy', &
1912 11 : & width=20, real_fmt="(es21.14)") ! in kB units
1913 11 : call sdoc%add_real('noninteracting',energies%entropy_ks) ! Noninteracting entropy = Entropy of the Kohn-Sham states
1914 11 : if(abs(energies%entropy_xc)>tiny(zero)) call sdoc%add_real('xc',energies%entropy_xc)
1915 11 : if(usepaw==1.and.abs(energies%paw%entropy_paw)>tiny(zero)) call sdoc%add_real('spherical_terms',energies%paw%entropy_paw)
1916 11 : if(abs(energies%entropy_extfpmd)>tiny(zero)) call sdoc%add_real('extfpmd',energies%entropy_extfpmd)
1917 11 : if(abs(energies%entropy_imp)>tiny(zero)) call sdoc%add_real('impurity',energies%entropy_imp)
1918 11 : call sdoc%add_real('total_entropy',energies%entropy) ! Total entropy energy
1919 : end if
1920 : end if
1921 :
1922 : !======== In case finite-temperature exchange-correlation functionals are used =========
1923 : !=================== write the total exchange-correlation components ===================
1924 : !=============================== For testing purposes only =============================
1925 5277 : if(abs(energies%entropy_xc)>tiny(zero)) then
1926 5 : write_totalxc=.false. ! For testing purposes only, set write_totalxc=.true.
1927 : if(write_totalxc) then
1928 : el_temp=merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
1929 : ftxcdoc = yamldoc_open('FTXCEnergyTerms', info='Components of total xc energy in Hartree', &
1930 : & width=20, real_fmt="(es21.14)")
1931 : if(usepaw==1) then
1932 : ! For now, only finite-temperature xc functionals contribute to entropy_paw.
1933 : ! We may introduce 'energies%entropy_pawxc' in the future.
1934 : call ftxcdoc%add_real('xc',energies%e_xc)
1935 : call ftxcdoc%add_real('spherical_terms_xc',energies%paw%epaw_xc)
1936 : call ftxcdoc%add_real('internal_xc',energies%e_xc+energies%paw%epaw_xc)
1937 : call ftxcdoc%add_real('-kT*entropy_xc',-el_temp*(energies%entropy_xc+energies%paw%entropy_paw))
1938 : call ftxcdoc%add_real('free_xc',energies%e_xc+energies%paw%epaw_xc-el_temp*(energies%entropy_xc+energies%paw%entropy_paw))
1939 : else
1940 : call ftxcdoc%add_real('internal_xc',energies%e_xc)
1941 : call ftxcdoc%add_real('-kT*entropy_xc',-el_temp*energies%entropy_xc)
1942 : call ftxcdoc%add_real('free_xc',energies%e_xc-el_temp*energies%entropy_xc)
1943 : end if
1944 : end if
1945 : end if
1946 :
1947 : ! Write components of total energies in Yaml format.
1948 5277 : call edoc%write_and_free(iout)
1949 5277 : if(optdc >= 1) call dc_edoc%write_and_free(iout)
1950 5277 : if (write_epaw_core) call pawcore_edoc%write_and_free(iout)
1951 5277 : if(write_entropy) call sdoc%write_and_free(iout)
1952 5277 : if(write_totalxc) call ftxcdoc%write_and_free(iout)
1953 :
1954 5277 : end subroutine prtene
1955 : !!***
1956 :
1957 : !!****f* ABINIT/get_dtsets_pspheads
1958 : !! NAME
1959 : !! get_dtsets_pspheads
1960 : !!
1961 : !! FUNCTION
1962 : !! Parse input file, get list of pseudos for files file and build list of datasets
1963 : !! pseudopotential headers, maxval of dimensions needed in outvars
1964 : !!
1965 : !! INPUTS
1966 : !! input_path: Input filename specifed on the command line. zero lenght if files file syntax is used.
1967 : !! Mainly used to check whether pseudos are defined in the input to avoid entering the files file
1968 : !! branch that prompts for pseudos.
1969 : !! path: Input Filename
1970 : !! comm: MPI communicator
1971 : !!
1972 : !! OUTPUT
1973 : !! lenstr= the length of the resulting string.
1974 : !! ndtset= the number of declared datasets.
1975 : !! string= contains on output the content of the file, ready for parsing.
1976 : !! dtsets(0:ndtset): List of datasets
1977 : !! dmatpuflag=flag controlling the use of an initial density matrix in PAW+U (max. value over datasets)
1978 : !! mx<ab_dimensions>=datatype storing the maximal dimensions.
1979 : !! pspheads(npsp)=<type pspheader_type>=all the important information from the
1980 : !! pseudopotential file headers, as well as the psp file names
1981 : !!
1982 : !! SOURCE
1983 :
1984 1442 : subroutine get_dtsets_pspheads(input_path, path, ndtset, lenstr, string, timopt, dtsets, pspheads, mx, dmatpuflag, comm)
1985 :
1986 : !Arguments ------------------------------------
1987 : !scalars
1988 : integer,intent(out) :: lenstr, ndtset
1989 : type(ab_dimensions),intent(out) :: mx
1990 : character(len=strlen), intent(out) :: string
1991 : character(len=*),intent(in) :: input_path, path
1992 : integer,intent(in) :: comm
1993 : integer,intent(out) :: timopt, dmatpuflag
1994 : !arrays
1995 : type(dataset_type),allocatable,intent(out) :: dtsets(:)
1996 : type(pspheader_type),allocatable,intent(out):: pspheads(:)
1997 :
1998 : !Local variables-------------------------------
1999 : !scalars
2000 : integer :: ipsp,ios, me, ndtset_alloc, nprocs
2001 : integer :: istatr,istatshft, papiopt, npsp, ii, idtset, msym, usepaw
2002 : character(len=fnlen) :: filpsp
2003 : character(len=500) :: msg
2004 : !arrays
2005 1442 : integer,allocatable :: mband_upper_(:)
2006 : real(dp) :: ecut_tmp(3,2,10),tsec(2)
2007 1442 : real(dp),allocatable :: zionpsp(:)
2008 1442 : character(len=fnlen), allocatable :: pspfilnam_(:), pseudo_paths(:)
2009 : !************************************************************************
2010 :
2011 1442 : me = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
2012 :
2013 : ! Read the file, stringify it and return the number of datasets.
2014 1442 : call parsefile(path, lenstr, ndtset, string, comm)
2015 :
2016 1442 : ndtset_alloc = ndtset; if (ndtset == 0) ndtset_alloc=1
2017 195875 : ABI_MALLOC(dtsets, (0:ndtset_alloc))
2018 :
2019 1442 : timopt = 1; if (xmpi_paral==1) timopt = 0
2020 :
2021 : ! Continue to analyze the input string, get upper dimensions, and allocate the remaining arrays.
2022 : call invars0(dtsets, istatr, istatshft, lenstr, msym, mx%natom, mx%nimage, mx%ntypat, &
2023 1442 : ndtset, ndtset_alloc, npsp, pseudo_paths, papiopt, timopt, string, comm)
2024 :
2025 : ! Enable PAPI timers
2026 1442 : call time_set_papiopt(papiopt)
2027 :
2028 9857 : dtsets(:)%timopt = timopt
2029 : dtsets(0)%timopt = 1
2030 1442 : if (xmpi_paral == 1) dtsets(0)%timopt = 0
2031 :
2032 1442 : call timab(timopt,5,tsec)
2033 :
2034 : ! Initialize pspheads, that contains the important information
2035 : ! from the pseudopotential headers, as well as the psp filename
2036 1442 : call timab(102,1,tsec)
2037 1442 : call timab(1021,3,tsec)
2038 :
2039 1442 : usepaw = 0
2040 6278 : ABI_MALLOC(pspheads, (npsp))
2041 1442 : if (npsp > 10) then
2042 0 : ABI_BUG('ecut_tmp is not well defined.')
2043 : end if
2044 131222 : ecut_tmp = -one
2045 :
2046 3394 : pspheads(:)%usewvl = dtsets(1)%usewvl
2047 :
2048 1442 : if (me == 0) then
2049 3492 : ABI_MALLOC(pspfilnam_, (npsp))
2050 :
2051 1164 : if (len_trim(pseudo_paths(1)) == 0) then
2052 : ! Enter Legacy `files file` mode --> Read the name of the psp file from files file.
2053 :
2054 : ! Catch possible mistake done by user (input without pseudos and `abinit t01.in` syntax)
2055 : ! else the code starts to prompt for pseudos and execution gets stuck
2056 2 : if (len_trim(input_path) /= 0) then
2057 0 : ABI_ERROR("`pseudos` variable must be specified in input when the code is invoked with the `abinit t01.in` syntax")
2058 : end if
2059 :
2060 : ! Finish to read the "file" file completely, as npsp is known,
2061 6 : do ipsp=1,npsp
2062 4 : write(std_out,'(/,a)' )' Please give name of formatted atomic psp file (and finish with a newline character)'
2063 4 : read (std_in, '(a)' , iostat=ios ) filpsp
2064 : ! It might be that a file name is missing
2065 4 : if (ios /= 0) then
2066 : write(msg, '(5a)' )&
2067 0 : 'There are not enough names of pseudopotentials provided in the files file.',ch10,&
2068 0 : 'Action: check first the variable ntypat (and/or npsp) in the input file;',ch10,&
2069 0 : 'if they are correct, complete your files file.'
2070 0 : ABI_ERROR(msg)
2071 : end if
2072 4 : pspfilnam_(ipsp) = trim(filpsp)
2073 6 : write(std_out,'(a,i0,2a)' )' For atom type ',ipsp,', psp file is ',trim(filpsp)
2074 : end do ! ipsp
2075 :
2076 : else
2077 : ! Get pseudopotential paths from input file.
2078 3892 : pspfilnam_ = pseudo_paths
2079 2730 : do ipsp=1,npsp
2080 2730 : write(std_out,'(a,i0,2a)' )' For atom type ',ipsp,', psp file is ',trim(pspfilnam_(ipsp))
2081 : end do
2082 : end if
2083 :
2084 : ! Now read the psp headers
2085 1164 : call inpspheads(pspfilnam_, npsp, pspheads, ecut_tmp)
2086 1164 : ABI_FREE(pspfilnam_)
2087 :
2088 2736 : if (minval(abs(pspheads(1:npsp)%pspcod - 7)) == 0) usepaw=1
2089 2736 : if (minval(abs(pspheads(1:npsp)%pspcod - 17)) == 0) usepaw=1
2090 : end if ! me == 0
2091 :
2092 1442 : ABI_FREE(pseudo_paths)
2093 :
2094 : ! Communicate pspheads to all processors
2095 1442 : call pspheads_comm(npsp, pspheads, usepaw)
2096 :
2097 : ! If (all) pspcod are 7 then this is a PAW calculation. Initialize (default) the value of ratsph
2098 9857 : do idtset=0,ndtset_alloc
2099 8415 : dtsets(idtset)%usepaw = usepaw
2100 9857 : if (usepaw == 0) then
2101 15046 : dtsets(idtset)%ratsph(:)=two
2102 : else
2103 : ! Note that the following coding assumes that npsp=ntypat for PAW, which is true as of now (XG20101024).
2104 : ! dtsets(idtset)%ratsph(1:npsp)=token%pspheads(1:npsp)%pawheader%rpaw
2105 3913 : do ipsp=1,npsp
2106 3913 : dtsets(idtset)%ratsph(ipsp) = pspheads(ipsp)%pawheader%rpaw
2107 : end do
2108 : endif
2109 : end do
2110 :
2111 : ! Take care of other dimensions, and part of the content of dtsets that is or might be needed early.
2112 4326 : ABI_MALLOC(zionpsp, (npsp))
2113 3394 : do ii=1,npsp
2114 3394 : zionpsp(ii) = pspheads(ii)%zionpsp
2115 : end do
2116 :
2117 4326 : ABI_MALLOC(mband_upper_, (0:ndtset_alloc))
2118 :
2119 : ! Get MAX dimension over datasets
2120 : call invars1m(dmatpuflag, dtsets, ab_out, lenstr, mband_upper_, mx,&
2121 1442 : msym, ndtset, ndtset_alloc, string, npsp, zionpsp, comm)
2122 :
2123 1428 : ABI_FREE(zionpsp)
2124 1428 : call timab(1021,2,tsec)
2125 1428 : call timab(1022,3,tsec)
2126 :
2127 : ! Provide defaults for the variables that have not yet been initialized.
2128 1428 : call indefo(dtsets, ndtset_alloc, nprocs)
2129 :
2130 1428 : call timab(1022,2,tsec)
2131 1428 : call timab(1023,3,tsec)
2132 :
2133 : ! Perform some global initialization, depending on the value of
2134 : ! pseudopotentials, parallelism variables, or macro input variables
2135 1428 : call macroin(dtsets, ecut_tmp, lenstr, ndtset_alloc, string)
2136 :
2137 : ! If all the pseudopotentials have the same pspxc, override the default value for dtsets 1 to ndtset
2138 3366 : if (minval(abs((pspheads(1:npsp)%pspxc - pspheads(1)%pspxc)))==0) then
2139 8387 : dtsets(1:ndtset_alloc)%ixc = pspheads(1)%pspxc
2140 : end if
2141 :
2142 : ! Call the main input routine.
2143 1428 : call invars2m(dtsets,ab_out,lenstr,mband_upper_,msym,ndtset,ndtset_alloc,npsp,pspheads,string, comm)
2144 :
2145 1428 : call macroin2(dtsets, ndtset_alloc)
2146 :
2147 1428 : mx%mband = dtsets(1)%mband
2148 8387 : do ii=1,ndtset_alloc
2149 8387 : mx%mband = max(dtsets(ii)%mband, mx%mband)
2150 : end do
2151 :
2152 1428 : call timab(1023,2,tsec)
2153 1428 : call timab(102,2,tsec)
2154 :
2155 1428 : ABI_FREE(mband_upper_)
2156 :
2157 2884 : end subroutine get_dtsets_pspheads
2158 : !!***
2159 :
2160 : !!****f* ABINIT/ebands_from_file
2161 : !! NAME
2162 : !! ebands_from_file
2163 : !!
2164 : !! FUNCTION
2165 : !! Build and ebands_t object from file. Supports Fortran and netcdf files
2166 : !! provided they have a Abinit header and obviously GS eigenvalues
2167 : !!
2168 : !! INPUTS
2169 : !! path: File name.
2170 : !! comm: MPI communicator.
2171 : !!
2172 : !! OUTPUT
2173 : !!
2174 : !! SOURCE
2175 :
2176 :
2177 0 : type(ebands_t) function ebands_from_file(path, comm) result(new)
2178 :
2179 : !Arguments ------------------------------------
2180 : !scalars
2181 : character(len=*),intent(in) :: path
2182 : integer,intent(in) :: comm
2183 :
2184 : !Local variables-------------------------------
2185 : !scalars
2186 : integer :: ncid, fform
2187 0 : type(hdr_type) :: hdr
2188 : !arrays
2189 0 : real(dp),pointer :: gs_eigen(:,:,:)
2190 :
2191 : ! *************************************************************************
2192 :
2193 : ! NOTE: Assume file with header. Must use wfk_read_eigenvalues to handle Fortran WFK
2194 0 : if (endswith(path, "_WFK") .or. endswith(path, "_WFK.nc")) then
2195 0 : call wfk_read_eigenvalues(path, gs_eigen, hdr, comm)
2196 0 : call new%from_hdr(hdr, maxval(hdr%nband), gs_eigen)
2197 :
2198 0 : else if (endswith(path, ".nc")) then
2199 0 : NCF_CHECK(nctk_open_read(ncid, path, comm))
2200 0 : call hdr%ncread(ncid, fform)
2201 0 : ABI_CHECK(fform /= 0, "fform == 0")
2202 0 : ABI_MALLOC(gs_eigen, (hdr%mband, hdr%nkpt, hdr%nsppol))
2203 0 : NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "eigenvalues"), gs_eigen))
2204 0 : call new%from_hdr(hdr, maxval(hdr%nband), gs_eigen)
2205 0 : NCF_CHECK(nf90_close(ncid))
2206 : else
2207 0 : ABI_ERROR(sjoin("Don't know how to construct crystal structure from: ", path, ch10, "Supported extensions: _WFK or .nc"))
2208 : end if
2209 :
2210 0 : ABI_FREE(gs_eigen)
2211 0 : call hdr%free()
2212 :
2213 0 : end function ebands_from_file
2214 : !!***
2215 :
2216 : !!****f* ABINIT/crystal_from_file
2217 : !! NAME
2218 : !! crystal_from_file
2219 : !!
2220 : !! FUNCTION
2221 : !! Build crystal_t object from netcdf file
2222 : !!
2223 : !! INPUTS
2224 : !!
2225 : !! OUTPUT
2226 : !!
2227 : !! SOURCE
2228 :
2229 0 : type(crystal_t) function crystal_from_file(path, comm) result(new)
2230 :
2231 : !Arguments ------------------------------------
2232 : !scalars
2233 : character(len=*),intent(in) :: path
2234 : integer,intent(in) :: comm
2235 :
2236 : !Local variables-------------------------------
2237 : !scalars
2238 : integer :: fform, ncid
2239 0 : type(hdr_type) :: hdr
2240 : ! *************************************************************************
2241 :
2242 0 : if (endswith(path, ".nc")) then
2243 0 : NCF_CHECK(nctk_open_read(ncid, path, comm))
2244 0 : call new%ncread(ncid)
2245 0 : NCF_CHECK(nf90_close(ncid))
2246 : else
2247 : ! Assume file with Abinit header
2248 : ! TODO: Should add routine to read crystal from structure without hdr
2249 0 : call hdr%from_fname(path, fform, comm)
2250 0 : ABI_CHECK(fform /= 0, "fform == 0")
2251 0 : new = hdr%get_crystal()
2252 0 : call hdr%free()
2253 : end if
2254 :
2255 0 : end function crystal_from_file
2256 : !!***
2257 :
2258 :
2259 : !!****f* ABINIT/get_gemm_nonlop_ompgpu_blocksize
2260 : !! NAME
2261 : !! get_gemm_nonlop_ompgpu_blocksize
2262 : !!
2263 : !! FUNCTION
2264 : !! Check GPU memory constraints for many ABINIT routines (lobpcg,chebfi,getghc)
2265 : !! and compute a size of GEMM nonlop block that is small enough to fit in GPU memory.
2266 : !! Print its estimation of memory consumption in output.
2267 : !!
2268 : !! INPUTS
2269 : !! gs_hamk : hamiltonian structure (used by getghc)
2270 : !! ndat : size of batching, usually matching bandpp or nblock_lobpcg
2271 : !! npw : number of planewaves
2272 : !! nband : number of bands
2273 : !! nspinor : number of spin-orbits
2274 : !! paral_kgb : 1 if KGB parallelism is enabled, 0 otherwise
2275 : !! optfor : 1 if forces computation is enabled, 0 otherwise
2276 : !! optstr : 1 if stress computation is enabled, 0 otherwise
2277 : !! wfoptalg : Which diago algorithm if used:
2278 : !! -1: none (GEMM nonlop isn't used for diago)
2279 : !! 111: CHEBFI2
2280 : !! 112: SLICE
2281 : !! 114: LOBPCG2
2282 : !! other: Only account for getghc
2283 : !! gpu_option : If GPU is enabled (expected to be ABI_GPU_OPENMP for now)
2284 : !! blocksize : if higher than 0, only print memory estimation and exit
2285 : !!
2286 : !! OUTPUT
2287 : !! nfft_blocks : Number of blocks fourwf computation will be divided into
2288 : !! blocksize : Size of MPI tasks blocks to be used in GEMM nonlop
2289 : !! nblocks : Number of MPI blocks to be used in GEMM nonlop
2290 : !!
2291 : !! SOURCE
2292 0 : subroutine get_gemm_nonlop_ompgpu_blocksize(ikpt,gs_hamk,ndat,nband,nspinor,nspden,paral_kgb,&
2293 : & npband,optfor,optstr,wfoptalg,gpu_option,use_distrib,&
2294 : & blocksize,nblocks,nfft_blocks,warn_on_fail,disable_output)
2295 :
2296 : integer,intent(in) :: ikpt,ndat,nband,nspinor,nspden,paral_kgb,npband,optfor,optstr,wfoptalg,gpu_option
2297 : logical,intent(in) :: use_distrib
2298 : logical,intent(in),optional :: warn_on_fail,disable_output
2299 : type(gs_hamiltonian_type),intent(in) :: gs_hamk
2300 : integer,intent(inout) :: blocksize,nfft_blocks
2301 : integer,intent(out) :: nblocks
2302 :
2303 : integer(kind=c_size_t) :: nonlop_smem,invovl_smem,getghc_wmem,invovl_wmem,nonlop_wmem,gs_ham_smem,updrho_wmem,prep_nonlop_wmem
2304 : integer(kind=c_size_t) :: sum_mem,sum_bandpp_mem,sum_other_mem,free_mem,localMem,fourwf_smem,fourwf_wmem,fourwf_mem,hegvd_mem
2305 : integer :: icplx,space,i,ndat_try,rank,nprocs,ndgxdt,blockdim,max_slices,npw,npw_fft,signs,nprojs,itypat
2306 : integer, target :: t_fft(3)
2307 : logical :: print_and_exit,l_warn_on_fail,l_disable_output,fixed_blocksize,fixed_fourwf_blocks
2308 : integer(kind=c_size_t) :: chebfiMem(2),lobpcgMem(2)
2309 : character(len=500) :: message
2310 :
2311 : ! *********************************************************************
2312 :
2313 0 : free_mem=256*1e9 ! Dummy value
2314 0 : l_warn_on_fail=.false.;if(present(warn_on_fail)) l_warn_on_fail=warn_on_fail
2315 0 : l_disable_output=.false.;if(present(disable_output)) l_disable_output=disable_output
2316 : #ifdef HAVE_GPU
2317 : if(gpu_option /= ABI_GPU_DISABLED) then
2318 : call gpu_get_max_mem(free_mem)
2319 : ! NOTE: Cutting 10% out to be safe
2320 : ! I computed this value using the memory allocation summary that
2321 : ! NVHPC provides after a GPU out-of-memory crash, on a run NVIDIA A100 with 80GB.
2322 : ! 8.5% is the amount of memory that wasn't reported allocated nor freed.
2323 : ! I add extra 1.5% to account for minor buffers eventually allocated.
2324 : ! This amount may either be hidden allocations for CUDA/cuBLAS/cuFFT/cuSOLVER,
2325 : ! or memory allocated outside ABINIT.
2326 : free_mem = 0.9 * free_mem
2327 : end if
2328 : #else
2329 : ABI_UNUSED(gpu_option)
2330 : #endif
2331 :
2332 0 : if(gpu_option /= ABI_GPU_OPENMP) then
2333 : ! No distribution is attempted outside of OpenMP GPU. User is already warned in chkinp
2334 0 : blocksize=1; nblocks=0; nfft_blocks=1
2335 0 : return
2336 : end if
2337 :
2338 0 : rank = xmpi_comm_rank(xmpi_world); nprocs = xmpi_comm_size(xmpi_world)
2339 0 : if ( gs_hamk%istwf_k == 2 ) then ! Real only
2340 0 : space = SPACE_CR
2341 0 : icplx = 2
2342 : else ! complex
2343 0 : space = SPACE_C
2344 0 : icplx = 1
2345 : end if
2346 :
2347 0 : npw=gs_hamk%npw_k
2348 0 : npw_fft=gs_hamk%npw_fft_k
2349 0 : ndat_try=ndat
2350 0 : blockdim=npband*ndat
2351 0 : ndgxdt=0
2352 0 : if(optfor>0) ndgxdt=ndgxdt+3
2353 0 : if(optstr>0) ndgxdt=ndgxdt+6
2354 0 : signs=2
2355 : !wfoptalg==-1 means we're in forstr
2356 0 : if(wfoptalg==-1) signs=1
2357 0 : t_fft(1) = gs_hamk%ngfft(3);
2358 0 : t_fft(2) = gs_hamk%ngfft(2);
2359 0 : t_fft(3) = gs_hamk%ngfft(1);
2360 0 : nprojs=0
2361 0 : do itypat=1,gs_hamk%ntypat
2362 0 : nprojs = nprojs + count(gs_hamk%indlmn(3,:,itypat)>0)*gs_hamk%nattyp(itypat)
2363 : end do
2364 :
2365 0 : nonlop_smem=0; invovl_smem=0; getghc_wmem=0; invovl_wmem=0; nonlop_wmem=0; gs_ham_smem=0
2366 0 : updrho_wmem=0; prep_nonlop_wmem=0; sum_mem=0; sum_bandpp_mem=0; sum_other_mem=0;
2367 0 : localMem=0; fourwf_smem=0; fourwf_wmem=0; fourwf_mem=0; hegvd_mem=0
2368 0 : chebfiMem(:)=0; lobpcgMem(:)=0
2369 :
2370 : !HEGVD work memory estimate.
2371 : ! Since *_bufferSize routines from (cu/hip)SOLVER require buffer
2372 : ! to be provided, I measeured the work size given by those routines
2373 : ! on many big cases and guess an approximate value.
2374 : ! hipSolver is eager than cuSolver, hence the extra multiplier
2375 :
2376 0 : if(wfoptalg==111 .or. wfoptalg==11) then
2377 0 : hegvd_mem = int(dp, c_size_t) * nband * nband * 3
2378 0 : else if(wfoptalg==114 .or. wfoptalg==14) then
2379 0 : hegvd_mem = int(dp, c_size_t) * (ndat*3) * (ndat*3) * 3
2380 : end if
2381 : #ifdef HAVE_GPU_CUDA
2382 : if(space == SPACE_C) hegvd_mem = hegvd_mem * 2
2383 : #endif
2384 : #ifdef HAVE_GPU_HIP
2385 : if(space == SPACE_C) hegvd_mem = hegvd_mem * 3
2386 : ! ROCm 7 memory usage was measured to be more or less
2387 : ! on par with CUDA but ROCm 6 was indeed ~9 times higher.
2388 : ! For now, we can't drop ROCm 6 so we keep this workaround.
2389 : if(gpu_get_lib_version_major() < 7) then
2390 : hegvd_mem = hegvd_mem * 9
2391 : end if
2392 : #endif
2393 :
2394 : if(wfoptalg>=0) then
2395 : #ifdef HAVE_GPU
2396 : call gpu_fft_get_estimate_work_size(3, c_loc(t_fft), FFT_Z2Z, ndat, fourwf_smem);
2397 : #endif
2398 : end if
2399 :
2400 0 : nonlop_smem = gemm_nonlop_ompgpu_static_mem(npw_fft, gs_hamk%indlmn, gs_hamk%nattyp, gs_hamk%ntypat, max(1,blocksize), ndgxdt, use_distrib)
2401 0 : getghc_wmem = getghc_ompgpu_work_mem(gs_hamk, ndat, max(nfft_blocks,1))
2402 : fourwf_wmem = int(2, c_size_t) * dp * gs_hamk%n4 * gs_hamk%n5 * gs_hamk%n6 &
2403 0 : & * (ndat/max(nfft_blocks,1) + modulo(ndat,max(nfft_blocks,1)))
2404 0 : fourwf_mem = fourwf_wmem+fourwf_smem
2405 :
2406 : nonlop_wmem = gemm_nonlop_ompgpu_work_mem(gs_hamk%istwf_k, ndat, ndgxdt, npw_fft,&
2407 0 : & gs_hamk%indlmn, gs_hamk%nattyp, gs_hamk%ntypat, gs_hamk%lmnmax, signs, wfoptalg)
2408 0 : gs_ham_smem = int(2,c_size_t)*npw_fft*size(gs_hamk%ffnl_k,dim=3)*size(gs_hamk%ffnl_k,dim=4) + int(3,c_size_t)*npw_fft
2409 0 : if(associated(gs_hamk%ph3d_k)) gs_ham_smem = gs_ham_smem + int(2,c_size_t) * npw_fft * gs_hamk%matblk
2410 0 : gs_ham_smem = gs_ham_smem*dp
2411 :
2412 : ! Mapped arrays used in mkrho or vtowfk
2413 0 : updrho_wmem = int(2,c_size_t)*npw_fft*ndat*nspinor ! cwavef
2414 0 : if(nspden==4) updrho_wmem = updrho_wmem + int(2,c_size_t)*npw_fft*ndat*2 ! cwavef_x + cwavef_y
2415 0 : updrho_wmem = updrho_wmem*dp
2416 :
2417 : ! Mapped arrays used in prep_nonlop (only paral_kgb==1)
2418 0 : prep_nonlop_wmem = 0
2419 0 : if(paral_kgb==1) prep_nonlop_wmem = int(2,c_size_t)*npw_fft*ndat*nspinor*3*dp ! cwavef_alltoall{1,2} + cwavef
2420 :
2421 0 : if(wfoptalg==111 .or. wfoptalg==112) then
2422 0 : chebfiMem = chebfi_memInfo(nband,icplx*npw*nspinor,space,paral_kgb,icplx*npw*nspinor,blockdim)
2423 0 : invovl_smem = invovl_ompgpu_static_mem(gs_hamk)
2424 0 : invovl_wmem = invovl_ompgpu_work_mem(gs_hamk, ndat)
2425 : end if
2426 0 : if(wfoptalg==114) then
2427 0 : lobpcgMem = lobpcg_memInfo(nband,icplx*npw*nspinor,space,paral_kgb,blockdim)
2428 : end if
2429 0 : localMem = (int(2,c_size_t)*npw*nspinor*nband+3*nband)*kind(1.d0) ! cg, eig, occ, resid in chebfiwf/lobpcgwf
2430 :
2431 : ! Check if arrays outside of GEMM nonlop projectors and ompgpu_fourwf fit in GPU memory
2432 0 : sum_other_mem = gs_ham_smem
2433 :
2434 0 : if(wfoptalg>=0) then
2435 0 : sum_other_mem = sum_other_mem+updrho_wmem+prep_nonlop_wmem
2436 : else
2437 0 : sum_other_mem = sum_other_mem+nonlop_wmem+prep_nonlop_wmem
2438 : end if
2439 :
2440 0 : if(wfoptalg==111) then
2441 0 : sum_other_mem = sum_other_mem + invovl_wmem+invovl_smem+chebfiMem(1)+chebfiMem(2)+localMem
2442 : end if
2443 :
2444 0 : if(wfoptalg==114) then
2445 0 : sum_other_mem = sum_other_mem + lobpcgMem(1)+lobpcgMem(2)+localMem
2446 : end if
2447 :
2448 0 : print_and_exit=.false.
2449 0 : fixed_blocksize=.false.
2450 0 : fixed_fourwf_blocks=.false.
2451 0 : nblocks=0
2452 0 : if(blocksize > 0 .and. nfft_blocks > 0) then
2453 0 : nblocks=max(1,nprocs/blocksize)
2454 0 : print_and_exit=.true.
2455 : else
2456 0 : if(blocksize > 0) then
2457 0 : nblocks=max(1,nprocs/blocksize)
2458 0 : fixed_blocksize=.true.
2459 : else
2460 0 : blocksize=1
2461 0 : if(.not. l_disable_output) write(std_out,*) "Setting GEMM nonlop block number...", new_line('A')
2462 : end if
2463 :
2464 0 : if(nfft_blocks > 0) then
2465 : fixed_fourwf_blocks=.true.
2466 : else
2467 0 : nfft_blocks=1
2468 0 : if(.not. l_disable_output) write(std_out,*) "Setting FFT blocks number...", new_line('A')
2469 : end if
2470 : end if
2471 :
2472 0 : max_slices=max(100,nprocs*2); if(sum_other_mem > free_mem) max_slices=1
2473 : ! How we try to optimize GPU memory consumption:
2474 : ! We work on two variables :
2475 : ! - blocksize : for slicing GEMM nonlop projectors arrays
2476 : ! - nfft_blocks : for slicing ompgpu_fourwf work buffer
2477 : ! At each iteration, we check which routine from GEMM nonlop or ompgpu_fourwf
2478 : ! have the higher memory requirement and increase related variable.
2479 : !
2480 : ! We arbitraly give at least 100 tries to improve GPU memory consumption before eventually
2481 : ! ruling out that use case is too big to run with available GPU memory and abort.
2482 : !
2483 : ! User may hard set slicing for both fourwf and GEMM nonlop, in which case the code will
2484 : ! warn the user about possible GPU memory overpassing instead of aborting.
2485 : !
2486 : ! However, if arrays from other parts of the code already have higher memory requirements,
2487 : ! we fail anyway and advise the user to increase nblock_lobpcg or run on more nodes.
2488 0 : do i=1,max_slices
2489 :
2490 : ! First iteration or user provided parameters to split fourwf and GEMM nonlop
2491 : ! Just measure
2492 0 : if(i==1 .or. print_and_exit) then
2493 0 : if(wfoptalg>=0) then
2494 : #ifdef HAVE_GPU
2495 : call gpu_fft_get_estimate_work_size(3, c_loc(t_fft), FFT_Z2Z, ndat/nfft_blocks, fourwf_smem);
2496 : #endif
2497 0 : getghc_wmem = getghc_ompgpu_work_mem(gs_hamk, ndat, nfft_blocks)
2498 : fourwf_wmem = int(2, c_size_t) * dp * gs_hamk%n4 * gs_hamk%n5 * gs_hamk%n6 &
2499 0 : & * (ndat/nfft_blocks + modulo(ndat,nfft_blocks))
2500 0 : fourwf_mem = fourwf_wmem + fourwf_smem
2501 : end if
2502 : nonlop_smem = gemm_nonlop_ompgpu_static_mem(npw_fft,gs_hamk%indlmn,gs_hamk%nattyp,&
2503 0 : & gs_hamk%ntypat,blocksize,ndgxdt,use_distrib)
2504 : else
2505 : ! Raise fourwf slicing if :
2506 : ! - GEMM nonlop block has been set by user
2507 : ! or
2508 : ! - fourwf memory requirements are higher
2509 : ! - fourwf slicing wasn't set by user
2510 : ! - fourwf is still sliceable
2511 : !
2512 : ! Raise GEMM nonlop blocks otherwise
2513 0 : if(fixed_blocksize .or. &
2514 : & (wfoptalg >= 0 &
2515 : & .and. nonlop_smem < fourwf_mem &
2516 : & .and. fourwf_mem >= getghc_wmem &
2517 : & .and. .not. fixed_fourwf_blocks &
2518 : & .and. nfft_blocks < ndat &
2519 : & .and. ndat_try > 1)) then
2520 : ! Fourwf work memory requirement is higher, split here
2521 0 : if(nfft_blocks == ndat) cycle ! Can't split more than ndat
2522 :
2523 : if(i>1 .and. .not. print_and_exit) then
2524 0 : do while(ndat_try <= (ndat/nfft_blocks + modulo(ndat,nfft_blocks)))
2525 0 : nfft_blocks=nfft_blocks+1
2526 : end do
2527 : ndat_try = (ndat/nfft_blocks + modulo(ndat,nfft_blocks))
2528 : end if
2529 : #ifdef HAVE_GPU
2530 : call gpu_fft_get_estimate_work_size(3, c_loc(t_fft), FFT_Z2Z, ndat/nfft_blocks, fourwf_smem);
2531 : #endif
2532 0 : getghc_wmem = getghc_ompgpu_work_mem(gs_hamk, ndat, nfft_blocks)
2533 : fourwf_wmem = int(2, c_size_t) * dp * gs_hamk%n4 * gs_hamk%n5 * gs_hamk%n6 &
2534 0 : & * (ndat/nfft_blocks + modulo(ndat,nfft_blocks))
2535 0 : fourwf_mem = fourwf_wmem + fourwf_smem
2536 : else
2537 : ! Gemm nonlop static memory requirement is higher, split here
2538 0 : if(i>1 .and. .not. print_and_exit) blocksize = blocksize + 1
2539 0 : if(modulo(nprocs,blocksize)/=0 .and. use_distrib) cycle
2540 0 : if(nprocs < blocksize .and. use_distrib) cycle
2541 : !FIXME : Skipping uneven blocksize <=5 if using MPI distrib, as the amount of GPU per node is even usually
2542 : !For example, with 3 nodes of 4 GPU, we don't want to have a blocksize of 3 as
2543 : !it would generate 4 comms-block, with 2 inter-node comms.
2544 : !While using a blocksize of 4 would generate 3 comms, one for each node, leading to less MPI comms
2545 0 : if(i>1 .and. modulo(blocksize,2)/=0 .and. use_distrib .and. .not. print_and_exit) cycle
2546 0 : if(i>1) nblocks=nprocs/blocksize
2547 :
2548 : nonlop_smem = gemm_nonlop_ompgpu_static_mem(npw_fft,gs_hamk%indlmn,gs_hamk%nattyp,&
2549 0 : & gs_hamk%ntypat,blocksize,ndgxdt,use_distrib)
2550 : end if
2551 : end if
2552 :
2553 : ! Bandpp~ndat sized buffer memory requirements are higher, split there
2554 0 : sum_mem = nonlop_smem + gs_ham_smem
2555 0 : sum_bandpp_mem = getghc_wmem
2556 :
2557 0 : if(wfoptalg>=0) then
2558 0 : sum_mem = sum_mem+getghc_wmem+updrho_wmem+prep_nonlop_wmem+fourwf_smem+hegvd_mem
2559 : else
2560 0 : sum_mem = sum_mem+nonlop_wmem+prep_nonlop_wmem
2561 : end if
2562 :
2563 0 : if(wfoptalg==111 .or. wfoptalg==112) then
2564 0 : sum_mem = sum_mem + invovl_smem+invovl_wmem+chebfiMem(1)+chebfiMem(2)+localMem
2565 0 : sum_bandpp_mem = sum_bandpp_mem + invovl_wmem
2566 : end if
2567 :
2568 0 : if(wfoptalg==114) then
2569 0 : sum_mem = sum_mem + lobpcgMem(1)+lobpcgMem(2)+localMem
2570 : end if
2571 :
2572 0 : if(sum_mem < free_mem .or. print_and_exit) exit
2573 :
2574 : end do
2575 :
2576 : ! Corner case : not enough GPU memory in forstrnps for forces and stress computation.
2577 : ! By default, forces and stress are computed in one gemm_nonlop call using choice==23
2578 : ! This translates to have various arrays sized by ndgxdt == 9 (6 for stress, 3 for forces)
2579 : ! To try circumventing the lack of GPU memory in that case, we may compute stress and forces
2580 : ! separately so arrays will be sized after ndgxdt=6 at most instead.
2581 0 : if(sum_mem > free_mem .and. optfor > 0 .and. optstr > 0 .and. wfoptalg < 0) then
2582 0 : ndgxdt = 6 ! number of derivatives for stress
2583 : nonlop_wmem = gemm_nonlop_ompgpu_work_mem(gs_hamk%istwf_k, ndat, ndgxdt, npw_fft,&
2584 0 : & gs_hamk%indlmn, gs_hamk%nattyp, gs_hamk%ntypat, gs_hamk%lmnmax, signs, wfoptalg)
2585 0 : blocksize=1
2586 : ! Same loop as above, simplified to forstrnps use case
2587 0 : do i=1,nprocs
2588 : ! Gemm nonlop static memory requirement is higher, split here
2589 0 : if(i>1 .and. .not. print_and_exit) blocksize = blocksize + 1
2590 0 : if(modulo(nprocs,blocksize)/=0 .and. use_distrib) cycle
2591 : !FIXME : Skipping uneven blocksize <=5 if using MPI distrib, as the amount of GPU per node is even usually
2592 : !For example, with 3 nodes of 4 GPU, we don't want to have a blocksize of 3 as
2593 : !it would generate 4 comms-block, with 2 inter-node comms.
2594 : !While using a blocksize of 4 would generate 3 comms, one for each node, leading to less MPI comms
2595 0 : if(i>1 .and. modulo(blocksize,2)/=0 .and. use_distrib .and. .not. print_and_exit) cycle
2596 0 : if(i>1) nblocks=nprocs/blocksize
2597 :
2598 : nonlop_smem = gemm_nonlop_ompgpu_static_mem(npw_fft,gs_hamk%indlmn,gs_hamk%nattyp,gs_hamk%ntypat,&
2599 0 : & blocksize,ndgxdt, use_distrib)
2600 0 : sum_mem = nonlop_smem + gs_ham_smem + nonlop_wmem + prep_nonlop_wmem
2601 :
2602 0 : if(sum_mem < free_mem) then
2603 0 : gemm_nonlop_split_choice23 = .true.
2604 0 : exit
2605 : end if
2606 : end do
2607 : end if
2608 :
2609 : ! Quickfix : sometimes, we may run out of GPU memory when computing forces/stresses because of fragmentation.
2610 : ! We try to reduce the risk by forcing even more blocking:
2611 0 : if((wfoptalg < 0 .and. (optfor > 0 .or. optstr > 0)) .and. sum_mem > 0.95*free_mem) then
2612 0 : if(blocksize > 5) then
2613 0 : if(.not. gemm_nonlop_split_choice23) then
2614 0 : gemm_nonlop_split_choice23 = .true.
2615 0 : ndgxdt=6
2616 : else
2617 0 : blocksize=blocksize*1.5
2618 0 : blocksize=min(nprojs,blocksize)
2619 : end if
2620 : else
2621 0 : blocksize=blocksize*1.5
2622 : end if
2623 :
2624 : nonlop_smem = gemm_nonlop_ompgpu_static_mem(npw_fft,gs_hamk%indlmn,gs_hamk%nattyp,gs_hamk%ntypat,&
2625 0 : & blocksize,ndgxdt,use_distrib)
2626 0 : sum_mem = nonlop_smem + gs_ham_smem + nonlop_wmem + prep_nonlop_wmem
2627 : end if
2628 :
2629 0 : if(.not. l_disable_output .or. sum_other_mem > free_mem .or. sum_mem > free_mem) then
2630 0 : write(std_out,'(A,I3,A)') "GPU memory consumption estimate per MPI task for K-point ",ikpt,":"
2631 0 : if(blocksize>1) then
2632 0 : if(use_distrib) then
2633 0 : write(std_out,'(A,I3,A,I3,A)') "MPI distribution of GEMM nonlop projectors using ",&
2634 0 : & nblocks, " blocks of ", blocksize, " MPI tasks."
2635 : else
2636 0 : write(std_out,'(A,I3,A)') "Local slicing of GEMM nonlop projectors using ",&
2637 0 : & blocksize, " blocks."
2638 : end if
2639 : end if
2640 0 : if(nfft_blocks>1 .and. wfoptalg>=0) then
2641 0 : write(std_out,'(A,I3,A)') "Local slicing of FFT work array using ",&
2642 0 : & nfft_blocks, " blocks."
2643 : end if
2644 0 : write(std_out,'(A,F10.3,1x,A)') " Considered available memory : ", real(free_mem)/(1024*1024), "MiB"
2645 0 : write(std_out,'(A)')
2646 0 : write(std_out,'(A)') "| Buffers governed by blocking/slicing |"
2647 0 : write(std_out,'(A)') "|:--------------------------|---------:|-------------:|---------------:|"
2648 0 : write(std_out,'(A,I4,A,F10.2,1x,A)') "| gemm_nonlop_projectors | ", blocksize, " blk | npw,*natom* | ", real(nonlop_smem,dp)/(1024*1024), "MiB |"
2649 0 : if(wfoptalg>=0) then
2650 0 : write(std_out,'(A,I4,A,F10.2,1x,A)') "| fourwf (fofr work array) | ", nfft_blocks, " blk | npw,*bandpp* | ", real(fourwf_wmem,dp)/(1024*1024), "MiB |"
2651 0 : write(std_out,'(A,F10.2,1x,A)') "| xFFT~internal buffers | NA | NA | ", real(fourwf_smem,dp)/(1024*1024), "MiB |"
2652 : end if
2653 :
2654 0 : if(sum_other_mem > free_mem) then
2655 0 : write(std_out,'(A)')
2656 0 : write(std_out,'(A)') "/!\ No slicing attempted as other arrays are too big to fit"
2657 0 : write(std_out,'(A)')
2658 : end if
2659 :
2660 0 : write(std_out,'(A)')
2661 0 : write(std_out,'(A)') "| Static buffers, computed once and permanently on card |"
2662 0 : write(std_out,'(A)') "|:-------------------------|--------------:|----------------:|"
2663 : ! CHEBFI2 or SLICE
2664 0 : if(wfoptalg==111 .or. wfoptalg==112) then
2665 0 : write(std_out,'(A,F10.2,1x,A)') "| invovl (mkinvovl) | natom | ", real(invovl_smem,dp)/(1024*1024), "MiB |"
2666 0 : write(std_out,'(A,F10.2,1x,A)') "| chebfi2 | npw | ", real(chebfiMem(1))/(1024*1024), "MiB |"
2667 : end if
2668 :
2669 : ! LOBPCG2
2670 0 : if(wfoptalg==114) then
2671 0 : write(std_out,'(A,F10.2,1x,A)') "| lobpcg2 | npw | ", real(lobpcgMem(1))/(1024*1024), "MiB |"
2672 : end if
2673 :
2674 0 : write(std_out,'(A,F10.2,1x,A)') "| hamiltonian arrays | npw | ", real(gs_ham_smem)/(1024*1024), "MiB |"
2675 :
2676 0 : write(std_out,'(A)')
2677 0 : write(std_out,'(A)') "| Work buffers (mostly sized after bandpp or nblock_lobpcg) |"
2678 0 : write(std_out,'(A)') "|:-------------------------|--------------:|----------------:|"
2679 : ! getghc (any diago algorithm)
2680 0 : if(wfoptalg>=0) then
2681 0 : if(getghc_wmem /= fourwf_wmem) then
2682 0 : write(std_out,'(A,F10.2,1x,A)') "| gemm_nonlop | bandpp | ", real(getghc_wmem,dp)/(1024*1024), "MiB |"
2683 : end if
2684 0 : write(std_out,'(A,F10.2,1x,A)') "| mkrho~vtowfk_extra | npw,bandpp | ", real(updrho_wmem,dp)/(1024*1024), "MiB |"
2685 0 : write(std_out,'(A,F10.2,1x,A)') "| hegvd | bandpp | ", real(hegvd_mem,dp)/(1024*1024), "MiB |"
2686 : else
2687 0 : write(std_out,'(A,F10.2,1x,A)') "| gemm_nonlop | natom,bandpp | ", real(nonlop_wmem,dp)/(1024*1024), "MiB |"
2688 : end if
2689 0 : if(paral_kgb==1) then
2690 0 : write(std_out,'(A,F10.2,1x,A)') "| prep_nonlop | npw,bandpp | ", real(prep_nonlop_wmem,dp)/(1024*1024), "MiB |"
2691 : end if
2692 :
2693 : ! CHEBFI2 or SLICE
2694 0 : if(wfoptalg==111 .or. wfoptalg==112) then
2695 0 : write(std_out,'(A,F10.2,1x,A)') "| invovl | natom,bandpp | ", real(invovl_wmem,dp)/(1024*1024), "MiB |"
2696 0 : write(std_out,'(A,F10.2,1x,A)') "| chebfi2 (RR buffers) | nband | ", real(chebfiMem(2))/(1024*1024), "MiB |"
2697 0 : write(std_out,'(A,F10.2,1x,A)') "| chebfiwf (cg,resid,eig) | npw,nband | ", real(localMem)/(1024*1024), "MiB |"
2698 : end if
2699 :
2700 : ! LOBPCG2
2701 0 : if(wfoptalg==114) then
2702 0 : write(std_out,'(A,F10.2,1x,A)') "| lobpcg2 (RR buffers) | bandpp | ", real(lobpcgMem(2))/(1024*1024), "MiB |"
2703 0 : write(std_out,'(A,F10.2,1x,A)') "| lobpcgwf (cg,resid,eig) | npw,nband | ", real(localMem)/(1024*1024), "MiB |"
2704 : end if
2705 :
2706 0 : write(std_out,'(A)')
2707 0 : if(sum_other_mem > free_mem) then
2708 0 : write(std_out,'(A,F10.2,1x,A)') "Sum : ", real(sum_other_mem)/(1024*1024), "MiB"
2709 : else
2710 0 : write(std_out,'(A,F10.2,1x,A)') "Sum : ", real(sum_mem)/(1024*1024), "MiB"
2711 : end if
2712 0 : write(std_out,'(A)')
2713 0 : flush(std_out)
2714 :
2715 : end if
2716 :
2717 0 : if(rank==0) then
2718 0 : if(sum_other_mem > free_mem) then
2719 : write(message,'(3a)') &
2720 0 : & ' Your case is too big to fit in GPU memory regardless of possible array optimizations in fourwf and GEMM nonlop.',ch10,&
2721 0 : & ' Action : run on more nodes and/or increase nblock_lobpcg if using LOBPCG.'
2722 0 : ABI_ERROR(message)
2723 : end if
2724 0 : if(sum_mem > free_mem) then
2725 0 : if(l_warn_on_fail) then
2726 0 : ABI_WARNING("It seems the test case you're trying to run is too big to run with given GPU resources !")
2727 : else
2728 0 : ABI_ERROR("It seems the test case you're trying to run is too big to run with given GPU resources !")
2729 : end if
2730 : end if
2731 : end if
2732 : !call xmpi_barrier(xmpi_world)
2733 :
2734 : end subroutine get_gemm_nonlop_ompgpu_blocksize
2735 : !!***
2736 :
2737 : end module m_common
2738 : !!***
|