Line data Source code
1 : !!****m* ABINIT/m_paw_mkaewf
2 : !! NAME
3 : !! m_paw_mkaewf
4 : !!
5 : !! FUNCTION
6 : !! Construct complete AE wave functions on the fine FFT grid adding onsite PAW corrections.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2008-2026 ABINIT group (MG)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : module m_paw_mkaewf
23 :
24 : use defs_basis
25 : use defs_wvltypes
26 : use m_abicore
27 : use m_xmpi
28 : use m_hide_blas
29 : use m_splines
30 : use m_errors
31 : use m_nctk
32 : use m_hdr
33 : use m_dtset
34 : use m_dtfil
35 : use netcdf
36 :
37 : use defs_abitypes, only : MPI_type
38 : use m_io_tools, only : flush_unit
39 : use m_numeric_tools, only : wrap2_zero_one
40 : use m_fftcore, only : sphereboundary
41 : use m_geometry, only : xcart2xred
42 : use m_crystal, only : crystal_t
43 : use m_ebands, only : ebands_t
44 : use m_pawrad, only : pawrad_type
45 : use m_pawtab, only : pawtab_type, pawtab_get_lsize
46 : use m_pawfgrtab, only : pawfgrtab_type, pawfgrtab_init, pawfgrtab_free, pawfgrtab_print
47 : use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_get, pawcprj_free
48 : use m_paw_pwaves_lmn, only : paw_pwaves_lmn_t, paw_pwaves_lmn_init, paw_pwaves_lmn_free
49 : use m_paral_atom, only : get_my_atmtab, free_my_atmtab
50 : use m_paw_nhat, only : nhatgrid
51 : use m_mpinfo, only : proc_distrb_cycle
52 : use m_fft, only : fourwf
53 :
54 : implicit none
55 :
56 : private
57 :
58 : public :: pawmkaewf
59 :
60 : CONTAINS !========================================================================================
61 : !!***
62 :
63 : !!****f* m_paw_mkaewf/pawmkaewf
64 : !! NAME
65 : !! pawmkaewf
66 : !!
67 : !! FUNCTION
68 : !! Construct complete AE wave functions on the fine FFT grid adding onsite PAW corrections.
69 : !!
70 : !! INPUTS
71 : !! crystal<crystal_t>=Crystalline structure
72 : !! ebands<ebands_t>=Electronic energies
73 : !! dimcprj(natom)=array of dimensions of array cprj (not ordered)
74 : !! mband=maximum number of bands
75 : !! mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
76 : !! mcprj=size of projected wave-functions array (cprj) =nspinor*mband*mkmem*nsppol
77 : !! mkmem=number of k points treated by this node.
78 : !! mpi_atmtab(:)=--optional-- indexes of the atoms treated by current proc
79 : !! [comm_atom]= MPI communicator over atoms
80 : !! mpw=maximum dimensioned size of npw.
81 : !! my_natom=number of atoms treated by current processor
82 : !! natom=number of atoms in cell
83 : !! ntypat=number of types of atoms in the cell
84 : !! nkpt=Total number of k-points
85 : !! nsppol=1 for unpolarized, 2 for spin-polarized
86 : !! unks=unit number for G vectors.
87 : !! nband(nkpt*nsppol)=Number of bands for each k-point and spin.
88 : !! istwfk(nkpt)=Storage mode at each k-point.
89 : !! Pawfgrtab(natom) <type(pawfgrtab_type)> : data about the fine grid around each atom
90 : !! Pawrad(ntypat) <type(pawrad_type)> : radial mesh data for each type of atom
91 : !! Pawtab(ntypat) <type(pawtab_type)> : PAW functions around each type of atom
92 : !! Dtfil <type(datafiles_type)>=variables related to files
93 : !! cg(2,mcg)=planewave coefficients of wavefunctions.
94 : !! Cprj(natom,nspinor*mband*mkmem*nsppol)=<p_lmn|Cnk> coefficients for each WF |Cnk>
95 : !! and each |p_lmn> non-local projector
96 : !! npwarr(nkpt)=Number of plane waves at each k-point
97 : !! ngfftf(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
98 : !! Note that ngfftf refers to the fine mesh.
99 : !! kg(3,mpw*mkmem)=reduced planewave coordinates
100 : !! Hdr<hdr_type>=the header of wf, den and pot files
101 : !! kpt(3,nkpt)=reduced coordinates of k points.
102 : !!
103 : !! OUTPUT
104 : !! ierr=Status error
105 : !! Main output is written on file (ETSF_IO file format).
106 : !!
107 : !! NOTES
108 : !! In PAW calculations, the pseudized wavefunction us represented
109 : !! on a relatively small plane wave basis set and is not normalized
110 : !! as it does not include the on-site PAW contributions which is described
111 : !! in terms of real spherical harmonics and radial functions.
112 : !! For post-processing and proper visualization, it is necessary
113 : !! to use the full electronic wave function, which is what this subroutine constructs.
114 : !! Specifically, it computes the pseudo part by doing an FFT from G- to r-space
115 : !! using the dense mesh defined by pawecutdg. The on-site PAW terms are also
116 : !! computed in real space inside each sphere and added to the pseudo part.
117 : !! Notice that this formula is expressed on the fine grid, and requires
118 : !! interpolating the PAW radial functions onto this grid, as well as calling
119 : !! initylmr in order to get the angular functions on the grid points.
120 : !!
121 : !! SOURCE
122 :
123 2 : subroutine pawmkaewf(Dtset,crystal,ebands,my_natom,mpw,mband,mcg,mcprj,nkpt,mkmem,nsppol,nband,&
124 2 : & istwfk,npwarr,kpt,ngfftf,kg,dimcprj,Pawfgrtab,Pawrad,Pawtab,&
125 1 : & Hdr,Dtfil,cg,Cprj,MPI_enreg,ierr,pseudo_norms,set_k,set_band , &
126 1 : & mpi_atmtab,comm_atom) ! Optional arguments
127 :
128 : !Arguments ------------------------------------
129 : !scalars
130 : integer,intent(in) :: my_natom,mband,mcg,mcprj,mkmem,mpw,nsppol,nkpt
131 : integer,intent(in),optional :: comm_atom,set_k,set_band
132 : integer,intent(out) :: ierr
133 : type(Datafiles_type),intent(in) :: Dtfil
134 : type(MPI_type),intent(in) :: MPI_enreg
135 : type(hdr_type),intent(inout) :: Hdr
136 : type(dataset_type),intent(in) :: Dtset
137 : type(crystal_t),intent(in) :: crystal
138 : type(ebands_t),intent(in) :: ebands
139 : !arrays
140 : integer,intent(in) :: nband(nkpt*nsppol),istwfk(nkpt),npwarr(nkpt),dimcprj(crystal%natom)
141 : integer,intent(in) :: ngfftf(18),kg(3,mpw*mkmem)
142 : integer,optional,target,intent(in) :: mpi_atmtab(:)
143 : real(dp),intent(in) :: cg(2,mcg)
144 : real(dp),intent(in) :: kpt(3,nkpt)
145 : real(dp),optional,intent(out) :: pseudo_norms(nsppol,nkpt,mband)
146 : type(pawfgrtab_type),intent(in) :: Pawfgrtab(my_natom)
147 : type(pawrad_type),intent(in) :: Pawrad(crystal%ntypat)
148 : type(pawtab_type),intent(in) :: Pawtab(crystal%ntypat)
149 : type(pawcprj_type),intent(in) :: Cprj(crystal%natom,mcprj)
150 :
151 : !Local variables-------------------------------
152 : !scalars
153 : integer,parameter :: tim_fourwf0=0,tim_rwwf0=0,master=0
154 : integer :: bdtot_index,iband,icg,mgfftf,paral_kgb
155 : integer :: iatom,iatom_tot,ifgd,ifftsph,ifft,itypat,ispinor,ipw,ndat,ii,i1,i2,i3
156 : integer :: jl,jm,jlmn,natom
157 : integer :: max_nfgd,nfgd,ln_size,lmn_size,my_comm_atom,option
158 : integer :: iorder_cprj,comm_cell,me_kpt,ibsp,ibg,isppol,ikpt,nband_k,cplex
159 : integer :: n1,n2,n3,n4,n5,n6,ikg,npwout,istwf_k,npw_k
160 : integer :: nfftot,nprocs,tmp_unt
161 : integer :: optcut,optgr0,optgr1,optgr2,optrad,start_band,start_kpt,stop_kpt,stop_band
162 : logical :: my_atmtab_allocated,paral_atom
163 : real(dp),parameter :: weight1=one
164 : real(dp) :: phj,tphj,re_p,im_p,norm,norm_rerr,max_rerr,imur,reur,arg
165 : character(len=500) :: msg
166 : character(len=nctk_slen) :: shape_str
167 : !arrays
168 1 : integer,allocatable :: l_size_atm(:)
169 1 : integer, pointer :: my_atmtab(:)
170 1 : integer,allocatable :: gbound(:,:),kg_k(:,:)
171 : real(dp) :: red(3),shift(3),rfft(3),kpoint(3),cp_fact(2)
172 1 : real(dp),allocatable :: r0shift(:,:,:),phk_atm(:,:,:),paw_compl(:)
173 1 : real(dp),allocatable :: buf_tmp(:,:,:),fofgin(:,:),fofgin_down(:,:),fofgout(:,:)
174 2 : real(dp),allocatable :: denpot(:,:,:),fofr(:,:,:,:),fofr_down(:,:,:,:),phkr(:,:)
175 1 : real(dp),allocatable :: ur_ae(:,:), ur_pw(:,:),ur_ae_onsite(:,:),ur_ps_onsite(:,:)
176 2 : real(dp),allocatable :: ur_mask(:),dummy_1d(:),rsph_red(:,:),rsph_cart(:,:)
177 1 : type(pawcprj_type),allocatable :: Cprj_k(:,:)
178 14 : type(pawfgrtab_type) :: local_pawfgrtab(my_natom)
179 1 : type(paw_pwaves_lmn_t),allocatable :: Paw_onsite(:)
180 : integer :: fform,ncerr,ncid,ae_ncid,pw_ncid,aeons_ncid,psons_ncid
181 : character(len=fnlen) :: fname
182 : ! ************************************************************************
183 :
184 : DBG_ENTER("COLL")
185 :
186 : !Init parallelism
187 1 : comm_cell = MPI_enreg%comm_cell; nprocs = xmpi_comm_size(comm_cell)
188 1 : me_kpt = MPI_enreg%me_kpt; paral_kgb=mpi_enreg%paral_kgb
189 :
190 : !Compatibility tests
191 1 : ABI_CHECK(mkmem/=0, "mkmem==0 not supported anymore!")
192 1 : ABI_CHECK(MPI_enreg%paral_kgb == 0, "paral_kgb/=0 not coded")
193 1 : ABI_CHECK(SIZE(dimcprj)>0, "dimcprj should be allocated")
194 1 : ABI_CHECK(mpi_enreg%paral_spinor==0, "parallelisation over spinors not implemented")
195 1 : ABI_CHECK(nprocs==1, "k spin parallelism not yet active")
196 1 : ABI_CHECK(dtset%nspinor==1, "nspinor == 2 is buggy")
197 :
198 1 : natom = crystal%natom
199 :
200 : !Set up parallelism over atoms
201 1 : paral_atom=(present(comm_atom).and.(my_natom/=natom))
202 1 : nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab
203 1 : my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom
204 1 : call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,my_natom_ref=my_natom)
205 :
206 : !If collection of pseudo norms is enabled, make sure the array is initialised
207 19 : if (present(pseudo_norms)) pseudo_norms = zero
208 :
209 : !use a local copy of pawfgrtab to make sure we use the correction in the paw spheres
210 : !the usual pawfgrtab uses r_shape which may not be the same as r_paw
211 1 : if (my_natom>0) then
212 1 : if (paral_atom) then
213 0 : call pawtab_get_lsize(pawtab,l_size_atm,my_natom,Dtset%typat,mpi_atmtab=my_atmtab)
214 : call pawfgrtab_init(local_pawfgrtab,Pawfgrtab(1)%cplex,l_size_atm,Dtset%nspden,Dtset%typat,&
215 0 : & mpi_atmtab=my_atmtab,comm_atom=my_comm_atom)
216 : else
217 1 : call pawtab_get_lsize(pawtab,l_size_atm,my_natom,Dtset%typat)
218 1 : call pawfgrtab_init(local_pawfgrtab,Pawfgrtab(1)%cplex,l_size_atm,Dtset%nspden,Dtset%typat)
219 : end if
220 1 : ABI_FREE(l_size_atm)
221 : end if
222 1 : optcut = 1 ! use rpaw to construct local_pawfgrtab
223 1 : optgr0 = 0; optgr1 = 0; optgr2 = 0 ! dont need gY terms locally
224 1 : optrad = 1 ! do store r-R
225 :
226 1 : if (paral_atom) then
227 : call nhatgrid(crystal%atindx1,crystal%gmet,my_natom,natom,crystal%nattyp,ngfftf,crystal%ntypat,&
228 : & optcut,optgr0,optgr1,optgr2,optrad,local_pawfgrtab,pawtab,crystal%rprimd,Dtset%typat,crystal%ucvol,Hdr%xred,&
229 0 : & comm_atom=my_comm_atom,mpi_atmtab=my_atmtab)
230 : else
231 : call nhatgrid(crystal%atindx1,crystal%gmet,my_natom,natom,crystal%nattyp,ngfftf,crystal%ntypat,&
232 1 : & optcut,optgr0,optgr1,optgr2,optrad,local_pawfgrtab,pawtab,crystal%rprimd,Dtset%typat,crystal%ucvol,Hdr%xred)
233 : end if
234 : !now local_pawfgrtab is ready to use
235 :
236 2 : max_nfgd=MAXVAL(local_pawfgrtab(:)%nfgd) ! MAX no. of points in the fine grid for this PAW sphere
237 4 : ABI_MALLOC(r0shift,(3,max_nfgd,my_natom))
238 4 : ABI_MALLOC(phk_atm,(2,max_nfgd,my_natom))
239 :
240 2 : do iatom=1,my_natom
241 1 : iatom_tot=iatom;if (paral_atom) iatom_tot=my_atmtab(iatom)
242 :
243 1 : nfgd=local_pawfgrtab(iatom)%nfgd ! no. of points in the fine grid for this PAW sphere
244 3 : ABI_MALLOC(rsph_red,(3,nfgd))
245 2 : ABI_MALLOC(rsph_cart,(3,nfgd))
246 1430 : do ifgd=1,nfgd
247 5717 : rsph_cart(:,ifgd) = local_pawfgrtab(iatom)%rfgd(:,ifgd) + crystal%xcart(:,iatom_tot)
248 : end do
249 1 : call xcart2xred(nfgd,crystal%rprimd,rsph_cart,rsph_red) ! we work in reduced coordinates.
250 1430 : do ifgd=1,nfgd
251 1429 : call wrap2_zero_one(rsph_red(1,ifgd),red(1),shift(1)) ! num = red + shift
252 1429 : call wrap2_zero_one(rsph_red(2,ifgd),red(2),shift(2))
253 1429 : call wrap2_zero_one(rsph_red(3,ifgd),red(3),shift(3))
254 5717 : r0shift(:,ifgd,iatom) = shift
255 : !if (ANY( ABS(shift) > tol12)) then
256 : ! ABI_WARNING("rmR_red is outside the first unit cell.")
257 : ! write(std_out,*)rsph_red(:,ifgd),shift
258 : !end if
259 : end do
260 1 : ABI_FREE(rsph_red)
261 2 : ABI_FREE(rsph_cart)
262 : end do
263 :
264 1 : if (.not.paral_atom .and. my_natom>0) then
265 : call pawfgrtab_print(local_pawfgrtab,natom=natom,unit=std_out,&
266 1 : & prtvol=Dtset%prtvol,mode_paral="COLL")
267 : end if
268 :
269 1 : ierr=0
270 :
271 : !FIXME check ordering in cprj and Eventually in external file
272 : !why is iorder_cprj not stored in the file for crosschecking purpose?
273 : !Here Im assuming cprj are not ordered!
274 1 : iorder_cprj=0
275 :
276 : !n4,n5,n6 are FFT dimensions, modified to avoid cache trashing
277 1 : n1=ngfftf(1); n2=ngfftf(2); n3=ngfftf(3)
278 1 : n4=ngfftf(4); n5=ngfftf(5); n6=ngfftf(6)
279 4 : nfftot=PRODUCT(ngfftf(1:3))
280 4 : mgfftf=MAXVAL(ngfftf(1:3))
281 :
282 3 : ABI_MALLOC(phkr,(2,nfftot))
283 4 : ABI_MALLOC(gbound,(2*mgfftf+8,2))
284 :
285 : !=== Initialize ETSF_IO files ===
286 : ! FIXME: nspinor == 2 is buggy
287 1 : if(dtset%pawprtwf==1) then
288 1 : fname = trim(dtfil%filnam_ds(4))//'_PAWAVES.nc'
289 1 : write(msg,'(2a)')' Opening file for AE PAW wave functions: ',trim(fname)
290 3 : call wrtout([std_out, ab_out], msg, 'PERS')
291 :
292 1 : if (xmpi_comm_rank(comm_cell) == master) then
293 1 : NCF_CHECK(nctk_open_create(ncid, fname, xmpi_comm_self))
294 :
295 1 : fform = 602
296 1 : NCF_CHECK(hdr%ncwrite(ncid, fform, nc_define=.True.))
297 :
298 : ! Define wavefunctions in real space on the dense FFT mesh
299 : ! Fortran layout:
300 : !real_space_wavefunctions: double 8d array with shape:
301 : ! [real_or_complex_wavefunctions]
302 : ! [number_of_grid_points_vector1][number_of_grid_points_vector2][number_of_grid_points_vector3]
303 : ! [number_of_spinor_components]
304 : ! [max_number_of_states][number_of_kpoints][number_of_spins]
305 :
306 : ncerr = nctk_def_dims(ncid, [ &
307 : nctkdim_t("real_or_complex_wavefunctions", 2), &
308 : nctkdim_t("number_of_grid_points_vector1", n1), &
309 : nctkdim_t("number_of_grid_points_vector2", n2), &
310 : nctkdim_t("number_of_grid_points_vector3", n3) &
311 5 : ], defmode=.True.)
312 1 : NCF_CHECK(ncerr)
313 :
314 : shape_str = "real_or_complex_wavefunctions, &
315 : & number_of_grid_points_vector1, number_of_grid_points_vector2, number_of_grid_points_vector3, &
316 : & number_of_spinor_components, &
317 1 : & max_number_of_states, number_of_kpoints, number_of_spins"
318 :
319 : ! Define wavefunctions in real space.
320 : ncerr = nctk_def_arrays(ncid, [&
321 : nctkarr_t('ur_ae', "dp", shape_str),&
322 : nctkarr_t('ur_pw', "dp", shape_str),&
323 : nctkarr_t('ur_ae_onsite', "dp", shape_str),&
324 : nctkarr_t('ur_ps_onsite', "dp", shape_str) &
325 5 : ], defmode=.True.)
326 1 : NCF_CHECK(ncerr)
327 :
328 : ! Complete the geometry information.
329 1 : NCF_CHECK(crystal%ncwrite(ncid))
330 1 : NCF_CHECK(ebands%ncwrite(ncid))
331 :
332 1 : NCF_CHECK(nf90_close(ncid))
333 : end if
334 :
335 1 : call xmpi_barrier(comm_cell)
336 :
337 : ! Reopen the file in parallel inside comm_cell
338 : ! Note that we use individual IO thus there's no need to handle idle processes
339 : ! if paral_kgb == 0 and nprocs > nkpt * nsppol
340 1 : NCF_CHECK(nctk_open_modify(ncid, fname, comm_cell))
341 1 : ae_ncid = nctk_idname(ncid, "ur_ae")
342 1 : pw_ncid = nctk_idname(ncid, "ur_pw")
343 1 : aeons_ncid = nctk_idname(ncid, "ur_ae_onsite")
344 1 : psons_ncid = nctk_idname(ncid, "ur_ps_onsite")
345 :
346 1 : NCF_CHECK(nctk_set_datamode(ncid))
347 : endif
348 :
349 : !Init structure storing phi_{nlm} and tphi_(nlm} on the dense FFT points located in the PAW spheres.
350 4 : ABI_MALLOC(Paw_onsite,(natom))
351 1 : if (paral_atom) then
352 : call paw_pwaves_lmn_init(Paw_onsite,my_natom,natom,crystal%ntypat,crystal%rprimd,crystal%xcart,&
353 0 : Pawtab,Pawrad,local_pawfgrtab, comm_atom=my_comm_atom,mpi_atmtab=my_atmtab)
354 : else
355 : call paw_pwaves_lmn_init(Paw_onsite,my_natom,natom,crystal%ntypat,crystal%rprimd,crystal%xcart,&
356 1 : Pawtab,Pawrad,local_pawfgrtab)
357 : end if
358 :
359 1 : bdtot_index=0; icg=0; ibg=0; norm_rerr=smallest_real
360 4 : ABI_MALLOC(paw_compl,(maxval(nband)))
361 7 : paw_compl=zero
362 :
363 : ! === Loop over spin ===
364 2 : do isppol=1,nsppol
365 1 : ikg=0; start_kpt=1; stop_kpt=nkpt
366 :
367 : ! Check if k-point was specified (only serial)
368 1 : if (present(set_k) .and. nprocs==1) then
369 1 : if (set_k/=0) then
370 1 : start_kpt = set_k
371 1 : stop_kpt = set_k
372 : !ABI_ERROR("set_k")
373 : end if
374 : end if
375 :
376 : ! === Loop over k points ===
377 3 : do ikpt=start_kpt,stop_kpt
378 4 : kpoint = kpt(:,ikpt)
379 1 : nband_k = nband(ikpt+(isppol-1)*nkpt)
380 1 : npw_k = npwarr(ikpt)
381 1 : istwf_k = istwfk(ikpt)
382 :
383 1 : if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me_kpt)) then
384 1 : bdtot_index=bdtot_index+nband_k
385 : !ABI_ERROR("cycle in seq!")
386 : cycle
387 : end if
388 :
389 21 : do i3=0,n3-1
390 20 : rfft(3)=DBLE(i3)/n3
391 381 : do i2=0,n2-1
392 360 : rfft(2)=DBLE(i2)/n2
393 6140 : do i1=0,n1-1
394 5760 : rfft(1)=DBLE(i1)/n1
395 5760 : ifft = 1 +i1 +i2*n1 +i3*n1*n2
396 23040 : phkr(1,ifft) = COS(two_pi*dot_product(kpoint,rfft))
397 23400 : phkr(2,ifft) = SIN(two_pi*dot_product(kpoint,rfft))
398 : end do
399 : end do
400 : end do
401 : ! phkr(1,:)=one; phkr(2,:)=zero
402 :
403 : ! Calculate the phase for the onsite PAW contributions.
404 2 : do iatom=1,my_natom
405 1 : nfgd=local_pawfgrtab(iatom)%nfgd ! no. of points in the fine grid for this PAW sphere
406 1431 : do ifgd=1,nfgd
407 5716 : arg = -two_pi* dot_product(r0shift(:,ifgd,iatom),kpoint)
408 1429 : phk_atm(1,ifgd,iatom) = COS(arg)
409 1430 : phk_atm(2,ifgd,iatom) = SIN(arg)
410 : end do
411 : end do
412 :
413 16 : ABI_MALLOC(Cprj_k,(natom,dtset%nspinor*nband_k))
414 1 : call pawcprj_alloc(Cprj_k,0,dimcprj)
415 :
416 : ! Extract cprj for this k-point.
417 1 : ibsp=0
418 7 : do iband=1,nband_k
419 13 : do ispinor=1,dtset%nspinor
420 6 : ibsp=ibsp+1
421 18 : do iatom=1,natom
422 246 : Cprj_k(iatom,ibsp)%cp(:,:)=Cprj(iatom,ibsp+ibg)%cp(:,:)
423 : end do
424 : end do
425 : end do
426 :
427 3 : ABI_MALLOC(kg_k,(3,npw_k))
428 :
429 : ! Extract G-vectors.
430 117 : kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
431 1 : call sphereboundary(gbound,istwf_k,kg_k,mgfftf,npw_k)
432 :
433 : ! If a single band is requested, neuter the loop (only serial)
434 1 : start_band = 1; stop_band = nband_k
435 1 : if (present(set_band).AND.nprocs==1) then
436 1 : if (set_band/=0) then
437 1 : start_band = set_band
438 1 : stop_band = set_band
439 : !ABI_ERROR("set_band")
440 : end if
441 : end if
442 :
443 : ! Loop over bands.
444 7 : do iband=start_band,stop_band
445 :
446 : ! Fourier transform on the real fft box of the smooth part.
447 6 : ndat=Dtset%nspinor
448 18 : ABI_MALLOC(fofgin,(2,npw_k*ndat))
449 30 : ABI_MALLOC(fofr,(2,n4,n5,n6*ndat))
450 :
451 180 : do ipw=1,npw_k*dtset%nspinor
452 528 : fofgin(:,ipw)=cg(:,ipw+(iband-1)*npw_k*dtset%nspinor+icg)
453 : end do
454 :
455 : ! Complex can be set to 0 with this option(0) of fourwf
456 6 : option=0; cplex=0; npwout=1
457 18 : ABI_MALLOC(denpot,(cplex*n4,n5,n6))
458 18 : ABI_MALLOC(fofgout,(2,npwout*ndat))
459 :
460 : call fourwf(cplex,denpot,fofgin(:,1:npw_k),fofgout,fofr(:,:,:,1:n6),gbound,gbound,istwf_k,kg_k,kg_k,&
461 : mgfftf,MPI_enreg,1,ngfftf,npw_k,npwout,n4,n5,n6,option,tim_fourwf0,weight1,weight1,&
462 6 : gpu_option=Dtset%gpu_option)
463 :
464 : ! Here I do not know if fourwf works in the case of spinors,
465 : ! It seems that not all fftalg option support ndata! should check!
466 : ! Do not forget to declare real(dp)::fofgin_down(:,:) to use the following statements
467 6 : if (Dtset%nspinor==2) then
468 0 : ABI_MALLOC(fofgin_down,(2,npw_k))
469 0 : ABI_MALLOC(fofr_down,(2,n4,n5,n6))
470 0 : fofgin_down(:,:)=fofgin(:,1+npw_k:2*npw_k)
471 : ! Complex can be set to 0 with this option(0) of fourwf
472 : ! cplex=1; option=1; npwout=1; ndat=1
473 : ! NOTE: fofr_down can NOT be replaced by fofr(:,:,:,n6+1:2*n6), or else
474 : ! the data in fofr(:,:,:,1:n6) will be the same with fofr(:,:,:,n6+1:2*n6)
475 : call fourwf(cplex,denpot,fofgin_down,fofgout,fofr_down,gbound,gbound,istwf_k,kg_k,kg_k,&
476 0 : mgfftf,MPI_enreg,1,ngfftf,npw_k,npwout,n4,n5,n6,option,tim_fourwf0,weight1,weight1)
477 0 : ABI_FREE(fofgin_down)
478 : end if
479 :
480 18 : ABI_MALLOC(ur_ae,(2,n1*n2*n3*ndat))
481 18 : ABI_MALLOC(ur_ae_onsite,(2,n1*n2*n3))
482 12 : ABI_MALLOC(ur_ps_onsite,(2,n1*n2*n3))
483 12 : ABI_MALLOC(ur_pw,(2,n1*n2*n3*ndat))
484 18 : ABI_MALLOC(ur_mask,(n1*n2*n3))
485 :
486 449286 : ur_ae=zero;ur_ae_onsite=zero;ur_ps_onsite=zero;ur_pw=zero;ur_mask=zero
487 :
488 : ! * Add phase e^{ikr} since it is contained in cprj.
489 126 : do i3=1,n3
490 2286 : do i2=1,n2
491 36840 : do i1=1,n1
492 34560 : ii = i1 + n1*(i2-1)+ n1*n2*(i3-1)
493 103680 : ur_pw(:,ii)=fofr(:,i1,i2,i3) ! Save pw part separately without the phase.
494 34560 : ur_ae(1,ii)= fofr(1,i1,i2,i3) * phkr(1,ii) - fofr(2,i1,i2,i3) * phkr(2,ii)
495 34560 : ur_ae(2,ii)= fofr(1,i1,i2,i3) * phkr(2,ii) + fofr(2,i1,i2,i3) * phkr(1,ii)
496 36720 : if(Dtset%nspinor==2) then
497 0 : ur_pw(:,ii+n1*n2*n3)=fofr_down(:,i1,i2,i3) ! Save pw part separately without the phase.
498 0 : ur_ae(1,ii+n1*n2*n3)= fofr_down(1,i1,i2,i3) * phkr(1,ii) - fofr_down(2,i1,i2,i3) * phkr(2,ii)
499 0 : ur_ae(2,ii+n1*n2*n3)= fofr_down(1,i1,i2,i3) * phkr(2,ii) + fofr_down(2,i1,i2,i3) * phkr(1,ii)
500 : end if
501 : end do
502 : end do
503 : end do
504 6 : ABI_FREE(fofr)
505 :
506 6 : if(Dtset%nspinor==2) then
507 0 : ABI_FREE(fofr_down)
508 : end if
509 :
510 : ! === Add onsite term on the augmented FFT mesh ===
511 12 : do iatom=1,my_natom
512 6 : itypat =local_pawfgrtab(iatom)%itypat
513 6 : lmn_size=Pawtab(itypat)%lmn_size
514 6 : ln_size =Pawtab(itypat)%basis_size ! no. of nl elements in PAW basis
515 6 : nfgd =local_pawfgrtab(iatom)%nfgd ! no. of points in the fine grid for this PAW sphere
516 :
517 6 : ibsp=(iband-1)*dtset%nspinor
518 18 : do ispinor=1,dtset%nspinor
519 6 : ibsp=ibsp+1
520 90 : do jlmn=1,lmn_size
521 78 : jl=Pawtab(itypat)%indlmn(1,jlmn)
522 78 : jm=Pawtab(itypat)%indlmn(2,jlmn)
523 78 : cp_fact(1) = Cprj_k(iatom,ibsp)%cp(1,jlmn) *sqrt(crystal%ucvol) ! Magic factor
524 78 : cp_fact(2) = Cprj_k(iatom,ibsp)%cp(2,jlmn) *sqrt(crystal%ucvol)
525 :
526 111546 : do ifgd=1,nfgd ! loop over fine grid points in current PAW sphere.
527 111462 : ifftsph = local_pawfgrtab(iatom)%ifftsph(ifgd) ! index of the point on the grid
528 111462 : phj = Paw_onsite(iatom)% phi(ifgd,jlmn)
529 111462 : tphj = Paw_onsite(iatom)%tphi(ifgd,jlmn)
530 : ! old code
531 : !re_p = cp_fact(1); im_p = cp_fact(2)
532 : ! apply the phase
533 111462 : re_p = cp_fact(1) * phk_atm(1,ifgd,iatom) - cp_fact(2) * phk_atm(2,ifgd,iatom)
534 111462 : im_p = cp_fact(1) * phk_atm(2,ifgd,iatom) + cp_fact(2) * phk_atm(1,ifgd,iatom)
535 :
536 111462 : ur_ae(1,ifftsph+(ispinor-1)*nfftot) = ur_ae(1,ifftsph+(ispinor-1)*nfftot) + re_p * (phj-tphj)
537 111462 : ur_ae(2,ifftsph+(ispinor-1)*nfftot) = ur_ae(2,ifftsph+(ispinor-1)*nfftot) + im_p * (phj-tphj)
538 111462 : ur_ae_onsite(1,ifftsph) = ur_ae_onsite(1,ifftsph) + re_p * phj
539 111462 : ur_ae_onsite(2,ifftsph) = ur_ae_onsite(2,ifftsph) + im_p * phj
540 111462 : ur_ps_onsite(1,ifftsph) = ur_ps_onsite(1,ifftsph) + re_p * tphj
541 111462 : ur_ps_onsite(2,ifftsph) = ur_ps_onsite(2,ifftsph) + im_p * tphj
542 111540 : ur_mask(ifftsph) = one
543 : end do
544 :
545 : end do !jlmn
546 : end do !ispinor
547 : end do !iatom
548 :
549 6 : if (paral_atom) then
550 0 : ABI_MALLOC(buf_tmp,(2,n1*n2*n3,3))
551 0 : buf_tmp(:,:,1) = ur_ae
552 0 : buf_tmp(:,:,2) = ur_ae_onsite
553 0 : buf_tmp(:,:,3) = ur_ps_onsite
554 0 : call xmpi_sum(buf_tmp,my_comm_atom,ierr)
555 0 : ur_ae = buf_tmp(:,:,1)
556 0 : ur_ae_onsite= buf_tmp(:,:,2)
557 0 : ur_ps_onsite= buf_tmp(:,:,3)
558 0 : ABI_FREE(buf_tmp)
559 : end if
560 :
561 : ! * Remove the phase e^{ikr}, we store u(r).
562 126 : do i3=1,n3
563 2286 : do i2=1,n2
564 36840 : do i1=1,n1
565 34560 : ii = i1 + n1*(i2-1)+ n1*n2*(i3-1)
566 34560 : reur=ur_ae(1,ii)
567 34560 : imur=ur_ae(2,ii)
568 34560 : ur_ae(1,ii)= reur * phkr(1,ii) + imur * phkr(2,ii)
569 34560 : ur_ae(2,ii)= -reur * phkr(2,ii) + imur * phkr(1,ii)
570 34560 : if(Dtset%nspinor==2) then
571 0 : reur=ur_ae(1,ii+nfftot) ! Important!
572 0 : imur=ur_ae(2,ii+nfftot)
573 0 : ur_ae(1,ii+nfftot)= reur * phkr(1,ii) + imur * phkr(2,ii)
574 0 : ur_ae(2,ii+nfftot)= -reur * phkr(2,ii) + imur * phkr(1,ii)
575 : end if
576 34560 : reur=ur_ae_onsite(1,ii)
577 34560 : imur=ur_ae_onsite(2,ii)
578 34560 : ur_ae_onsite(1,ii)= reur * phkr(1,ii) + imur * phkr(2,ii)
579 34560 : ur_ae_onsite(2,ii)= -reur * phkr(2,ii) + imur * phkr(1,ii)
580 34560 : reur=ur_ps_onsite(1,ii)
581 34560 : imur=ur_ps_onsite(2,ii)
582 34560 : ur_ps_onsite(1,ii)= reur * phkr(1,ii) + imur * phkr(2,ii)
583 36720 : ur_ps_onsite(2,ii)= -reur * phkr(2,ii) + imur * phkr(1,ii)
584 : end do
585 : end do
586 : end do
587 :
588 6 : norm=zero
589 180 : do ii=1,npw_k*Dtset%nspinor
590 180 : norm=norm+fofgin(1,ii)**2+fofgin(2,ii)**2
591 : end do
592 6 : write(std_out,'(a,2i5,f22.16)',advance='no') 'ikpt,iband, norm (G,PSWF)=',ikpt,iband,norm
593 6 : norm=zero
594 34566 : do ifft=1,nfftot*Dtset%nspinor
595 34566 : norm = norm + ur_ae(1,ifft)**2+ur_ae(2,ifft)**2
596 : end do
597 6 : norm=norm/nfftot
598 6 : norm_rerr = MAX((ABS(norm-one))*100,norm_rerr)
599 6 : write(std_out,*)"norm (R,AEWF)= ",norm
600 6 : call flush_unit(std_out)
601 :
602 6 : norm=zero
603 34566 : do ifft=1, nfftot
604 34566 : norm=norm+(ur_pw(1,ifft)**2+ur_pw(2,ifft)**2)*ur_mask(ifft)
605 : enddo
606 34566 : do ifft=1, nfftot
607 : paw_compl(iband)=paw_compl(iband)+(ur_pw(1,ifft)*ur_ps_onsite(1,ifft)+ur_pw(2,ifft)*ur_ps_onsite(2,ifft))&
608 34566 : & /norm/nsppol*dtset%wtk(ikpt) !/(stop_kpt-start_kpt+1)
609 : enddo
610 :
611 : ! MS: Various testing and debugging options
612 6 : if (.TRUE..and.nprocs==1) then
613 6 : if (present(pseudo_norms)) then
614 : ! Check the supposedly zero overlap |\tilde{Psi_n}-\tilde{Psi_n^1}|^2
615 12 : ABI_MALLOC(dummy_1d,(n1*n2*n3))
616 34566 : dummy_1d = zero
617 6 : norm = zero
618 34566 : do ifft = 1, nfftot
619 : dummy_1d(ifft) = ((ur_pw(1,ifft)-ur_ps_onsite(1,ifft))**2 &
620 34560 : + (ur_pw(2,ifft)-ur_ps_onsite(2,ifft))**2) * ur_mask(ifft)
621 34566 : norm = norm + dummy_1d(ifft)
622 : end do
623 6 : norm = norm / nfftot
624 6 : pseudo_norms(isppol,ikpt,iband) = norm
625 6 : ABI_FREE(dummy_1d)
626 : end if
627 :
628 : else
629 : write(msg,'(5a)')&
630 0 : "The option to print PAW all-electron wavefunctions is on, but execution ",ch10,&
631 0 : "is in parallel on two or more processors. XcrysDen files with individual con-",ch10,&
632 0 : "tributions will not be written. In order to enable this you must run in serial."
633 0 : ABI_WARNING(msg)
634 : end if ! Check if serial run
635 :
636 6 : if(dtset%pawprtwf==1) then
637 : ncerr = nf90_put_var(ncid, ae_ncid, ur_ae, &
638 102 : start=[1,1,1,1,1,iband,ikpt,isppol], count=[2,n1,n2,n3,1,1,1,1])
639 6 : NCF_CHECK(ncerr)
640 :
641 : ncerr = nf90_put_var(ncid, pw_ncid, ur_pw, &
642 102 : start=[1,1,1,1,1,iband,ikpt,isppol], count=[2,n1,n2,n3,1,1,1,1])
643 6 : NCF_CHECK(ncerr)
644 :
645 : ncerr = nf90_put_var(ncid, aeons_ncid, ur_ae_onsite, &
646 102 : start=[1,1,1,1,1,iband,ikpt,isppol], count=[2,n1,n2,n3,1,1,1,1])
647 6 : NCF_CHECK(ncerr)
648 :
649 : ncerr = nf90_put_var(ncid, psons_ncid, ur_ps_onsite, &
650 102 : start=[1,1,1,1,1,iband,ikpt,isppol], count=[2,n1,n2,n3,1,1,1,1])
651 6 : NCF_CHECK(ncerr)
652 : endif
653 :
654 6 : ABI_FREE(ur_ae)
655 6 : ABI_FREE(ur_ae_onsite)
656 6 : ABI_FREE(ur_ps_onsite)
657 6 : ABI_FREE(ur_pw)
658 6 : ABI_FREE(ur_mask)
659 6 : ABI_FREE(fofgin)
660 6 : ABI_FREE(fofgout)
661 7 : ABI_FREE(denpot)
662 : end do !nband_k
663 :
664 1 : bdtot_index=bdtot_index+nband_k
665 :
666 1 : if (mkmem/=0) then
667 1 : ibg=ibg+dtset%nspinor*nband_k
668 1 : icg=icg+npw_k*dtset%nspinor*nband_k
669 1 : ikg=ikg+npw_k
670 : end if
671 :
672 1 : ABI_FREE(kg_k)
673 :
674 1 : call pawcprj_free(Cprj_k)
675 8 : ABI_FREE(Cprj_k)
676 :
677 : end do !ikpt
678 : end do !nsppol
679 :
680 1 : ABI_FREE(phkr)
681 1 : ABI_FREE(gbound)
682 :
683 : ! Free augmentation waves.
684 1 : call paw_pwaves_lmn_free(Paw_onsite)
685 2 : ABI_FREE(Paw_onsite)
686 :
687 : ! Maximum relative error over CPUs.
688 1 : call xmpi_max(norm_rerr,max_rerr,comm_cell,ierr)
689 1 : write(std_out,*)"max_rerr=",max_rerr
690 :
691 1 : if (max_rerr > ten) then
692 : write(msg,'(7a)')&
693 1 : "Inaccuracy on the normalization of the wave funtions exceeds 10%. ",ch10,&
694 1 : "Likely due to the use of a too coarse FFT mesh or unconverged wavefunctions. ",ch10,&
695 1 : "Numerical values inside the augmentation regions might be inaccurate. ",ch10,&
696 2 : "Action: increase pawecutdg in your input file. "
697 1 : ABI_COMMENT(msg)
698 : end if
699 :
700 :
701 1 : open(file=trim(dtfil%filnam_ds(4))//'_PAWCOMPL', newunit=tmp_unt,status='unknown',form='formatted')
702 8 : do iband=1,maxval(nband)
703 7 : write(tmp_unt,*) iband,paw_compl(iband)
704 : enddo
705 1 : close(tmp_unt)
706 :
707 1 : ABI_FREE(paw_compl)
708 1 : ABI_FREE(r0shift)
709 1 : ABI_FREE(phk_atm)
710 1 : call pawfgrtab_free(local_pawfgrtab)
711 :
712 : ! Destroy atom table used for parallelism
713 1 : call free_my_atmtab(my_atmtab,my_atmtab_allocated)
714 :
715 : DBG_EXIT("COLL")
716 :
717 5 : end subroutine pawmkaewf
718 : !!***
719 :
720 : end module m_paw_mkaewf
721 : !!***
|