Branch data Line data Source code
1 : : !!****m* ABINIT/m_gwr_driver
2 : : !! NAME
3 : : !! m_gwr_driver
4 : : !!
5 : : !! FUNCTION
6 : : !! Driver for GWR calculations
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2021-2026 ABINIT group (MG)
10 : : !! This file is distributed under the terms of the
11 : : !! APACHE license version 2.0, see ~abinit/COPYING
12 : : !! or https://www.apache.org/licenses/LICENSE-2.0 .
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_gwr_driver
23 : :
24 : : use, intrinsic :: iso_c_binding
25 : : USE_MPI
26 : : use defs_basis
27 : : use defs_wvltypes
28 : : use m_errors
29 : : use m_abicore
30 : : use m_xmpi
31 : : use m_xomp
32 : : use m_hdr
33 : : use libxc_functionals
34 : : use m_crystal
35 : : use m_ebands
36 : : use m_dtset
37 : : use m_dtfil
38 : : use m_wfk
39 : : use netcdf
40 : : use m_nctk
41 : :
42 : : use defs_datatypes, only : pseudopotential_type
43 : : use defs_abitypes, only : MPI_type
44 : : use m_time, only : timab
45 : : use m_io_tools, only : file_exists, open_file, get_unit, iomode_from_fname
46 : : use m_time, only : cwtime, cwtime_report, sec2str
47 : : use m_fstrings, only : strcat, sjoin, ftoa, itoa, string_in, ltoa
48 : : use m_fftcore, only : print_ngfft, get_kg
49 : : use m_fft, only : fourdp
50 : : use m_ioarr, only : read_rhor
51 : : use m_energies, only : energies_type
52 : : use m_mpinfo, only : destroy_mpi_enreg, initmpi_seq
53 : : use m_pawang, only : pawang_type
54 : : use m_pawrad, only : pawrad_type
55 : : use m_pawtab, only : pawtab_type, pawtab_print, pawtab_get_lsize
56 : : use m_paw_an, only : paw_an_type, paw_an_init, paw_an_free, paw_an_nullify
57 : : use m_paw_ij, only : paw_ij_type, paw_ij_init, paw_ij_free, paw_ij_nullify
58 : : use m_pawfgrtab, only : pawfgrtab_type, pawfgrtab_init, pawfgrtab_free, pawfgrtab_print
59 : : use m_pawrhoij, only : pawrhoij_type, pawrhoij_alloc, pawrhoij_copy, pawrhoij_free, &
60 : : pawrhoij_inquire_dim, pawrhoij_symrhoij, pawrhoij_unpack
61 : : use m_pawdij, only : pawdij, symdij_all
62 : : use m_pawfgr, only : pawfgr_type, pawfgr_init, pawfgr_destroy
63 : : use m_paw_pwaves_lmn, only : paw_pwaves_lmn_t, paw_pwaves_lmn_init, paw_pwaves_lmn_free
64 : : use m_pawpwij, only : pawpwff_t, pawpwff_init, pawpwff_free, paw_rho_tw_g
65 : : use m_kg, only : getph
66 : : use m_wfd, only : wfd_t, test_charge
67 : : use m_pspini, only : pspini
68 : : use m_paw_correlations,only : pawpuxinit
69 : : use m_paw_dmft, only : paw_dmft_type
70 : : use m_paw_sphharm, only : setsym_ylm
71 : : use m_paw_mkrho, only : denfgr
72 : : use m_paw_nhat, only : nhatgrid, pawmknhat
73 : : use m_paw_tools, only : chkpawovlp, pawprt
74 : : use m_paw_denpot, only : pawdenpot
75 : : use m_paw_init, only : pawinit, paw_gencond
76 : : use m_pawcprj, only : pawcprj_type, pawcprj_free, pawcprj_alloc ! , paw_overlap
77 : : use m_pawxc, only : pawxc_get_usekden
78 : : use m_ksdiago, only : ugb_t, hyb_t
79 : : use m_mkrho, only : prtrhomxmn
80 : : use m_melemts, only : melflags_t
81 : : use m_setvtr, only : setvtr
82 : : use m_vhxc_me, only : calc_vhxc_me
83 : : use m_gwr, only : gwr_t
84 : : use m_vcoul, only : vcgen_t
85 : : use m_ephtk, only : ephtk_update_ebands
86 : : use m_pstat, only : pstat_proc
87 : :
88 : : implicit none
89 : :
90 : : private
91 : : !!***
92 : :
93 : : public :: gwr_driver
94 : :
95 : : #ifdef HAVE_MPI1
96 : : include 'mpif.h'
97 : : #endif
98 : : !!***
99 : :
100 : : contains
101 : : !!***
102 : :
103 : : !!****f* m_gwr_driver/gwr_driver
104 : : !! NAME
105 : : !! gwr_driver
106 : : !!
107 : : !! FUNCTION
108 : : !! Main routine for GWR calculations.
109 : : !!
110 : : !! INPUTS
111 : : !! acell(3)=Length scales of primitive translations (bohr)
112 : : !! codvsn=Code version
113 : : !! dtfil<datafiles_type>=Variables related to files.
114 : : !! dtset<dataset_type>=All input variables for this dataset.
115 : : !! pawang<pawang_type)>=PAW angular mesh and related data.
116 : : !! pawrad(ntypat*usepaw)<pawrad_type>=Paw radial mesh and related data.
117 : : !! pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
118 : : !! psps<pseudopotential_type>=Variables related to pseudopotentials.
119 : : !! Before entering the first time in the routine, a significant part of Psps has been initialized :
120 : : !! the integers dimekb,lmnmax,lnmax,mpssang,mpssoang,mpsso,mgrid,ntypat,n1xccc,usepaw,useylm,
121 : : !! and the arrays dimensioned to npsp. All the remaining components of Psps are to be initialized in
122 : : !! the call to pspini. The next time the code enters bethe_salpeter, Psps might be identical to the
123 : : !! one of the previous Dtset, in which case, no reinitialisation is scheduled in pspini.F90.
124 : : !! xred(3,natom)=Reduced atomic coordinates.
125 : : !!
126 : : !! NOTES
127 : : !!
128 : : !! ON THE USE OF FFT GRIDS:
129 : : !! =================
130 : : !! In case of PAW:
131 : : !! ---------------
132 : : !! Two FFT grids are used:
133 : : !! - A "coarse" FFT grid (defined by ecut) for the application of the Hamiltonian on the plane waves basis.
134 : : !! It is defined by nfft, ngfft, mgfft, ...
135 : : !! Hamiltonian, wave-functions, density related to WFs (rhor here), ... are expressed on this grid.
136 : : !! - A "fine" FFT grid (defined) by ecutdg) for the computation of the density inside PAW spheres.
137 : : !! It is defined by nfftf, ngfftf, mgfftf, ... Total density, potentials, ... are expressed on this grid.
138 : : !! In case of norm-conserving:
139 : : !! ---------------------------
140 : : !! - Only the usual FFT grid (defined by ecut) is used. It is defined by nfft, ngfft, mgfft, ...
141 : : !! For compatibility reasons, (nfftf,ngfftf,mgfftf) are set equal to (nfft,ngfft,mgfft) in that case.
142 : : !!
143 : : !! SOURCE
144 : :
145 : 0 : subroutine gwr_driver(codvsn, dtfil, dtset, pawang, pawrad, pawtab, psps, xred)
146 : :
147 : : !Arguments ------------------------------------
148 : : !scalars
149 : : character(len=8),intent(in) :: codvsn
150 : : type(datafiles_type),intent(in) :: dtfil
151 : : type(dataset_type),intent(inout) :: dtset
152 : : type(pawang_type),intent(inout) :: pawang
153 : : type(pseudopotential_type),intent(inout) :: psps
154 : : !arrays
155 : : real(dp),intent(in) :: xred(3,dtset%natom)
156 : : type(pawrad_type),intent(inout) :: pawrad(psps%ntypat*psps%usepaw)
157 : : type(pawtab_type),intent(inout) :: pawtab(psps%ntypat*psps%usepaw)
158 : :
159 : : !Local variables ------------------------------
160 : : !scalars
161 : : integer,parameter :: master = 0, cplex1 = 1, ipert0 = 0, idir0 = 0, optrhoij1 = 1
162 : : integer :: ii, comm, nprocs, my_rank, mgfftf, nfftf, omp_ncpus, work_size, nks_per_proc
163 : : integer :: ierr, spin, ik_ibz, nband_k, iomode__, color, io_comm, usevxctau_paw !, kg_varid
164 : : real(dp) :: eff, mempercpu_mb, max_wfsmem_mb, nonscal_mem, el_temp
165 : : real(dp) :: ecore, ecut_eff, ecutdg_eff, cpu, wall, gflops, diago_cpu, diago_wall, diago_gflops
166 : : logical, parameter :: is_dfpt = .false.
167 : : logical :: read_wfk, write_wfk, cc4s_task, rectangular, with_pools, rdm_update, call_pawinit, cc4s_from_wfk
168 : : character(len=500) :: msg
169 : : character(len=fnlen) :: wfk_path, den_path, kden_path, out_path
170 : 0 : type(hdr_type) :: wfk_hdr, den_hdr, kden_hdr, owfk_hdr
171 [ # # # # : 0 : type(crystal_t) :: cryst, den_cryst, wfk_cryst
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
172 : 0 : type(ebands_t) :: ks_ebands, owfk_ebands, tmp_ebands
173 : : type(pawfgr_type) :: pawfgr
174 : 0 : type(wvl_data) :: wvl
175 : 0 : type(mpi_type) :: mpi_enreg_seq
176 [ # # # # : 0 : type(gwr_t) :: gwr
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
177 [ # # ]: 0 : type(wfk_t) :: owfk
178 : : !arrays
179 : : real(dp), parameter :: k0(3) = zero
180 : : integer :: cplex, cplex_dij, cplex_rhoij
181 : : integer :: gnt_option,has_dijU,has_dijso,ider,izero
182 : : integer :: istep, moved_atm_inside, moved_rhor, n3xccc, sc_mode
183 : : !integer :: ngrvdw,nhatgrdim,nkxc,nkxc1,nprocs,nscf,nspden_rhoij,nzlmopt,optene
184 : : integer :: ndij !,ndim,nfftf,nfftf_tot,nkcalc,gwc_nfft,gwc_nfftot,gwx_nfft,gwx_nfftot
185 : : integer :: ngrvdw, nhatgrdim, nkxc, nkxc1, nspden_rhoij, optene, nzlmopt
186 : : integer :: optcut, optgr0, optgr1, optgr2, optrad, psp_gencond, option
187 : : integer :: rhoxsp_method, usexcnhat !, use_umklp
188 : : real(dp) :: compch_fft, compch_sph !,r_s,rhoav,alpha
189 : : !real(dp) :: drude_plsmf !,my_plsmf,ecut_eff,ecutdg_eff,ehartree
190 : : real(dp) :: gsqcutc_eff, gsqcutf_eff, gsqcut_shp, vxcavg, gw_gsq, gs_fermie
191 : : type(energies_type) :: KS_energies
192 : : type(melflags_t) :: KS_mflags
193 : 0 : type(paw_dmft_type) :: Paw_dmft
194 [ # # # # : 0 : type(ugb_t) :: ugb
# # # # #
# ]
195 [ # # # # : 0 : type(hyb_t) :: hyb
# # # # #
# # # ]
196 : 0 : type(xmpi_pool2d_t) :: diago_pool
197 : : !arrays
198 : : integer :: ngfftc(18),ngfftf(18),units(2) !, grid3(3)
199 : 0 : integer,allocatable :: nq_spl(:), l_size_atm(:)
200 : 0 : integer,allocatable :: tmp_kstab(:,:,:), npwarr_ik(:), gvec_(:,:), istwfk_ik(:), nband_iks(:,:)
201 : 0 : real(dp) :: strsxc(6), diago_info(3, dtset%nkpt, dtset%nsppol),tsec(2)
202 : 0 : real(dp),allocatable :: grchempottn(:,:),grewtn(:,:),grvdw(:,:),qmax(:)
203 : 0 : real(dp),allocatable :: ks_nhat(:,:),ks_nhatgr(:,:,:),ks_rhog(:,:)
204 : 0 : real(dp),allocatable :: ks_rhor(:,:),ks_vhartr(:), ks_vtrial(:,:), ks_vxc(:,:)
205 : 0 : real(dp),allocatable :: ks_taur(:,:) !, ks_vxctau(:,:), xcctau3d(:)
206 : 0 : real(dp),allocatable :: kxc(:,:), ph1d(:,:), ph1df(:,:) !qp_kxc(:,:),
207 : 0 : real(dp),allocatable :: vpsp(:), xccc3d(:), dijexc_core(:,:,:) !, dij_hf(:,:,:)
208 : 0 : real(dp),allocatable :: eig_k(:), occ_k(:)
209 : 0 : real(dp),contiguous,pointer :: cg_k_ptr(:,:)
210 : 0 : type(paw_an_type),allocatable :: KS_paw_an(:)
211 : 0 : type(paw_ij_type),allocatable :: KS_paw_ij(:)
212 : 0 : type(pawfgrtab_type),allocatable :: Pawfgrtab(:)
213 : 0 : type(pawrhoij_type),allocatable :: KS_Pawrhoij(:)
214 : 0 : type(pawpwff_t),allocatable :: Paw_pwff(:)
215 : : !type(pawcprj_type),allocatable :: cprj_k(:,:)
216 : : !************************************************************************
217 : :
218 : : ! This part performs the initialization of the basic objects used to perform e-ph calculations:
219 : : !
220 : : ! 1) Crystal structure `cryst`
221 : : ! 2) Ground state band energies: `ks_ebands`
222 : : ! 5) Pseudos and PAW basic objects.
223 : : !
224 : : ! Once we have these objects, we can call specialized routines for e-ph calculations.
225 : : ! Notes:
226 : : !
227 : : ! * Any modification to the basic objects mentioned above should be done here (e.g. change of efermi)
228 : : ! * This routines shall not allocate big chunks of memory. The CPU-demanding sections should be
229 : : ! performed in the subdriver that will employ different MPI distribution schemes optimized for that particular task.
230 : :
231 : : ! abirules!
232 : : if (.False.) write(std_out,*)xred
233 : :
234 : 0 : comm = xmpi_world; nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
235 [ # # ]: 0 : units(:) = [std_out, ab_out]
236 : :
237 : 0 : call cwtime(cpu, wall, gflops, "start")
238 : 0 : call pstat_proc%print(_PSTAT_ARGS_)
239 : :
240 : : ! write(msg,'(a)')&
241 : : ! ' GWR: Calculation of the GW corrections with GWR code ',ch10,ch10,&
242 : : ! call wrtout(units, msg)
243 : : !
244 : : #if defined HAVE_GW_DPC
245 : 0 : write(msg,'(a,i2,a)')'.Using double precision arithmetic; gwpc = ',gwp,ch10
246 : : #else
247 : : write(msg,'(a,i2,a)')'.Using single precision arithmetic; gwpc = ',gwp,ch10
248 : : #endif
249 : 0 : call wrtout(units, msg)
250 : :
251 : : ! autoparal section
252 : : ! TODO: This just to activate autoparal in AbiPy. Lot of things should be improved.
253 [ # # ]: 0 : if (dtset%max_ncpus /= 0) then
254 : 0 : write(ab_out,'(a)')"--- !Autoparal"
255 : 0 : write(ab_out,"(a)")"# Autoparal section for GWR runs"
256 : 0 : write(ab_out,"(a)") "info:"
257 : 0 : write(ab_out,"(a,i0)")" autoparal: ",dtset%autoparal
258 : 0 : write(ab_out,"(a,i0)")" max_ncpus: ",dtset%max_ncpus
259 : 0 : write(ab_out,"(a,i0)")" nkpt: ",dtset%nkpt
260 : 0 : write(ab_out,"(a,i0)")" nsppol: ",dtset%nsppol
261 : 0 : write(ab_out,"(a,i0)")" nspinor: ",dtset%nspinor
262 : 0 : write(ab_out,"(a,i0)")" mband: ",dtset%mband
263 : 0 : write(ab_out,"(3a)") " gwr_task: '",trim(dtset%gwr_task),"'"
264 : :
265 [ # # ]: 0 : if (string_in(dtset%gwr_task, "HDIAGO, HDIAGO_FULL, CC4S, CC4S_FULL")) then
266 : 0 : work_size = dtset%nkpt * dtset%nsppol * dtset%mpw
267 : 0 : max_wfsmem_mb = (two * dp * dtset%mpw * dtset%mband * dtset%nkpt * dtset%nsppol * dtset%nspinor * b2Mb) * 1.1_dp
268 : : else
269 : 0 : work_size = dtset%gwr_ntau * dtset%nkpt * dtset%nsppol * dtset%mpw
270 : 0 : max_wfsmem_mb = (two * dp * dtset%mpw * dtset%mband * dtset%nkpt * dtset%nsppol * dtset%nspinor * b2Mb) * 1.1_dp
271 : : end if
272 : : ! Non-scalable memory in Mb i.e. memory that is not distributed with MPI.
273 : 0 : nonscal_mem = zero
274 : :
275 : : ! List of configurations.
276 : : ! Assuming an OpenMP implementation with perfect speedup!
277 : 0 : write(ab_out,"(a)")"configurations:"
278 : :
279 [ # # ]: 0 : do ii=1,dtset%max_ncpus
280 : 0 : nks_per_proc = work_size / ii
281 : 0 : nks_per_proc = nks_per_proc + mod(work_size, ii)
282 : 0 : eff = (one * work_size) / (ii * nks_per_proc)
283 : : ! Add the non-scalable part and increase by 10% to account for other datastructures.
284 : 0 : mempercpu_mb = (max_wfsmem_mb + nonscal_mem) * 1.1_dp
285 [ # # ]: 0 : do omp_ncpus=1,1 !xomp_get_max_threads()
286 : 0 : write(ab_out,"(a,i0)")" - tot_ncpus: ",ii * omp_ncpus
287 : 0 : write(ab_out,"(a,i0)")" mpi_ncpus: ",ii
288 : 0 : write(ab_out,"(a,i0)")" omp_ncpus: ",omp_ncpus
289 : 0 : write(ab_out,"(a,f12.9)")" efficiency: ",eff
290 : 0 : write(ab_out,"(a,f12.2)")" mem_per_cpu: ",mempercpu_mb
291 : : end do
292 : : end do
293 : 0 : write(ab_out,'(a)')"..."
294 : 0 : call wrtout(std_out, "Stopping now!")
295 : 0 : call abi_abort('PERS', exit_status=0, print_config=.false.)
296 : : end if
297 : :
298 [ # # # # : 0 : cryst = dtset%get_crystal(img=1)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
299 : :
300 : : ! Some variables need to be initialized/nullify at start
301 : 0 : usexcnhat = 0
302 : 0 : call KS_energies%init()
303 : :
304 : : !Get electronic temperature from dtset
305 [ # # # # : 0 : el_temp = merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
# # ]
306 : :
307 : 0 : den_path = dtfil%fildensin; wfk_path = dtfil%fnamewffk; kden_path = dtfil%filkdensin
308 : : !use_den = f (string_in(dtset%gwr_task, "CC4S_FROM_WFK")) then
309 : :
310 [ # # ]: 0 : if (my_rank == master) then
311 : : ! Initialize filenames. Accept files in Fortran or in netcdf format.
312 [ # # ]: 0 : if (nctk_try_fort_or_ncfile(den_path, msg) /= 0) then
313 : 0 : ABI_ERROR(sjoin("Cannot find DEN file:", den_path, ". Error:", msg))
314 : : end if
315 : 0 : call wrtout(units, sjoin("- Reading GS density from: ", den_path))
316 : :
317 [ # # ]: 0 : if (dtset%usekden == 1) then
318 [ # # ]: 0 : if (nctk_try_fort_or_ncfile(kden_path, msg) /= 0) then
319 : 0 : ABI_ERROR(sjoin("Cannot find KDEN file:", kden_path, ". Error:", msg))
320 : : end if
321 : 0 : call wrtout(units, sjoin("- Reading KDEN kinetic energy density from: ", kden_path))
322 : : end if
323 : 0 : call wrtout(ab_out, ch10//ch10)
324 : : end if ! master
325 : :
326 : : ! Broadcast filenames (needed if we are using netcdf files)
327 : 0 : call xmpi_bcast(den_path, master, comm, ierr)
328 : 0 : call xmpi_bcast(kden_path, master, comm, ierr)
329 : :
330 : : ! TODO: FFT meshes for DEN/POT should be initialized from the DEN file instead of the dtset.
331 : : ! Interpolating the DEN indeed breaks degeneracies in the vxc matrix elements.
332 : : call pawfgr_init(pawfgr, dtset, mgfftf, nfftf, ecut_eff, ecutdg_eff, ngfftc, ngfftf, &
333 : 0 : gsqcutc_eff=gsqcutc_eff, gsqcutf_eff=gsqcutf_eff, gmet=cryst%gmet, k0=k0)
334 : :
335 [ # # ]: 0 : call print_ngfft([std_out], ngfftc, header='Coarse FFT mesh for the wavefunctions')
336 [ # # ]: 0 : call print_ngfft([std_out], ngfftf, header='Dense FFT mesh for densities and potentials')
337 : :
338 : : ! Fake MPI_type for the sequential part.
339 : 0 : call initmpi_seq(mpi_enreg_seq)
340 : 0 : call mpi_enreg_seq%distribfft%init_seq('c', ngfftc(2), ngfftc(3), 'all')
341 : 0 : call mpi_enreg_seq%distribfft%init_seq('f', ngfftf(2), ngfftf(3), 'all')
342 : :
343 : : ! ===========================================
344 : : ! === Open and read pseudopotential files ===
345 : : ! ===========================================
346 : 0 : call pspini(dtset, dtfil, ecore, psp_gencond, gsqcutc_eff, gsqcutf_eff, pawrad, pawtab, psps, cryst%rprimd, comm_mpi=comm)
347 : :
348 : : ! ============================
349 : : ! ==== PAW initialization ====
350 : : ! ============================
351 [ # # ]: 0 : if (dtset%usepaw == 1) then
352 : 0 : call chkpawovlp(cryst%natom, cryst%ntypat, dtset%pawovlp, pawtab, cryst%rmet, cryst%typat, cryst%xred)
353 : :
354 : 0 : cplex_dij = dtset%nspinor; cplex = 1; ndij = 1
355 : :
356 [ # # # # : 0 : ABI_MALLOC(ks_pawrhoij, (cryst%natom))
# # # # #
# # # #
# ]
357 : : call pawrhoij_inquire_dim(cplex_rhoij=cplex_rhoij, nspden_rhoij=nspden_rhoij, &
358 : 0 : nspden=dtset%nspden, spnorb=dtset%pawspnorb, cpxocc=dtset%pawcpxocc)
359 : 0 : call pawrhoij_alloc(ks_pawrhoij, cplex_rhoij, nspden_rhoij, dtset%nspinor, dtset%nsppol, cryst%typat, pawtab=pawtab)
360 : :
361 : : ! Test if we have to call pawinit
362 [ # # # # : 0 : gnt_option = 1; if (dtset%pawxcdev == 2 .or. (dtset%pawxcdev == 1 .and. dtset%positron /= 0)) gnt_option = 2
# # ]
363 : 0 : call paw_gencond(dtset, gnt_option, "test", call_pawinit)
364 : : !call_pawinit = .True.
365 : :
366 [ # # # # ]: 0 : if (psp_gencond == 1 .or. call_pawinit) then
367 : 0 : call timab(553, 1, tsec)
368 : 0 : gsqcut_shp = two * abs(dtset%diecut) * dtset%dilatmx**2 / pi**2
369 : : call pawinit(dtset%effmass_free, gnt_option, gsqcut_shp, zero, dtset%pawlcutd, dtset%pawlmix, &
370 : : psps%mpsang, dtset%pawnphi, cryst%nsym, dtset%pawntheta, pawang, pawrad, &
371 : 0 : dtset%pawspnorb, pawtab, dtset%pawxcdev, dtset%ixc, dtset%usepotzero)
372 : 0 : call timab(553,2,tsec)
373 : :
374 : : ! Update internal values
375 : 0 : call paw_gencond(dtset, gnt_option, "save", call_pawinit)
376 : : else
377 [ # # # # ]: 0 : if (pawtab(1)%has_kij ==1) pawtab(1:cryst%ntypat)%has_kij = 2
378 [ # # # # ]: 0 : if (pawtab(1)%has_nabla==1) pawtab(1:cryst%ntypat)%has_nabla = 2
379 : : end if
380 : :
381 [ # # ]: 0 : psps%n1xccc = maxval(pawtab(1:cryst%ntypat)%usetcore)
382 : :
383 : : ! Initialize optional flags in Pawtab to zero
384 : : ! Cannot be done in Pawinit since the routine is called only if some parts. are changed
385 [ # # ]: 0 : pawtab(:)%has_nabla = 0
386 [ # # ]: 0 : pawtab(:)%lamb_shielding = zero
387 : :
388 : 0 : call setsym_ylm(cryst%gprimd, pawang%l_max-1, cryst%nsym, dtset%pawprtvol, cryst%rprimd, cryst%symrec, pawang%zarot)
389 : :
390 : : ! Initialize and compute data for DFT+U
391 : 0 : Paw_dmft%use_dmft = Dtset%usedmft
392 : : call pawpuxinit(Dtset%dmatpuopt,Dtset%exchmix,Dtset%f4of2_sla,Dtset%f6of2_sla, &
393 : : is_dfpt,Dtset%jpawu,Dtset%lexexch,Dtset%lpawu,dtset%nspinor,Cryst%ntypat,dtset%optdcmagpawu,Pawang,Dtset%pawprtvol, &
394 : 0 : Pawrad,Pawtab,Dtset%upawu,Dtset%usedmft,Dtset%useexexch,Dtset%usepawu,dtset%ucrpa)
395 : :
396 [ # # ]: 0 : if (my_rank == master) call pawtab_print(Pawtab)
397 : :
398 : : ! Get Pawrhoij from the header of the WFK file.
399 : : !call pawrhoij_copy(wfk_hdr%pawrhoij, KS_Pawrhoij)
400 : :
401 : : ! Evaluate form factor of radial part of phi.phj-tphi.tphj.
402 : 0 : gw_gsq = max(Dtset%ecutsigx, Dtset%ecuteps) / (two*pi**2)
403 : :
404 : : ! Set up q-grid, make qmax 20% larger than largest expected.
405 [ # # # # : 0 : ABI_MALLOC(nq_spl, (Psps%ntypat))
# # # # #
# # # ]
406 [ # # # # : 0 : ABI_MALLOC(qmax, (Psps%ntypat))
# # # # #
# # # ]
407 [ # # ]: 0 : qmax = SQRT(gw_gsq)*1.2d0
408 [ # # ]: 0 : nq_spl = Psps%mqgrid_ff
409 : : ! write(std_out,*)"using nq_spl",nq_spl,"qmax=",qmax
410 : :
411 : 0 : rhoxsp_method = 1 ! Arnaud-Alouani (default in sigma)
412 : : !rhoxsp_method = 2 ! Shiskin-Kresse
413 [ # # ]: 0 : if (Dtset%pawoptosc /= 0) rhoxsp_method = Dtset%pawoptosc
414 : :
415 [ # # # # : 0 : ABI_MALLOC(paw_pwff, (psps%ntypat))
# # # # #
# # # # #
# # # # ]
416 : 0 : call pawpwff_init(Paw_pwff, rhoxsp_method, nq_spl, qmax, cryst%gmet, pawrad, pawtab, psps)
417 : :
418 [ # # ]: 0 : ABI_FREE(nq_spl)
419 [ # # ]: 0 : ABI_FREE(qmax)
420 : :
421 : : ! Variables/arrays related to the fine FFT grid
422 [ # # # # : 0 : ABI_CALLOC(ks_nhat, (nfftf, Dtset%nspden))
# # # # #
# # # # #
# # # # #
# ]
423 : :
424 [ # # # # : 0 : ABI_MALLOC(pawfgrtab, (cryst%natom))
# # # # #
# # # #
# ]
425 : 0 : call pawtab_get_lsize(pawtab, l_size_atm, cryst%natom, cryst%typat)
426 : :
427 : : cplex = 1
428 : 0 : call pawfgrtab_init(pawfgrtab, cplex, l_size_atm, dtset%nspden, dtset%typat)
429 [ # # ]: 0 : ABI_FREE(l_size_atm)
430 : 0 : compch_fft=greatest_real
431 [ # # ]: 0 : usexcnhat = maxval(Pawtab(:)%usexcnhat)
432 : : ! * 0 if Vloc in atomic data is Vbare (Blochl's formulation)
433 : : ! * 1 if Vloc in atomic data is VH(tnzc) (Kresse's formulation)
434 : 0 : call wrtout(std_out, sjoin(' using usexcnhat: ', itoa(usexcnhat)))
435 : : !
436 : : ! Identify parts of the rectangular grid where the density has to be calculated
437 : 0 : optcut = 0; optgr0 = Dtset%pawstgylm; optgr1 = 0; optgr2 = 0; optrad = 1 - Dtset%pawstgylm
438 [ # # ]: 0 : if (Dtset%pawcross==1) optrad=1
439 [ # # # # ]: 0 : if (Dtset%xclevel==2.and.usexcnhat>0) optgr1=Dtset%pawstgylm
440 : :
441 : : call nhatgrid(cryst%atindx1, cryst%gmet, cryst%natom, cryst%natom, cryst%nattyp, ngfftf, cryst%ntypat,&
442 : 0 : optcut,optgr0,optgr1,optgr2,optrad,Pawfgrtab,Pawtab,Cryst%rprimd,Cryst%typat,Cryst%ucvol,Cryst%xred)
443 : :
444 : 0 : call pawfgrtab_print(Pawfgrtab,Cryst%natom,unit=std_out,prtvol=Dtset%pawprtvol)
445 : :
446 : : else
447 [ # # ]: 0 : ABI_MALLOC(Paw_pwff, (0))
448 [ # # ]: 0 : ABI_MALLOC(Pawfgrtab, (0))
449 : : end if ! End of PAW Initialization
450 : :
451 : : ! Allocate these arrays anyway, since they are passed to subroutines.
452 [ # # # # : 0 : ABI_MALLOC_IFNOT(ks_nhat, (nfftf, 0))
# # # # #
# # # ]
453 [ # # # # : 0 : ABI_MALLOC_IFNOT(dijexc_core, (1, 1, 0))
# # ]
454 : :
455 : : !=============================================
456 : : ! Read density and compare crystal structures
457 : : ! ============================================
458 [ # # # # : 0 : ABI_MALLOC(ks_rhor, (nfftf, dtset%nspden))
# # # # #
# # # # #
# # ]
459 : :
460 : : call read_rhor(den_path, cplex1, dtset%nspden, nfftf, ngfftf, dtset%usepaw, mpi_enreg_seq, ks_rhor, &
461 : 0 : den_hdr, ks_pawrhoij, comm, allow_interp=.False., want_varname="density")
462 : :
463 [ # # # # : 0 : den_cryst = den_hdr%get_crystal()
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
464 [ # # ]: 0 : if (cryst%compare(den_cryst, header=" Comparing input crystal with DEN crystal") /= 0) then
465 : 0 : ABI_ERROR("Crystal structure from input and from DEN file do not agree! Check messages above!")
466 : : end if
467 : : ! Get fermie from the GS calculation.
468 : : ! NB: It might understimate the real fermi level, especially if the den was computed on a shifted k-mesh
469 : : ! at present it's only used to implement pseudobands
470 : 0 : gs_fermie = den_hdr%fermie
471 : 0 : call den_cryst%free(); call den_hdr%free()
472 : :
473 [ # # # # : 0 : ABI_MALLOC(ks_taur, (nfftf, dtset%nspden * dtset%usekden))
# # # # #
# # # # #
# # ]
474 [ # # ]: 0 : if (dtset%usekden == 1) then
475 : : call read_rhor(kden_path, cplex1, dtset%nspden, nfftf, ngfftf, 0, mpi_enreg_seq, ks_taur, &
476 : 0 : kden_hdr, ks_pawrhoij, comm, allow_interp=.False., want_varname="kinedr")
477 : 0 : call kden_hdr%free()
478 : 0 : call prtrhomxmn(std_out, mpi_enreg_seq, nfftf, ngfftf, dtset%nspden, 1, ks_taur, optrhor=1, ucvol=cryst%ucvol)
479 : : end if
480 : :
481 : : !========================================
482 : : !==== Additional computation for PAW ====
483 : : !========================================
484 : 0 : nhatgrdim = 0
485 [ # # ]: 0 : if (dtset%usepaw == 1) then
486 : : ! Calculate the compensation charge nhat.
487 [ # # ]: 0 : if (Dtset%xclevel==2) nhatgrdim = usexcnhat * Dtset%pawnhatxc
488 : 0 : cplex = 1; ider = 2 * nhatgrdim; izero = 0
489 [ # # ]: 0 : if (nhatgrdim > 0) then
490 [ # # # # : 0 : ABI_MALLOC(ks_nhatgr,(nfftf,Dtset%nspden,3*nhatgrdim))
# # # # #
# # # # #
# # # # #
# # # ]
491 : : end if
492 [ # # ]: 0 : if (nhatgrdim == 0) then
493 [ # # # # ]: 0 : ABI_MALLOC(ks_nhatgr,(0,0,0))
494 : : end if
495 : :
496 : : call pawmknhat(compch_fft,cplex,ider,idir0,ipert0,izero,Cryst%gprimd,&
497 : : Cryst%natom,Cryst%natom,nfftf,ngfftf,nhatgrdim,Dtset%nspden,Cryst%ntypat,Pawang,&
498 : : Pawfgrtab,ks_nhatgr,ks_nhat,KS_Pawrhoij,KS_Pawrhoij,Pawtab,k0,Cryst%rprimd,&
499 : 0 : Cryst%ucvol,dtset%usewvl,Cryst%xred)
500 : :
501 : : ! === Evaluate onsite energies, potentials, densities ===
502 : : ! Initialize variables/arrays related to the PAW spheres.
503 : : ! Initialize also lmselect (index of non-zero LM-moments of densities).
504 [ # # # # : 0 : ABI_MALLOC(KS_paw_ij, (Cryst%natom))
# # # # #
# # # # #
# # # # ]
505 [ # # ]: 0 : has_dijso = Dtset%pawspnorb; has_dijU = merge(0, 1, Dtset%usepawu == 0)
506 : :
507 : 0 : call paw_ij_nullify(KS_paw_ij)
508 : : call paw_ij_init(KS_paw_ij,cplex,Dtset%nspinor,Dtset%nsppol,&
509 : : Dtset%nspden,Dtset%pawspnorb,Cryst%natom,Cryst%ntypat,Cryst%typat,Pawtab,&
510 : : has_dij=1,has_dijhartree=1,has_dijhat=1,has_dijxc=1,has_dijxc_hat=1,has_dijxc_val=1,&
511 : : has_dijso=has_dijso,has_dijU=has_dijU,has_exexch_pot=1,has_pawu_occ=1, &
512 : 0 : has_dijfock=dtset%usefock)
513 : :
514 : 0 : nkxc1 = 0
515 [ # # # # : 0 : ABI_MALLOC(KS_paw_an, (Cryst%natom))
# # # # #
# # # # #
# # # # ]
516 : 0 : call paw_an_nullify(KS_paw_an)
517 : 0 : usevxctau_paw=pawxc_get_usekden(dtset%ixc)
518 : : call paw_an_init(KS_paw_an,Cryst%natom,Cryst%ntypat,nkxc1,0,Dtset%nspden,&
519 : 0 : cplex,Dtset%pawxcdev,Cryst%typat,Pawang,Pawtab,has_vxc=1,has_vxcval=1,has_vxctau=usevxctau_paw)
520 : :
521 : : ! Calculate onsite vxc with and without core charge.
522 : 0 : nzlmopt=-1; option=0; compch_sph=greatest_real
523 : : call pawdenpot(compch_sph,el_temp,Cryst%gprimd,ipert0,Dtset%ixc,Cryst%natom,Cryst%natom,Dtset%nspden,&
524 : : Cryst%ntypat,Dtset%nucdipmom,nzlmopt,option,KS_Paw_an,KS_Paw_an,KS_energies%paw,KS_paw_ij,&
525 : : Pawang,Dtset%pawprtvol,Pawrad,KS_Pawrhoij,Dtset%pawspnorb,&
526 : : Pawtab,Dtset%pawxcdev,Dtset%spnorbscl,Dtset%xclevel,Dtset%xc_denpos,Dtset%xc_taupos,&
527 : 0 : Cryst%xred,Cryst%ucvol,Psps%znuclpsp,Dtset%spinaxis)
528 : :
529 : : else
530 [ # # # # ]: 0 : ABI_MALLOC(ks_nhatgr, (0, 0, 0))
531 [ # # # # ]: 0 : ABI_MALLOC(ks_paw_ij, (0))
532 [ # # # # ]: 0 : ABI_MALLOC(ks_paw_an, (0))
533 : : end if ! PAW
534 : :
535 : : !call test_charge(nfftf,ks_ebands%nelect,Dtset%nspden,ks_rhor,Cryst%ucvol,&
536 : : ! Dtset%usepaw,usexcnhat,Pawfgr%usefinegrid,compch_sph,compch_fft,drude_plsmf)
537 : :
538 : : ! For PAW, add the compensation charge on the FFT mesh, then get rho(G).
539 : : ! NB: ks_nhat is already included in the density stored on file so we don't need to add it.to ks_rhor
540 : : !if (dtset%usepaw==1) ks_rhor = ks_rhor + ks_nhat
541 : :
542 : : ! TODO: Overloaded interface with units or just change the API to accept units
543 : 0 : call prtrhomxmn(std_out, mpi_enreg_seq, nfftf, ngfftf, dtset%nspden, 1, ks_rhor, ucvol=cryst%ucvol)
544 : 0 : call prtrhomxmn(ab_out, mpi_enreg_seq, nfftf, ngfftf, dtset%nspden, 1, ks_rhor, ucvol=cryst%ucvol)
545 : :
546 [ # # ]: 0 : if (dtset%usekden==1) then
547 : 0 : call prtrhomxmn(std_out,MPI_enreg_seq,nfftf,ngfftf,Dtset%nspden,1,ks_taur,optrhor=1,ucvol=cryst%ucvol)
548 : 0 : call prtrhomxmn(ab_out,MPI_enreg_seq,nfftf,ngfftf,Dtset%nspden,1,ks_taur,optrhor=1,ucvol=cryst%ucvol)
549 : : end if
550 : :
551 : : ! FFT n(r) --> n(g)
552 [ # # # # : 0 : ABI_MALLOC(ks_rhog, (2, nfftf))
# # # # #
# # # ]
553 : 0 : call fourdp(cplex1, ks_rhog, ks_rhor(:, 1), -1, mpi_enreg_seq, nfftf, 1, ngfftf, 0)
554 : :
555 : : ! Compute structure factor phases and large sphere cutoff
556 [ # # # # : 0 : ABI_MALLOC(ph1d, (2, 3 * (2 * Dtset%mgfft + 1) * Cryst%natom))
# # # # #
# # # # #
# # ]
557 [ # # # # : 0 : ABI_MALLOC(ph1df, (2, 3 * (2 * mgfftf + 1) * Cryst%natom))
# # # # #
# # # # #
# # ]
558 : :
559 : 0 : call getph(cryst%atindx, cryst%natom, ngfftc(1), ngfftc(2), ngfftc(3), ph1d, cryst%xred)
560 : :
561 [ # # # # ]: 0 : if (psps%usepaw == 1 .and. pawfgr%usefinegrid == 1) then
562 : 0 : call getph(cryst%atindx, cryst%natom, ngfftf(1), ngfftf(2), ngfftf(3), ph1df, cryst%xred)
563 : : else
564 [ # # # # ]: 0 : ph1df(:,:)=ph1d(:,:)
565 : : end if
566 : :
567 : : ! The following steps have been gathered in the setvtr routine:
568 : : ! - get Ewald energy and Ewald forces
569 : : ! - compute local ionic pseudopotential vpsp
570 : : ! - eventually compute 3D core electron density xccc3d
571 : : ! - eventually compute vxc and vhartr
572 : : ! - set up ks_vtrial
573 : : !
574 : : !*******************************************************************
575 : : !**** NOTE THAT HERE Vxc CONTAINS THE CORE-DENSITY CONTRIBUTION ****
576 : : !*******************************************************************
577 : :
578 : 0 : ngrvdw = 0
579 [ # # ]: 0 : ABI_MALLOC(grvdw, (3, ngrvdw))
580 [ # # # # : 0 : ABI_MALLOC(grchempottn, (3, cryst%natom))
# # # # #
# # # ]
581 [ # # # # : 0 : ABI_MALLOC(grewtn, (3, cryst%natom))
# # # # ]
582 : 0 : nkxc = 0
583 [ # # ]: 0 : if (dtset%nspden == 1) nkxc = 2
584 [ # # ]: 0 : if (dtset%nspden >= 2) nkxc = 3 ! check GGA and spinor, quite a messy part!!!
585 : : ! In case of MGGA, fxc and kxc are not available and we dont need them (for now ...)
586 [ # # # # ]: 0 : if (dtset%ixc < 0 .and. libxc_functionals_ismgga()) nkxc = 0
587 [ # # ]: 0 : if (nkxc /= 0) then
588 [ # # # # : 0 : ABI_MALLOC(kxc, (nfftf, nkxc))
# # # # #
# # # # #
# # ]
589 : : end if
590 : :
591 [ # # ]: 0 : n3xccc = 0; if (psps%n1xccc /= 0) n3xccc = nfftf
592 [ # # # # : 0 : ABI_MALLOC(xccc3d, (n3xccc))
# # # # #
# # # ]
593 [ # # # # : 0 : ABI_MALLOC(ks_vhartr, (nfftf))
# # # # #
# # # ]
594 [ # # # # : 0 : ABI_MALLOC(ks_vtrial, (nfftf, dtset%nspden))
# # # # #
# # # # #
# # ]
595 [ # # # # : 0 : ABI_MALLOC(vpsp, (nfftf))
# # # # ]
596 [ # # # # : 0 : ABI_MALLOC(ks_vxc, (nfftf, dtset%nspden))
# # # # #
# # # #
# ]
597 : :
598 : : ! TODO: I don't think direct diago can be used with mega-GGA due to the functional derivative wrt KS states.
599 : : ! TB-BK should be OK though.
600 : :
601 : : !usevxctau=merge(1,0,xc_need_kden(dtset%ixc))
602 : : !ABI_MALLOC(ks_vxctau, (nfftf, dtset%nspden * usevxctau))
603 : : !ABI_MALLOC(xcctau3d, (n3xccc * dtset%usekden))
604 : : !ABI_FREE(ks_vxctau)
605 : : !ABI_FREE(xcctau3d)
606 : :
607 : 0 : optene = 4; moved_atm_inside = 0; moved_rhor = 0; istep = 1
608 : :
609 : : call setvtr(Cryst%atindx1,Dtset,KS_energies,cryst%gmet,cryst%gprimd,grchempottn,grewtn,grvdw,gsqcutf_eff,&
610 : : istep,kxc,mgfftf,moved_atm_inside,moved_rhor,MPI_enreg_seq,&
611 : : Cryst%nattyp,nfftf,ngfftf,ngrvdw,ks_nhat,ks_nhatgr,nhatgrdim,nkxc,Cryst%ntypat,Psps%n1xccc,n3xccc,&
612 : : optene,Pawang,Pawrad,KS_pawrhoij,Pawtab,ph1df,Psps,ks_rhog,ks_rhor,cryst%rmet,cryst%rprimd,strsxc,&
613 : : Cryst%ucvol,usexcnhat,ks_vhartr,vpsp,ks_vtrial,ks_vxc,vxcavg,Wvl,xccc3d,Cryst%xred, &
614 : 0 : taur=ks_taur) !xcctau3d=xcctau3d, vxctau=ks_vxctau)
615 : :
616 [ # # ]: 0 : ABI_FREE(grvdw)
617 [ # # ]: 0 : ABI_FREE(grchempottn)
618 [ # # ]: 0 : ABI_FREE(grewtn)
619 : :
620 : : !============================
621 : : !==== Compute KS PAW Dij ====
622 : : !============================
623 [ # # ]: 0 : if (dtset%usepaw == 1) then
624 : 0 : call timab(561,1,tsec)
625 : :
626 : : ! Calculate the unsymmetrized Dij.
627 : : call pawdij(cplex,Dtset%enunit,Cryst%gprimd,ipert0,&
628 : : Cryst%natom,Cryst%natom,nfftf,ngfftf(1)*ngfftf(2)*ngfftf(3),&
629 : : Dtset%nspden,Cryst%ntypat,KS_paw_an,KS_paw_ij,Pawang,Pawfgrtab,&
630 : : Dtset%pawprtvol,Pawrad,KS_Pawrhoij,Dtset%pawspnorb,Pawtab,Dtset%pawxcdev,&
631 : : k0,Dtset%spnorbscl,Cryst%ucvol,dtset%cellcharge(1),ks_vtrial,&
632 : : ks_vxc,Cryst%xred,Dtset%znucl,&
633 : 0 : nucdipmom=Dtset%nucdipmom,spinaxis=Dtset%spinaxis)
634 : :
635 : : ! Symmetrize KS Dij
636 : : call symdij_all(Cryst%gprimd,Cryst%indsym,ipert0,&
637 : : Cryst%natom,Cryst%natom,Cryst%nsym,Cryst%ntypat,KS_paw_ij,Pawang,&
638 : 0 : Dtset%pawprtvol,Pawtab,Cryst%rprimd,Cryst%symafm,Cryst%symrec)
639 : :
640 : : ! Output the pseudopotential strengths Dij and the augmentation occupancies Rhoij.
641 : 0 : call pawprt(Dtset,Cryst%natom,KS_paw_ij,KS_Pawrhoij,Pawtab)
642 : 0 : call timab(561,2,tsec)
643 : : end if
644 : :
645 : 0 : call pstat_proc%print(_PSTAT_ARGS_)
646 : 0 : call cwtime_report(" prepare gwr_driver_init", cpu, wall, gflops)
647 : :
648 [ # # ]: 0 : if (string_in(dtset%gwr_task, "HDIAGO, HDIAGO_FULL, CC4S, CC4S_FULL")) then
649 : : ! ==========================================
650 : : ! Direct diagonalization of the Hamiltonian
651 : : ! ==========================================
652 [ # # # # : 0 : ABI_MALLOC(nband_iks, (dtset%nkpt, dtset%nsppol))
# # # # #
# # # # #
# # ]
653 [ # # # # : 0 : ABI_MALLOC(npwarr_ik, (dtset%nkpt))
# # # # #
# # # ]
654 [ # # # # : 0 : ABI_MALLOC(istwfk_ik, (dtset%nkpt))
# # # # ]
655 [ # # ]: 0 : istwfk_ik = 1
656 : :
657 : : ! Compute npw_k from ecut so that we can update the header and redefine %mpw
658 [ # # ]: 0 : do ik_ibz=1,dtset%nkpt
659 : : !if (dtset%istwfk(ik_ibz) == 2) istwfk_ik(ik_ibz) = 2 ! TODO: istwkf 2 is not yet supported.
660 [ # # ]: 0 : call get_kg(dtset%kptns(:,ik_ibz), istwfk_ik(ik_ibz), dtset%ecut, cryst%gmet, npwarr_ik(ik_ibz), gvec_)
661 [ # # ]: 0 : ABI_FREE(gvec_)
662 : : end do
663 [ # # ]: 0 : dtset%mpw = maxval(npwarr_ik)
664 : :
665 : : ! CC4S does not need to output the WFK file.
666 : 0 : write_wfk = string_in(dtset%gwr_task, "HDIAGO, HDIAGO_FULL")
667 : :
668 : : ! Use input nband or min of npwarr_ik to set the number of bands.
669 [ # # # # : 0 : if (string_in(dtset%gwr_task, "HDIAGO, CC4S")) nband_iks(:,:) = maxval(dtset%nband)
# # # # ]
670 [ # # # # : 0 : if (string_in(dtset%gwr_task, "HDIAGO_FULL, CC4S_FULL")) nband_iks(:,:) = minval(npwarr_ik)
# # # # ]
671 : 0 : cc4s_task = string_in(dtset%gwr_task, "CC4S, CC4S_FULL")
672 [ # # ]: 0 : if (cc4s_task) then
673 [ # # ]: 0 : ABI_CHECK_IEQ(dtset%nkpt, 1, "CC4S interface does not support more than one k-point.")
674 : : end if
675 : :
676 : : ! Build header with new npwarr and nband.
677 : 0 : call owfk_ebands%from_dtset(dtset, npwarr_ik, nband=nband_iks)
678 [ # # # # : 0 : owfk_ebands%eig = zero
# # ]
679 [ # # # # : 0 : owfk_ebands%istwfk = istwfk_ik
# # # # ]
680 : : !print *, "owfk_ebands%npwarr:", owfk_ebands%npwarr; stop
681 : 0 : call owfk_hdr%init(owfk_ebands, codvsn, dtset, pawtab, 0, psps, wvl%descr)
682 : :
683 : : ! Change the value of istwfk taken from dtset and set the Fermie level from gs_fermie.
684 [ # # # # : 0 : ABI_REMALLOC(owfk_hdr%istwfk, (dtset%nkpt))
# # # # #
# # # # #
# # ]
685 [ # # ]: 0 : owfk_hdr%istwfk(:) = istwfk_ik
686 : 0 : owfk_hdr%fermie = gs_fermie
687 : :
688 : : ! Build MPI pools to distribute (kpt, spin).
689 : : ! Try to get rectangular grids in each pool to improve efficiency in slk diago.
690 [ # # ]: 0 : rectangular = .True.; if (dtset%nkpt == 1) rectangular = .False.
691 : 0 : with_pools = .True.
692 [ # # # # : 0 : if (any(dtset%gwr_np_kgts /= 0) .and. (nprocs == dtset%gwr_np_kgts(2))) then
# # # # ]
693 : 0 : with_pools = .False.; call wrtout(std_out, " Deactivating pools in HDIAGO")
694 : : end if
695 : : !with_pools = .False.
696 : 0 : call diago_pool%from_dims(dtset%nkpt, dtset%nsppol, comm, with_pools, rectangular=rectangular)
697 [ # # # # : 0 : diago_info = zero
# # ]
698 : :
699 : : ! TODO: Build hyb descriptor with hybrid orbitals from WFK file.
700 : 0 : cc4s_from_wfk = .False.
701 : : if (dtset%usefock == 1 .and. cc4s_from_wfk) then
702 : : call hyb%from_wfk_file(cryst, dtfil, dtset, psps, pawtab, ngfftc, diago_pool, comm)
703 : : end if
704 : :
705 [ # # ]: 0 : if (write_wfk) then
706 : : ! Master writes the Abinit header and the Fortran record markers
707 [ # # ]: 0 : out_path = dtfil%fnameabo_wfk; if (dtset%iomode == IO_MODE_ETSF) out_path = nctk_ncify(out_path)
708 : 0 : iomode__ = iomode_from_fname(out_path)
709 : 0 : call wrtout(std_out, sjoin(" Writing wavefunctions to file:", out_path))
710 [ # # ]: 0 : if (my_rank == master) then
711 : 0 : call owfk%open_write(owfk_hdr, out_path, 0, iomode__, get_unit(), xmpi_comm_self, write_hdr=.True., write_frm=.True.)
712 : 0 : call owfk%close()
713 : : end if
714 : 0 : call xmpi_barrier(comm)
715 : : end if
716 : :
717 : : ! Build H_k(g,g') for each k-point and spin and diagonalize the Hamiltonian with Scalapack/ELPA.
718 [ # # ]: 0 : do spin=1,dtset%nsppol
719 [ # # ]: 0 : do ik_ibz=1,dtset%nkpt
720 [ # # ]: 0 : if (.not. diago_pool%treats(ik_ibz, spin)) cycle
721 : 0 : nband_k = nband_iks(ik_ibz, spin)
722 : :
723 [ # # ]: 0 : if (dtset%usefock == 1 .and. .not. cc4s_from_wfk) then
724 : 0 : call wrtout(units, "Reading ugb datatype from WFK file")
725 [ # # ]: 0 : ABI_CHECK(.not. string_in(dtset%gwr_task, "CC4S_FULL"), "CC4S_FULL cannot be used with Fock, please specify nband")
726 : : call ugb%from_wfk_file(ik_ibz, spin, istwfk_ik(ik_ibz), dtset%kptns(:,ik_ibz), nband_k, dtset, &
727 [ # # ]: 0 : dtfil, cryst, eig_k, diago_pool%comm%value)
728 : :
729 : : else
730 : 0 : call cwtime(diago_cpu, diago_wall, diago_gflops, "start")
731 : : call ugb%from_diago(spin, istwfk_ik(ik_ibz), dtset%kptns(:,ik_ibz), dtset%ecut, gs_fermie, nband_k, ngfftc, nfftf, &
732 [ # # ]: 0 : dtset, pawtab, pawfgr, ks_paw_ij, cryst, psps, ks_vtrial, eig_k, hyb, diago_pool%comm%value)
733 : 0 : call cwtime(diago_cpu, diago_wall, diago_gflops, "stop")
734 : :
735 [ # # ]: 0 : if (diago_pool%comm%me == 0) diago_info(1, ik_ibz, spin) = diago_wall
736 : 0 : call cwtime(diago_cpu, diago_wall, diago_gflops, "start")
737 : : end if
738 : :
739 [ # # ]: 0 : owfk_ebands%eig(1:nband_k, ik_ibz, spin) = eig_k(1:nband_k)
740 : :
741 [ # # ]: 0 : if (write_wfk) then
742 : : ! occupancies are set to zero. Client code is responsible for recomputing occ and fermie when reading this WFK.
743 : 0 : call wrtout(std_out, sjoin(" Writing kpoint ik_ibz:", itoa(ik_ibz), ", spin: ", itoa(spin), " to disk ..."))
744 [ # # # # : 0 : ABI_CALLOC(occ_k, (nband_k))
# # # # #
# # # #
# ]
745 [ # # ]: 0 : color = merge(1, 0, ugb%my_nband > 0)
746 : 0 : call xmpi_comm_split(diago_pool%comm%value, color, diago_pool%comm%me, io_comm, ierr)
747 : : call wrtout(std_out, sjoin(" Number of MPI procs involved in IO operation:", &
748 : 0 : itoa(xmpi_comm_size(io_comm)), "/", itoa(diago_pool%comm%nproc)))
749 : :
750 [ # # ]: 0 : if (ugb%my_nband > 0) then
751 [ # # # # : 0 : ABI_CHECK(all(shape(ugb%cg_k) == [2, ugb%npwsp, ugb%my_nband]), "Wrong shape")
# # ]
752 [ # # ]: 0 : ABI_CHECK_IEQ(ugb%npw_k, owfk_hdr%npwarr(ik_ibz), "Wrong npw_k")
753 [ # # # # : 0 : call c_f_pointer(c_loc(ugb%cg_k), cg_k_ptr, shape=[2, ugb%npwsp * ugb%my_nband])
# # # # #
# # # # #
# # # # #
# ]
754 : :
755 : : ! Reopen file inside io_comm.
756 : 0 : call owfk%open_write(owfk_hdr, out_path, 0, iomode__, get_unit(), io_comm, write_hdr=.False., write_frm=.False.)
757 : : !call wrtout(std_out, "After owfk%open_write")
758 : :
759 : : ! Write my bands.
760 : : !sc_mode = merge(xmpio_single, xmpio_collective, ugb%has_idle_procs)
761 : : !sc_mode = xmpio_collective
762 : 0 : sc_mode = xmpio_single
763 : : call owfk%write_band_block([ugb%my_bstart, ugb%my_bstop], ik_ibz, spin, sc_mode, &
764 [ # # ]: 0 : kg_k=ugb%kg_k, cg_k=cg_k_ptr, eig_k=owfk_ebands%eig(:, ik_ibz, spin), occ_k=occ_k)
765 : 0 : call owfk%close()
766 : : end if
767 : 0 : call xmpi_comm_free(io_comm)
768 [ # # ]: 0 : ABI_FREE(occ_k)
769 : : end if
770 : :
771 : 0 : call cwtime(diago_cpu, diago_wall, diago_gflops, "stop")
772 [ # # # # ]: 0 : if (diago_pool%comm%me == 0) diago_info(2:3, ik_ibz, spin) = [diago_wall, dble(diago_pool%comm%nproc)]
773 : :
774 : : ! Compute and write matrix elements required by CC4S
775 [ # # ]: 0 : if (cc4s_task) call cc4s_gamma(spin, ik_ibz, dtset, dtfil, cryst, owfk_ebands, psps, pawtab, paw_pwff, ugb)
776 : :
777 [ # # ]: 0 : ABI_FREE(eig_k)
778 : 0 : call ugb%free()
779 : : end do ! ik_ibz
780 : : end do ! spin
781 : 0 : call wrtout(std_out, " Direct diago completed by this MPI pool. Other pools might take more time if k != 0")
782 : :
783 : 0 : call xmpi_sum_master(diago_info, master, comm, ierr)
784 [ # # ]: 0 : if (my_rank == master) then
785 [ # # ]: 0 : do spin=1,dtset%nsppol
786 [ # # ]: 0 : do ik_ibz=1,dtset%nkpt
787 : 0 : associate (info => diago_info(:, ik_ibz, spin))
788 : 0 : write(std_out, "(2(a,i0),5a,i0)") " ik_ibz: ", ik_ibz, ", spin: ", spin, &
789 [ # # # # ]: 0 : ", diago_wall: ", trim(sec2str(info(1))), ", io_wall: ", trim(sec2str(info(2))), ", nprocs: ", int(info(3))
790 : : end associate
791 : : end do
792 : : end do
793 : : end if
794 : :
795 : : ! Collect eigenvalues for the different k-points/spins.
796 [ # # ]: 0 : do spin=1,dtset%nsppol
797 [ # # ]: 0 : do ik_ibz=1,dtset%nkpt
798 [ # # # # : 0 : if (diago_pool%treats(ik_ibz, spin) .and. diago_pool%comm%me /= 0) owfk_ebands%eig(:, ik_ibz, spin) = zero
# # ]
799 : : end do
800 : : end do
801 : 0 : call xmpi_sum(owfk_ebands%eig, comm, ierr)
802 : :
803 : 0 : call owfk_ebands%update_occ(dtset%spinmagntarget, prtvol=dtset%prtvol, fermie_to_zero=.False.)
804 : :
805 [ # # ]: 0 : if (my_rank == master) then
806 [ # # # # ]: 0 : if (write_wfk .and. iomode__ == IO_MODE_ETSF) then
807 [ # # ]: 0 : NCF_CHECK(owfk_ebands%ncwrite_path(cryst, out_path))
808 : : end if
809 : 0 : call owfk_ebands%print_gaps(units, header="KS gaps after direct diagonalization")
810 [ # # ]: 0 : if (cc4s_task) call cc4s_write_eigens(owfk_ebands, dtfil)
811 : : end if
812 : :
813 [ # # ]: 0 : ABI_FREE(npwarr_ik)
814 [ # # ]: 0 : ABI_FREE(istwfk_ik)
815 [ # # ]: 0 : ABI_FREE(nband_iks)
816 : 0 : call owfk_hdr%free(); call owfk_ebands%free(); call hyb%free(); call diago_pool%free()
817 : :
818 [ # # ]: 0 : else if (string_in(dtset%gwr_task, "CC4S_FROM_WFK")) then
819 : : ! Read orbitals from an external WFK file and produce output files for CC4S.
820 : :
821 : : ! Construct crystal and ks_ebands from the GS WFK file.
822 [ # # # # : 0 : tmp_ebands = wfk_read_ebands(wfk_path, comm, out_hdr=wfk_hdr)
# # # # #
# # # # #
# # # # #
# # # ]
823 [ # # # # : 0 : ks_ebands = tmp_ebands%chop(1, maxval(dtset%nband))
# # # # #
# # # # #
# # # # #
# # # #
# ]
824 : :
825 : : ! Make sure that ef is inside the gap if semiconductor.
826 : : !call ks_ebands%update_occ(dtset%spinmagntarget, prtvol=dtset%prtvol, fermie_to_zero=.True.)
827 : :
828 : 0 : call tmp_ebands%free()
829 : 0 : call wfk_hdr%vs_dtset(dtset)
830 : :
831 [ # # # # : 0 : wfk_cryst = wfk_hdr%get_crystal()
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
832 [ # # ]: 0 : if (cryst%compare(wfk_cryst, header=" Comparing input crystal with WFK crystal") /= 0) then
833 : 0 : ABI_ERROR("Crystal structure from input and from WFK file do not agree! Check messages above!")
834 : : end if
835 : 0 : call wfk_cryst%free()
836 : :
837 [ # # ]: 0 : if (my_rank == master) call cc4s_write_eigens(ks_ebands, dtfil)
838 : :
839 : : ! Build MPI pools to distribute (kpt, spin).
840 : 0 : with_pools = .True.
841 [ # # # # : 0 : if (any(dtset%gwr_np_kgts /= 0) .and. (nprocs == dtset%gwr_np_kgts(2))) then
# # # # ]
842 : 0 : with_pools = .False.; call wrtout(std_out, " Deactivating pools in HDIAGO")
843 : : end if
844 : 0 : call diago_pool%from_dims(dtset%nkpt, dtset%nsppol, comm, with_pools, rectangular=.False.)
845 [ # # ]: 0 : ABI_CHECK_IEQ(dtset%nkpt, 1, "Only Gamma-point sampling is supported")
846 [ # # ]: 0 : ABI_CHECK_IEQ(dtset%nsppol, 1, "Only spin-unpolarized calculations are supported")
847 : :
848 [ # # ]: 0 : do spin=1,dtset%nsppol
849 [ # # ]: 0 : do ik_ibz=1,dtset%nkpt
850 [ # # ]: 0 : if (.not. diago_pool%treats(ik_ibz, spin)) cycle
851 : 0 : nband_k = dtset%nband(ik_ibz + (spin-1)*dtset%nkpt)
852 : : call ugb%from_wfk_file(ik_ibz, spin, dtset%istwfk(ik_ibz), dtset%kptns(:,ik_ibz), nband_k, dtset, &
853 [ # # ]: 0 : dtfil, cryst, eig_k, diago_pool%comm%value)
854 [ # # ]: 0 : ABI_FREE(eig_k)
855 : 0 : call cc4s_gamma(spin, ik_ibz, dtset, dtfil, cryst, ks_ebands, psps, pawtab, paw_pwff, ugb)
856 : 0 : call ugb%free()
857 : : end do
858 : : end do
859 : 0 : call wfk_hdr%free(); call ks_ebands%free(); call diago_pool%free()
860 : :
861 : : else
862 : : ! ====================================================
863 : : ! === This is the real GWR stuff once all is ready ===
864 : : ! ====================================================
865 [ # # ]: 0 : ABI_CHECK(dtset%usepaw == 0, "PAW in GWR not yet implemented.")
866 : 0 : read_wfk = .True.
867 : : if (read_wfk) then
868 [ # # ]: 0 : if (my_rank == master) then
869 [ # # ]: 0 : if (nctk_try_fort_or_ncfile(wfk_path, msg) /= 0) then
870 : 0 : ABI_ERROR(sjoin("Cannot find GS WFK file:", wfk_path, ". Error:", msg))
871 : : end if
872 : 0 : call wrtout(units, sjoin("- Reading GS states from WFK file:", wfk_path))
873 : : end if
874 : :
875 : : ! Broadcast filenames (needed because they might have been changed if we are using netcdf files)
876 : 0 : call xmpi_bcast(wfk_path, master, comm, ierr)
877 : :
878 : : ! Construct crystal and ks_ebands from the GS WFK file.
879 [ # # # # : 0 : tmp_ebands = wfk_read_ebands(wfk_path, comm, out_hdr=wfk_hdr)
# # # # #
# # # # #
# # # # #
# # # ]
880 [ # # # # : 0 : ks_ebands = tmp_ebands%chop(1, maxval(dtset%nband))
# # # # #
# # # # #
# # # # #
# # # #
# ]
881 : 0 : call tmp_ebands%free()
882 : 0 : call wfk_hdr%vs_dtset(dtset)
883 : :
884 [ # # # # : 0 : wfk_cryst = wfk_hdr%get_crystal()
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
885 [ # # ]: 0 : if (cryst%compare(wfk_cryst, header=" Comparing input crystal with WFK crystal") /= 0) then
886 : 0 : ABI_ERROR("Crystal structure from input and from WFK file do not agree! Check messages above!")
887 : : end if
888 : : !call wfk_cryst%print(header="crystal structure from WFK file")
889 : 0 : call wfk_cryst%free()
890 : :
891 : : ! Make sure that ef is inside the gap if semiconductor.
892 : 0 : call ks_ebands%update_occ(dtset%spinmagntarget, prtvol=dtset%prtvol, fermie_to_zero=.True.)
893 : :
894 : : ! Here we change the GS bands (Fermi level, scissors operator ...)
895 : : ! All the modifications to ebands should be done here.
896 : : !call ephtk_update_ebands(dtset, dtfil%filqpdatain, ks_ebands, "Ground state energies", comm)
897 : : end if
898 : 0 : call pstat_proc%print(_PSTAT_ARGS_)
899 : :
900 : 0 : call gwr%init(dtset, dtfil, cryst, psps, pawtab, ks_ebands, mpi_enreg_seq, comm)
901 [ # # ]: 0 : if (gwr%idle_proc) goto 100
902 : :
903 : : !=== Calculate Vxc(b1,b2,k,s)=<b1,k,s|v_{xc}|b2,k,s> for all the states included in GW ===
904 : : ! * This part is parallelized within wfd%comm since each node has all GW wavefunctions.
905 : : ! * Note that vH matrix elements are calculated using the true uncutted interaction.
906 : :
907 : 0 : rdm_update = dtset%gwr_task == "GAMMA_GW"
908 : :
909 : 0 : call KS_mflags%reset()
910 [ # # ]: 0 : if (rdm_update) then
911 : 0 : KS_mflags%has_hbare=1
912 : 0 : KS_mflags%has_kinetic=1
913 : : end if
914 : 0 : KS_mflags%has_vhartree=1
915 : 0 : KS_mflags%has_vxc =1
916 : 0 : KS_mflags%has_vxcval =1
917 [ # # ]: 0 : if (Dtset%usepawu /= 0 ) KS_mflags%has_vu = 1
918 [ # # ]: 0 : if (Dtset%useexexch /= 0) KS_mflags%has_lexexch = 1
919 [ # # # # ]: 0 : if (Dtset%usepaw==1 .and. Dtset%gw_sigxcore == 1) KS_mflags%has_sxcore = 1
920 : : ! off-diagonal elements only for SC on wavefunctions.
921 : 0 : KS_mflags%only_diago = 1
922 [ # # ]: 0 : if (rdm_update) KS_mflags%only_diago = 0
923 : :
924 : : ! Load wavefunctions for Sigma_nk in gwr%kcalc_wfd.
925 [ # # ]: 0 : call gwr%load_kcalc_wfd(wfk_path, tmp_kstab)
926 : :
927 : : ! Compute gwr%ks_me matrix elements.
928 [ # # ]: 0 : if (.not. string_in(dtset%gwr_task, "RPA_ENERGY")) then
929 : : ! FIXME: This routine allocates (nband, nband) matrices and should be rewritten!
930 : : call calc_vhxc_me(gwr%kcalc_wfd, ks_mflags, gwr%ks_me, cryst, dtset, nfftf, ngfftf, &
931 : : ks_vtrial, ks_vhartr, ks_vxc, psps, pawtab, ks_paw_an, pawang, pawfgrtab, ks_paw_ij, dijexc_core, &
932 : 0 : ks_rhor, usexcnhat, ks_nhat, ks_nhatgr, nhatgrdim, tmp_kstab, taur=ks_taur)
933 [ # # ]: 0 : if (my_rank == master) call gwr%ks_me%print(header="KS matrix elements", unit=std_out)
934 : : end if
935 : :
936 [ # # ]: 0 : ABI_FREE(tmp_kstab)
937 : :
938 : : if (read_wfk) then
939 : : ! Read wavefunctions from WFK file.
940 : 0 : call gwr%read_ugb_from_wfk(wfk_path)
941 : : else
942 : : ! Diagonalize H on the fly and
943 : : !call gwr%get_ugb_from_vtrial(ngfftf, ks_vtrial)
944 : : !gwr%wfk_hdr = ?
945 : : end if
946 : :
947 : : ! Now call high-level routines depending on gwr_task.
948 : 0 : select case (dtset%gwr_task)
949 : : case ("RPA_ENERGY")
950 : 0 : call gwr%rpa_energy()
951 : : case ("GAMMA_GW")
952 : 0 : call gwr%gamma_gw(nfftf, ngfftf, vpsp)
953 : : case ("CHI0")
954 : 0 : call gwr%run_chi0()
955 : : case ("G0W0")
956 : 0 : call gwr%run_g0w0()
957 : : case ("G0V")
958 : 0 : call gwr%build_sigxme(compute_qp=.True.)
959 : : case ("EGEW", "EGW0", "G0EW")
960 : 0 : call gwr%run_energy_scf()
961 : : case default
962 [ # # # # : 0 : ABI_ERROR(sjoin("Invalid value for gwr_task:", dtset%gwr_task))
# # # ]
963 : : end select
964 : : end if
965 : :
966 : : !=====================
967 : : !==== Free memory ====
968 : : !=====================
969 : 0 : 100 call xmpi_barrier(comm)
970 [ # # ]: 0 : ABI_FREE(ks_nhat)
971 [ # # ]: 0 : ABI_FREE(ks_nhatgr)
972 [ # # ]: 0 : ABI_FREE(dijexc_core)
973 : 0 : call pawfgr_destroy(pawfgr)
974 : :
975 [ # # ]: 0 : if (dtset%usepaw == 1) then
976 : : ! Deallocation for PAW.
977 : 0 : call pawrhoij_free(ks_pawrhoij)
978 [ # # # # : 0 : ABI_FREE(ks_pawrhoij)
# # # # #
# # # # #
# # # # ]
979 : 0 : call pawfgrtab_free(pawfgrtab)
980 : 0 : call paw_ij_free(ks_paw_ij)
981 [ # # # # : 0 : ABI_FREE(ks_paw_ij)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
982 : 0 : call paw_an_free(ks_paw_an)
983 : 0 : call pawpwff_free(Paw_pwff)
984 : : end if
985 : :
986 [ # # ]: 0 : ABI_FREE(ph1d)
987 [ # # ]: 0 : ABI_FREE(ph1df)
988 [ # # ]: 0 : ABI_FREE(ks_rhor)
989 [ # # ]: 0 : ABI_FREE(ks_rhog)
990 [ # # ]: 0 : ABI_FREE(ks_taur)
991 [ # # ]: 0 : ABI_FREE(kxc)
992 [ # # ]: 0 : ABI_FREE(xccc3d)
993 [ # # ]: 0 : ABI_FREE(ks_vhartr)
994 [ # # ]: 0 : ABI_FREE(ks_vtrial)
995 [ # # ]: 0 : ABI_FREE(vpsp)
996 [ # # ]: 0 : ABI_FREE(ks_vxc)
997 : : ! PAW stuff
998 [ # # # # : 0 : ABI_SFREE(paw_pwff)
# # # # ]
999 [ # # # # : 0 : ABI_SFREE(pawfgrtab)
# # # # #
# # # # #
# # # # #
# ]
1000 [ # # # # : 0 : ABI_SFREE(ks_paw_an)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
1001 : :
1002 : 0 : call cryst%free(); call wfk_hdr%free(); call ks_ebands%free(); call destroy_mpi_enreg(mpi_enreg_seq)
1003 : : #if defined FC_NVHPC
1004 : : call wrtout(units, "- Cannot deallocate gwr datatype if FC_NVHPC, DO NOT USE DATASETS!")
1005 : : #else
1006 : 0 : call gwr%free()
1007 : : #endif
1008 : :
1009 : 0 : call pstat_proc%print(_PSTAT_ARGS_)
1010 : :
1011 [ # # # # : 0 : end subroutine gwr_driver
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
1012 : : !!***
1013 : :
1014 : : !!****f* m_gwr_driver/cc4s_write_eigens
1015 : : !! NAME
1016 : : !! cc4s_write_eigens
1017 : : !!
1018 : : !! FUNCTION
1019 : : !! Write eigenvalues in CC4S format. Only master proc should call this routine.
1020 : : !!
1021 : : !! INPUTS
1022 : :
1023 : 0 : subroutine cc4s_write_eigens(ebands, dtfil)
1024 : :
1025 : : !Arguments ------------------------------------
1026 : : type(ebands_t),intent(in) :: ebands
1027 : : type(datafiles_type),intent(in) :: dtfil
1028 : :
1029 : : !Local variables-------------------------------
1030 : : integer :: unt, ik_ibz, spin, band, gap_err
1031 : : real(dp) :: my_fermie
1032 : : character(len=500) :: msg
1033 : : character(len=fnlen) :: filepath
1034 : 0 : type(gaps_t) :: ks_gaps
1035 : : ! *************************************************************************
1036 : :
1037 : 0 : ks_gaps = ebands%get_gaps(gap_err)
1038 [ # # ]: 0 : call ks_gaps%print([std_out], header="Kohn-Sham gaps and band edges from IBZ mesh")
1039 [ # # # # : 0 : if (any(ks_gaps%ierr /= 0)) then
# # ]
1040 : 0 : ABI_ERROR("Cannot compute gaps!")
1041 : : end if
1042 : :
1043 : : ! Make sure fermi level is within the gap. I know, the case nsppol = 2 is treated in a dirty way!
1044 : 0 : my_fermie = zero
1045 [ # # ]: 0 : do spin=1,ebands%nsppol
1046 : 0 : my_fermie = ks_gaps%vb_max(spin) + (ks_gaps%cb_min(spin) - ks_gaps%vb_max(spin)) / two
1047 : : end do
1048 : 0 : my_fermie = my_fermie / ebands%nsppol
1049 : 0 : call ks_gaps%free()
1050 : :
1051 : : ! See https://manuals.cc4s.org/user-manual/objects/EigenEnergies.html
1052 [ # # # # ]: 0 : filepath = trim(dtfil%filnam_ds(4))//'_EigenEnergies.yaml'
1053 : 0 : write(ab_out, "(3a)")ch10," Writing Eigenenergies metadata to file: ", trim(filepath)
1054 [ # # ]: 0 : if (open_file(filepath, msg, newunit=unt, access="stream", form="formatted", status="replace", action="write") /= 0) then
1055 : 0 : ABI_ERROR(msg)
1056 : : end if
1057 : 0 : write(unt,'(A)') 'version: 100'
1058 : 0 : write(unt,'(A)') 'type: Tensor'
1059 : 0 : write(unt,'(A)') 'scalarType: Real64'
1060 : 0 : write(unt,'(A)') 'dimensions:'
1061 : 0 : write(unt,'(A,I0)') '- length: ',ebands%mband * ebands%nkpt * ebands%nsppol
1062 : 0 : write(unt,'(A)') ' type: State'
1063 : 0 : write(unt,'(A)') 'elements:'
1064 : 0 : write(unt,'(A)') ' type: TextFile'
1065 : 0 : write(unt,'(A)') 'unit: 1.0 # Hartree units'
1066 : 0 : write(unt,'(A)') 'metaData:'
1067 : 0 : write(unt,'(A,E22.15)') ' fermiEnergy: ',my_fermie
1068 : 0 : write(unt,'(A)') ' energies:'
1069 : :
1070 [ # # ]: 0 : do spin=1,ebands%nsppol
1071 [ # # ]: 0 : do ik_ibz=1,ebands%nkpt
1072 [ # # ]: 0 : do band=1,ebands%nband(ik_ibz + (spin-1)*ebands%nkpt)
1073 : 0 : write(unt,"(a,e22.15)") ' - ',ebands%eig(band,ik_ibz,spin)
1074 : : end do
1075 : : end do
1076 : : end do
1077 : 0 : close(unt)
1078 : :
1079 [ # # # # ]: 0 : filepath = trim(dtfil%filnam_ds(4))//'_EigenEnergies.elements'
1080 : 0 : write(ab_out, "(3a)")ch10," Writing Eigenenergies to file: ", trim(filepath)
1081 [ # # ]: 0 : if (open_file(filepath, msg, newunit=unt, access="stream", form="formatted", status="replace", action="write") /= 0) then
1082 : 0 : ABI_ERROR(msg)
1083 : : end if
1084 : :
1085 [ # # ]: 0 : do spin=1,ebands%nsppol
1086 [ # # ]: 0 : do ik_ibz=1,ebands%nkpt
1087 [ # # ]: 0 : do band=1,ebands%nband(ik_ibz + (spin-1)*ebands%nkpt)
1088 : 0 : write(unt,"(e22.15)") ebands%eig(band,ik_ibz,spin)
1089 : : end do
1090 : : end do
1091 : : end do
1092 : :
1093 : 0 : close(unt)
1094 : :
1095 [ # # # # : 0 : end subroutine cc4s_write_eigens
# # # # #
# # # # #
# # ]
1096 : : !!***
1097 : :
1098 : : !!****f* m_gwr_driver/cc4s_gamma
1099 : : !! NAME
1100 : : !! cc4s_gamma
1101 : : !!
1102 : : !! FUNCTION
1103 : : !! Interface with CC4S code.
1104 : : !! Compute <b1,k|e^{-iGr}|b2,k> matrix elements and store them to disk
1105 : : !!
1106 : : !! INPUTS
1107 : :
1108 : 0 : subroutine cc4s_gamma(spin, ik_ibz, dtset, dtfil, cryst, ebands, psps, pawtab, paw_pwff, ugb)
1109 : :
1110 : : use m_numeric_tools, only : blocked_loop
1111 : : use m_gwdefs, only : GW_Q0_DEFAULT
1112 : : use m_fftcore, only : sphereboundary
1113 : : use m_fft_mesh, only : setmesh
1114 : : use m_fft, only : uplan_t
1115 : : use m_vcoul, only : vcgen_t
1116 : :
1117 : : use m_sort, only : sort_gvecs
1118 : : use m_pawpwij, only : pawpwij_t, pawpwij_init, pawpwij_free
1119 : :
1120 : : !Arguments ------------------------------------
1121 : : integer,intent(in) :: spin, ik_ibz
1122 : : type(dataset_type),intent(in) :: dtset
1123 : : type(datafiles_type),intent(in) :: dtfil
1124 : : type(crystal_t),intent(in) :: cryst
1125 : : type(ebands_t),intent(in) :: ebands
1126 : : type(Pseudopotential_type),intent(in) :: psps
1127 : : type(pawpwff_t),intent(in) :: paw_pwff(dtset%ntypat*dtset%usepaw)
1128 : : type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
1129 : : type(ugb_t),target,intent(in) :: ugb
1130 : :
1131 : : !Local variables-------------------------------
1132 : : !scalars
1133 : : integer,parameter :: mG0(3) = 0, master = 0
1134 : : integer :: nproc, my_rank, my_ib2st, npw_k, nspinor, m_npw, npwvec, ig, mpierr, fh, comm, buf_size, ierr
1135 : : integer :: band1, band1_start, batch1_size, n1dat, idat1, m_istwfk, iatom, dim_rtwg
1136 : : integer :: band2, band2_start, batch2_size, n2dat, idat2, units(2), ii, unt, nqibz_, nqbz_, nkbz_, test_unt, M_
1137 : : integer(XMPI_OFFSET_KIND) :: offset
1138 : : real(dp) :: cpu, wall, gflops, qpt(3), qbz_(3,1), gcart(3), kpt(3), max_abs_err, abs_err, my_gw_qlwl(3), mem_mb
1139 : : character(len=500) :: msg
1140 : : character(len=fnlen) :: filepath, cvx_filepath
1141 : : logical :: k_is_gamma
1142 : : logical,parameter :: trust_no_one = .False.
1143 : 0 : type(uplan_t) :: uplan_1, uplan_2, uplan_m
1144 [ # # # # : 0 : type(vcgen_t) :: vcgen
# # # # #
# ]
1145 : 0 : integer :: u_ngfft(18), u_nfft, u_mgfft, enforce_sym, method, nlmn_atm(cryst%natom)
1146 : 0 : integer,pointer :: gvec_max(:,:)
1147 : 0 : integer,allocatable,target :: m_gvec(:,:), sorted_kg_k(:,:)
1148 : 0 : complex(dp),allocatable :: ug1_batch(:,:), ur1_batch(:,:), ur2_batch(:,:), ur12_batch(:,:), ug12_batch(:,:), cwork(:)
1149 : 0 : complex(gwp),allocatable :: sqrt_vc(:), paw_rhotwg(:)
1150 : 0 : type(pawpwij_t),allocatable :: pwij(:)
1151 : 0 : type(pawcprj_type),allocatable :: cprj1(:,:)
1152 : : ! *************************************************************************
1153 : :
1154 : 0 : call cwtime(cpu, wall, gflops, "start")
1155 : :
1156 : 0 : comm = ugb%comm; nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
1157 [ # # ]: 0 : units = [std_out, ab_out]
1158 : 0 : npw_k = ugb%npw_k; nspinor = ugb%nspinor
1159 : :
1160 [ # # # # ]: 0 : if (dtset%prtvol > 10) call ugb%print([std_out], dtset%prtvol, header="ugb for CC4S")
1161 : :
1162 : : ! m_gvec is the g-sphere for the oscillators M computed from ecuteps (half-sphere if wavefunctions have TR).
1163 : : ! setmesh assumes g-vectors sorted by norm so use kin_sorted = True and sort ug%kg_k below.
1164 [ # # # # : 0 : kpt = dtset%kptns(:,ik_ibz); k_is_gamma = all(abs(kpt) < tol12)
# # ]
1165 [ # # ]: 0 : m_istwfk = 1; if (ugb%istwf_k == 2) m_istwfk = 2
1166 [ # # ]: 0 : call get_kg(kpt, m_istwfk, dtset%ecuteps, cryst%gmet, m_npw, m_gvec, kin_sorted=.True.)
1167 : :
1168 : : ! Setup FFT mesh
1169 [ # # ]: 0 : u_ngfft = dtset%ngfft
1170 : 0 : method = 2
1171 [ # # ]: 0 : if (dtset%fftgw==00 .or. dtset%fftgw==01) method=0
1172 [ # # ]: 0 : if (dtset%fftgw==10 .or. dtset%fftgw==11) method=1
1173 [ # # ]: 0 : if (dtset%fftgw==20 .or. dtset%fftgw==21) method=2
1174 [ # # ]: 0 : if (dtset%fftgw==30 .or. dtset%fftgw==31) method=3
1175 : 0 : enforce_sym = mod(dtset%fftgw, 10)
1176 : : ! Gamma only --> we don't need to rotate wavefunctions in the BZ
1177 [ # # ]: 0 : if (k_is_gamma) enforce_sym = 0
1178 : :
1179 [ # # ]: 0 : call sort_gvecs(npw_k, kpt, cryst%gmet, ugb%kg_k, sorted_kg_k)
1180 : :
1181 : 0 : npwvec = npw_k; gvec_max => sorted_kg_k
1182 [ # # ]: 0 : if (m_npw > npw_k) then
1183 : 0 : npwvec = m_npw; gvec_max => m_gvec
1184 : : end if
1185 [ # # ]: 0 : call setmesh(cryst%gmet, gvec_max, u_ngfft, npwvec, m_npw, npw_k, u_nfft, method, mG0, cryst, enforce_sym, unit=std_out)
1186 [ # # ]: 0 : ABI_FREE(sorted_kg_k)
1187 : :
1188 : : u_mgfft = maxval(u_ngfft(1:3))
1189 : 0 : qpt = zero
1190 : :
1191 : 0 : nqibz_ = 1; nqbz_ = 1; qbz_ = zero; nkbz_ = 1
1192 : : ! TODO: MC technique does not seem to work as expected, even in the legacy code.
1193 : : call vcgen%init(cryst, ebands%kptrlatt, nkbz_, nqibz_, nqbz_, qbz_, &
1194 : 0 : dtset%gw_rcut, dtset%gw_icutcoul, dtset%vcutgeo, dtset%ecuteps, comm)
1195 : :
1196 : : ! NB: npweps = m_npw
1197 [ # # # # : 0 : ABI_MALLOC(sqrt_vc, (m_npw))
# # # # #
# # # ]
1198 [ # # # # ]: 0 : my_gw_qlwl(:) = GW_Q0_DEFAULT; if (dtset%gw_nqlwl > 0) my_gw_qlwl = dtset%gw_qlwl(:,1)
1199 : 0 : call vcgen%get_vc_sqrt(qpt, m_npw, m_gvec, my_gw_qlwl, cryst, sqrt_vc, comm)
1200 : : ! Override the G=0 component with the correct value set by gw_icutcoulomb method
1201 : 0 : sqrt_vc(1) = sqrt(vcgen%i_sz)
1202 : : !sqrt_vc(1) = zero
1203 : 0 : call vcgen%free()
1204 : :
1205 [ # # ]: 0 : if (my_rank == master) then
1206 : 0 : call wrtout(units, " Computing oscilator matrix elements for CC4S.")
1207 [ # # ]: 0 : call print_ngfft([std_out], u_ngfft, header='FFT mesh for wavefunctions')
1208 : :
1209 : : ! =====================
1210 : : ! Write files for CC4S
1211 : : ! =====================
1212 [ # # # # ]: 0 : if (ik_ibz == 1 .and. spin == 1) then
1213 : : ! Write g-vector files, see https://manuals.cc4s.org/user-manual/objects/GridVectors.html
1214 [ # # # # ]: 0 : filepath = trim(dtfil%filnam_ds(4))//'_GridVectors.yaml'
1215 : 0 : write(ab_out, "(3a)")ch10," Writing Gridvectors metadata to file: ", trim(filepath)
1216 [ # # ]: 0 : if (open_file(filepath, msg, newunit=unt, access="stream", form="formatted", status="replace", action="write") /= 0) then
1217 : 0 : ABI_ERROR(msg)
1218 : : end if
1219 : 0 : write(unt,'(a)') 'version: 100'
1220 : 0 : write(unt,'(a)') 'type: Tensor'
1221 : 0 : write(unt,'(a)') 'scalarType: Real64'
1222 : 0 : write(unt,'(a)') 'dimensions:'
1223 : 0 : write(unt,'(a)') ' - length: 3'
1224 : 0 : write(unt,'(a)') ' type: Vector'
1225 : 0 : write(unt,'(a,i0)') ' - length: ',m_npw
1226 : 0 : write(unt,'(a)') ' type: Momentum'
1227 : 0 : write(unt,'(a)') 'elements:'
1228 : 0 : write(unt,'(a)') ' type: TextFile'
1229 : 0 : write(unt,'(a)') 'unit: 1.0 # Bohr^-1'
1230 : : ! The last three lines correspond to the reciprocal lattice vectors (including the factor 2pi)
1231 : 0 : write(unt,'(a)') 'metaData:'
1232 : : write(unt,'(" Gi: [",E22.15,",",E22.15,",",E22.15,"]")') &
1233 : 0 : two_pi*cryst%gprimd(1,1), two_pi*cryst%gprimd(2,1), two_pi*cryst%gprimd(3,1)
1234 : : write(unt,'(" Gj: [",E22.15,",",E22.15,",",E22.15,"]")') &
1235 : 0 : two_pi*cryst%gprimd(1,2), two_pi*cryst%gprimd(2,2), two_pi*cryst%gprimd(3,2)
1236 : : write(unt,'(" Gk: [",E22.15,",",E22.15,",",E22.15,"]")') &
1237 : 0 : two_pi*cryst%gprimd(1,3), two_pi*cryst%gprimd(2,3), two_pi*cryst%gprimd(3,3)
1238 : 0 : close(unt)
1239 : :
1240 : : ! Write g-vectors (cart coords)
1241 [ # # # # ]: 0 : filepath = trim(dtfil%filnam_ds(4))//'_GridVectors.elements'
1242 [ # # ]: 0 : if (open_file(filepath, msg, newunit=unt, access="stream", form="formatted", status="replace", action="write") /= 0) then
1243 : 0 : ABI_ERROR(msg)
1244 : : end if
1245 : :
1246 : : !TODO: k-points to be implemented.
1247 [ # # ]: 0 : do ig=1,m_npw
1248 [ # # # # : 0 : gcart = two_pi * matmul(cryst%gprimd, m_gvec(:,ig))
# # # # #
# ]
1249 [ # # ]: 0 : do ii=1,3
1250 : 0 : write(unt, *) gcart(ii)
1251 : : end do
1252 : : end do
1253 : 0 : close(unt)
1254 : :
1255 : : ! https://manuals.cc4s.org/user-manual/objects/CoulombVertex.html
1256 [ # # # # ]: 0 : filepath = trim(dtfil%filnam_ds(4))//'_CoulombVertex.yaml'
1257 : 0 : write(ab_out, "(3a)")ch10, ' Writing CoulombVertex metadata to file: ', trim(filepath)
1258 [ # # ]: 0 : if (open_file(filepath, msg, newunit=unt, access="stream", form="formatted", status="replace", action="write") /= 0) then
1259 : 0 : ABI_ERROR(msg)
1260 : : end if
1261 : 0 : write(unt,'(a)') 'version: 100'
1262 : 0 : write(unt,'(a)') 'type: Tensor'
1263 : 0 : write(unt,'(a)') 'scalarType: Complex64'
1264 : 0 : write(unt,'(a)') 'dimensions:'
1265 : 0 : write(unt,'(a,i0)') '- length: ',m_npw
1266 : 0 : write(unt,'(a)') ' type: AuxiliaryField'
1267 : 0 : write(unt,'(a,i0)') '- length: ',ugb%nband_k
1268 : 0 : write(unt,'(a)') ' type: State'
1269 : 0 : write(unt,'(a,i0)') '- length: ',ugb%nband_k
1270 : 0 : write(unt,'(a)') ' type: State'
1271 : 0 : write(unt,'(a)') 'elements:'
1272 : 0 : write(unt,'(a)') ' type: IeeeBinaryFile'
1273 : 0 : write(unt,'(a)') 'unit: 1.0 # Atomic units'
1274 : 0 : write(unt,'(a)') 'metaData:'
1275 [ # # ]: 0 : if (m_istwfk == 2) then
1276 : 0 : write(unt,'(a)') ' halfGrid: 1'
1277 : : else
1278 : 0 : write(unt,'(a)') ' halfGrid: 0'
1279 : : end if
1280 : 0 : close(unt)
1281 : :
1282 : : ! https://manuals.cc4s.org/user-manual/objects/CoulombPotential.html
1283 [ # # # # ]: 0 : filepath = trim(dtfil%filnam_ds(4))//'_CoulombPotential.yaml'
1284 : 0 : write(ab_out, "(3a)")ch10, ' Writing CoulombPotential metadata to file: ', trim(filepath)
1285 [ # # ]: 0 : if (open_file(filepath, msg, newunit=unt, access="stream", form="formatted", status="replace", action="write") /= 0) then
1286 : 0 : ABI_ERROR(msg)
1287 : : end if
1288 : 0 : write(unt,'(a)') 'version: 100'
1289 : 0 : write(unt,'(a)') 'type: Tensor'
1290 : 0 : write(unt,'(a)') 'scalarType: Real64'
1291 : 0 : write(unt,'(a)') 'dimensions:'
1292 : 0 : write(unt,'(a,i0)') ' - length: ',m_npw
1293 : 0 : write(unt,'(a)') ' type: Momentum'
1294 : 0 : write(unt,'(a)') 'elements:'
1295 : 0 : write(unt,'(a)') ' type: TextFile'
1296 : 0 : write(unt,'(a)') 'unit: 1.0 # Atomic units '
1297 : 0 : close(unt)
1298 : :
1299 [ # # # # ]: 0 : filepath = trim(dtfil%filnam_ds(4))//'_CoulombPotential.elements'
1300 : 0 : write(ab_out, "(3a)")ch10, ' Writing CoulombPotential data to file: ', trim(filepath)
1301 [ # # ]: 0 : if (open_file(filepath, msg, newunit=unt, access="stream", form="formatted", status="replace", action="write") /= 0) then
1302 : 0 : ABI_ERROR(msg)
1303 : : end if
1304 [ # # ]: 0 : do ig=1,m_npw
1305 : 0 : write(unt,*)real(sqrt_vc(ig) * conjg(sqrt_vc(ig)), kind=dp)
1306 : : !write(unt,*)real(sqrt_vc(ig)**2)
1307 : : end do
1308 : 0 : close(unt)
1309 : : end if ! ik_ibz == 1 .and. spin == 1
1310 : : end if ! my_rank == master
1311 : :
1312 : : ! Open binary file to store CoulombVertex
1313 [ # # # # ]: 0 : cvx_filepath = trim(dtfil%filnam_ds(4))//'_CoulombVertex.elements'
1314 [ # # ]: 0 : if (my_rank == master) write(ab_out, "(3a)")ch10, ' Writing CoulombVertex data to file: ', trim(cvx_filepath)
1315 : :
1316 : : #ifdef HAVE_MPI_IO
1317 : 0 : call MPI_FILE_OPEN(comm, cvx_filepath, MPI_MODE_CREATE + MPI_MODE_WRONLY, xmpio_info, fh, mpierr)
1318 : 0 : ABI_CHECK_MPI(mpierr, "MPI_FILE_OPEN")
1319 : : #else
1320 : : ABI_ERROR("CC4S interface requires MPI-IO!")
1321 : : #endif
1322 : :
1323 : : if (trust_no_one .and. my_rank == 0) then
1324 : : if (open_file("test_mg", msg, newunit=test_unt, form="formatted", status="replace", action="write") /= 0) then
1325 : : ABI_ERROR(msg)
1326 : : end if
1327 : : end if
1328 : :
1329 : : ! Define batch sizes and allocate workspace arrays.
1330 : : ! Increasing this value improves efficiency (less communication) at the price of more memory.
1331 : 0 : batch1_size = min(48, ugb%nband_k); batch2_size = min(48, ugb%nband_k) !; batch1_size = 1; batch2_size = 1
1332 : 0 : call wrtout(std_out, sjoin(" Using batch1_size:", itoa(batch1_size), ", batch2_size:", itoa(batch2_size)))
1333 : :
1334 : : mem_mb = (two * u_nfft * nspinor * batch1_size + &
1335 : : two * u_nfft * nspinor * batch2_size * two + &
1336 : 0 : two * m_npw * nspinor * batch2_size) * dp * b2Mb
1337 : 0 : call wrtout(std_out, sjoin(" Memory for workspace arrays ", ftoa(mem_mb, fmt="f8.1"), "[Mb] <<< MEM"))
1338 : :
1339 [ # # # # : 0 : ABI_MALLOC(ur1_batch, (u_nfft * nspinor, batch1_size))
# # # # #
# # # # #
# # ]
1340 [ # # # # : 0 : ABI_MALLOC(ur2_batch, (u_nfft * nspinor, batch2_size))
# # # # #
# # # # #
# # ]
1341 [ # # # # : 0 : ABI_MALLOC(ur12_batch, (u_nfft * nspinor, batch2_size))
# # # # #
# # # ]
1342 [ # # # # : 0 : ABI_MALLOC(ug12_batch, (m_npw * nspinor, batch2_size))
# # # # #
# # # # #
# # ]
1343 : :
1344 [ # # ]: 0 : if (psps%usepaw == 1) then
1345 : : ! Evaluate oscillator matrix elements btw partial waves. Note q=Gamma
1346 [ # # # # : 0 : ABI_MALLOC(pwij, (psps%ntypat))
# # # # #
# # # # #
# # # # #
# ]
1347 : 0 : call pawpwij_init(pwij, m_npw, qpt, m_gvec, cryst%rprimd, psps, pawtab, paw_pwff)
1348 [ # # ]: 0 : do iatom=1,cryst%natom
1349 : 0 : nlmn_atm(iatom) = pawtab(cryst%typat(iatom))%lmn_size
1350 : : end do
1351 [ # # # # : 0 : ABI_MALLOC(cprj1, (cryst%natom, nspinor*batch1_size))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
1352 : 0 : call pawcprj_alloc(cprj1, 0, nlmn_atm)
1353 : 0 : dim_rtwg = nspinor
1354 [ # # # # : 0 : ABI_MALLOC(paw_rhotwg, (m_npw*dim_rtwg))
# # # # #
# # # ]
1355 : : end if
1356 : :
1357 : : ! TODO:
1358 : : ! 1) take advantage of M_{b1,b2}(g) = <b1|e^{-ig.r}|b2> => M_{b1,b2}(g) = M_{b2,b1}(-g)^*
1359 : : ! once I have a better understanding of the fileformat expected by CC4S.
1360 : : ! 2) Handle parallel IO if nsppol 2 (we are inside the spin loop that is already MPI distributed!)
1361 : : ! 3) Clarify ordering of CoulombVertex (b1,b2 vs b2,b1) and eigenvalues (spin?)
1362 : : ! 4) Treatment of q--> 0 in vc_coul
1363 : : ! 4) See other TODOs below.
1364 : :
1365 : 0 : call uplan_1%init(npw_k, nspinor, batch1_size, u_ngfft, ugb%istwf_k, ugb%kg_k, dp, dtset%gpu_option)
1366 : 0 : call uplan_2%init(npw_k, nspinor, batch2_size, u_ngfft, ugb%istwf_k, ugb%kg_k, dp, dtset%gpu_option)
1367 : 0 : call uplan_m%init(m_npw, nspinor, batch2_size, u_ngfft, m_istwfk, m_gvec, dp, dtset%gpu_option)
1368 : :
1369 : 0 : M_ = m_npw
1370 : :
1371 : : ! Blocked loop over group of b1 indices. NB: Assuming bands distributed in contiguous blocks.
1372 [ # # # # : 0 : do band1_start=1, ugb%nband_k, batch1_size
# # # # ]
1373 : : ! Collect n1dat bands starting from band1_start on each proc.
1374 : 0 : n1dat = blocked_loop(band1_start, ugb%nband_k, batch1_size)
1375 : :
1376 [ # # # # ]: 0 : call ugb%mat%collect_cplx(ugb%npwsp, n1dat, [1, band1_start], ug1_batch)
1377 [ # # ]: 0 : if (psps%usepaw == 1) call ugb%collect_cprj(nspinor, n1dat, band1_start, cprj1)
1378 : :
1379 : : ! FFT: ug1_batch --> ur1_batch
1380 : 0 : call uplan_1%execute_gr(n1dat, ug1_batch(:,1), ur1_batch(:,1))
1381 [ # # # # : 0 : if (ugb%istwf_k /= 2) ur1_batch = conjg(ur1_batch) ! Not needed if k == Gamma as ur1 is real.
# # ]
1382 [ # # ]: 0 : ABI_FREE(ug1_batch)
1383 : :
1384 : : ! Blocked loop over MY group of b2 indices (contiguous blocks)
1385 [ # # # # : 0 : do band2_start=ugb%my_bstart, ugb%my_bstop, batch2_size
# # # # ]
1386 : 0 : n2dat = blocked_loop(band2_start, ugb%my_bstop, batch2_size)
1387 : 0 : my_ib2st = band2_start - ugb%my_bstart + 1
1388 : :
1389 : : ! FFT: ugb%mat --> ur2_batch for n2dat states.
1390 : 0 : call uplan_2%execute_gr(n2dat, ugb%mat%buffer_cplx(:,my_ib2st), ur2_batch(:,1))
1391 : :
1392 : : ! For each row of the submatrix, build n2dat products (band1, idat2) in r-space, then r --> g.
1393 [ # # ]: 0 : do idat1=1,n1dat
1394 : 0 : band1 = band1_start + idat1 - 1
1395 : :
1396 [ # # ]: 0 : do idat2=1,n2dat
1397 [ # # ]: 0 : ur12_batch(:,idat2) = ur1_batch(:,idat1) * ur2_batch(:,idat2)
1398 : : end do
1399 : 0 : call uplan_m%execute_rg(n2dat, ur12_batch(:,1), ug12_batch(:,1))
1400 : :
1401 [ # # ]: 0 : if (psps%usepaw == 1) then
1402 : : ! Add PAW on-site contributions
1403 [ # # ]: 0 : do idat2=1,n2dat
1404 : : associate (cprj1_kmq => cprj1(:, 1 + (idat1-1)*nspinor), &
1405 : 0 : cprj2_k => ugb%cprj_k(:, 1 + (my_ib2st+idat2-2)*nspinor)) ! NB: ugb%cprj_k(2, nspinor*my_nband)
1406 [ # # ]: 0 : paw_rhotwg = zero
1407 : 0 : call paw_rho_tw_g(cryst, pwij, m_npw, dim_rtwg, nspinor, m_gvec, cprj1_kmq, cprj2_k, paw_rhotwg)
1408 [ # # ]: 0 : ug12_batch(:,idat2) = ug12_batch(:,idat2) + paw_rhotwg
1409 : : end associate
1410 : : end do
1411 : : end if
1412 : :
1413 : : ! This to zero the matrix elements for certain (band1, band2) entries.
1414 : : ! in this case: band1 = 1, band2 = 1.
1415 : : !if (band1 == 1) then
1416 : : ! do idat2=1,n2dat
1417 : : ! ! This is the condition for band2
1418 : : ! if (band2_start + idat2 - 1 == 1) ug12_batch(:,idat2) = zero
1419 : : ! end do
1420 : : !end if
1421 : :
1422 [ # # ]: 0 : if (nspinor == 2) then
1423 : : ! Sum over spinors and repack data in the first n2dat positions to prepare IO operation.
1424 [ # # ]: 0 : do idat2=1,n2dat
1425 [ # # ]: 0 : ug12_batch(1:m_npw,idat2) = ug12_batch(1:m_npw,idat2) + ug12_batch(m_npw+1:,idat2)
1426 : : end do
1427 [ # # # # ]: 0 : do idat2=2,n2dat,2
1428 [ # # ]: 0 : ug12_batch(m_npw+1:,idat2-1) = ug12_batch(1:m_npw,idat2)
1429 : : end do
1430 : : end if
1431 : :
1432 [ # # ]: 0 : do idat2=1,n2dat
1433 : : !if (band1 == band2_start + idat2 -1) then
1434 : : ! write(std_out,*) " ug12_batch(g=0,band1,band2), band", ug12_batch(1,idat2), band1, band2_start + idat2 -1
1435 : : !end if
1436 : : ! Multiply by sqrt(vc(g))
1437 : : ! This renormalization is needed to make CC4S converge (work done by AlejandroG, FabienB, MatteoG)
1438 [ # # ]: 0 : ug12_batch(:,idat2) = ug12_batch(:,idat2) * sqrt_vc(:) / sqrt(cryst%ucvol)
1439 : : !FBru:
1440 : : ! CC4S convention:
1441 : : ! When using time-reversal, include a factor sqrt(2) for the non-zero G's
1442 : : ! Then CC4S will perform the sum only over half the grid so all the G/=0 component should be counted twice.
1443 [ # # # # ]: 0 : if (m_istwfk == 2) ug12_batch(2:,idat2) = ug12_batch(2:,idat2) * sqrt(two)
1444 : : end do
1445 : : !write(std_out,*)" max(abs(ug12_batch)):", maxval(abs(ug12_batch(:,1:n2dat)))
1446 : :
1447 : : #ifdef HAVE_MPI_IO
1448 : : ! Write ug12_batch using Stream-IO
1449 : 0 : buf_size = m_npw * n2dat
1450 : :
1451 : : ! FBru convert to longer integer before the multiplication
1452 : : offset = INT(m_npw, KIND=XMPI_OFFSET_KIND) &
1453 : : * INT( (band2_start-1) + (band1-1) * ugb%nband_k, KIND=XMPI_OFFSET_KIND) &
1454 : 0 : * INT(xmpi_bsize_dpc, KIND=XMPI_OFFSET_KIND)
1455 : :
1456 : 0 : call MPI_FILE_WRITE_AT(fh, offset, ug12_batch, buf_size, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
1457 [ # # ]: 0 : ABI_HANDLE_MPIERR(mpierr)
1458 : :
1459 : 0 : if (my_rank == 0 .and. trust_no_one) then
1460 : : do idat2=1,n2dat
1461 : : band2 = band2_start + idat2 - 1
1462 : : write(test_unt,*)band1, band2, ug12_batch(1:M_,idat2)
1463 : : end do
1464 : : end if
1465 : : #endif
1466 : : end do ! idat1
1467 : :
1468 : : end do ! band2_start
1469 : : end do ! band1_start
1470 : :
1471 : : #ifdef HAVE_MPI_IO
1472 : 0 : call MPI_FILE_CLOSE(fh, mpierr)
1473 : 0 : ABI_CHECK_MPI(mpierr, "FILE_CLOSE!")
1474 : 0 : call xmpi_barrier(comm)
1475 : :
1476 [ # # ]: 0 : if (my_rank == 0) then
1477 : 0 : buf_size = 4
1478 : 0 : call wrtout(units, sjoin(" Reading norm of Coulomb vertex for testing purposes with ng:", itoa(buf_size)), newlines=1, pre_newlines=1)
1479 : 0 : call wrtout(units, " List of g-vectors in the Coulomb vertex:")
1480 [ # # ]: 0 : do ig=1,buf_size
1481 : 0 : call wrtout(units, sjoin(itoa(ig), ":", ltoa(m_gvec(:,ig))))
1482 : : end do
1483 [ # # # # : 0 : ABI_MALLOC(cwork, (buf_size))
# # # # #
# # # ]
1484 : 0 : call MPI_FILE_OPEN(xmpi_comm_self, cvx_filepath, MPI_MODE_RDONLY, xmpio_info, fh, mpierr)
1485 : 0 : ABI_CHECK_MPI(mpierr, "MPI_FILE_OPEN")
1486 : 0 : ierr = 0
1487 [ # # ]: 0 : band1_loop: do band1=1, ugb%nband_k
1488 [ # # ]: 0 : do band2=1, ugb%nband_k
1489 [ # # ]: 0 : ierr = ierr + 1; if (ierr == 6) exit band1_loop
1490 : 0 : offset = ((band2-1) * m_npw + (band1-1) * m_npw * ugb%nband_k) * xmpi_bsize_dpc
1491 : 0 : call MPI_FILE_READ_AT(fh, offset, cwork, buf_size, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
1492 [ # # ]: 0 : ABI_HANDLE_MPIERR(mpierr)
1493 : 0 : call wrtout(units, sjoin(" For band1:", itoa(band1), ", band2:", itoa(band2)))
1494 [ # # # # ]: 0 : where (abs(cwork) < tol8)
1495 : : cwork = zero
1496 : : end where
1497 [ # # ]: 0 : write(msg, "(*(1x, es12.5))")abs(cwork(1:buf_size))
1498 : 0 : call wrtout(units, msg)
1499 : : end do
1500 : : end do band1_loop
1501 [ # # ]: 0 : ABI_FREE(cwork)
1502 : : end if
1503 : : #endif
1504 : :
1505 : : ! =============
1506 : : ! DEBUG SECTION
1507 : : ! =============
1508 : : #ifdef HAVE_MPI_IO
1509 : : if (my_rank == 0 .and. trust_no_one) then
1510 : : close(test_unt)
1511 : : if (open_file("test_mg", msg, newunit=test_unt, form="formatted", status="old", action="read") /= 0) then
1512 : : ABI_ERROR(msg)
1513 : : end if
1514 : :
1515 : : call MPI_FILE_OPEN(xmpi_comm_self, cvx_filepath, MPI_MODE_RDONLY, xmpio_info, fh, mpierr)
1516 : : ABI_CHECK_MPI(mpierr, "MPI_FILE_OPEN")
1517 : :
1518 : : ABI_MALLOC(cwork, (m_npw))
1519 : : max_abs_err = zero
1520 : : do ig=1, ugb%nband_k**2
1521 : : read(test_unt,*) band1, band2, ug12_batch(1:M_,1)
1522 : : offset = ((band2-1) * m_npw + (band1-1) * m_npw * ugb%nband_k) * xmpi_bsize_dpc
1523 : : call MPI_FILE_READ_AT(fh, offset, cwork, m_npw, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
1524 : : ABI_HANDLE_MPIERR(mpierr)
1525 : :
1526 : : abs_err = maxval(abs(ug12_batch(1:M_,1) - cwork(1:M_)))
1527 : : max_abs_err = max(max_abs_err, abs_err)
1528 : : if (abs_err > zero) write(std_out, *)" For ig:", ig, "/", ugb%nband_k**2, "abs_err", abs_err
1529 : : !write(std_out, *)"1:", ug12_batch(1:M_,1); write(std_out, *)"2:", cwork(1:M_)
1530 : : end do
1531 : :
1532 : : close(test_unt)
1533 : : call MPI_FILE_CLOSE(fh, mpierr)
1534 : : ABI_CHECK_MPI(mpierr, "FILE_CLOSE!")
1535 : : ABI_FREE(cwork)
1536 : :
1537 : : write(std_out,*)" max_abs_err:", max_abs_err
1538 : : ABI_CHECK(max_abs_err < tol16, sjoin("max_abs_err:", ftoa(max_abs_err)))
1539 : : call wrtout(std_out, " Debugging section OK!!!")
1540 : : end if
1541 : : #endif
1542 : :
1543 : : ! Free memory
1544 : 0 : call uplan_1%free(); call uplan_2%free(); call uplan_m%free()
1545 : :
1546 [ # # ]: 0 : ABI_FREE(m_gvec)
1547 [ # # ]: 0 : ABI_FREE(ur1_batch)
1548 [ # # ]: 0 : ABI_FREE(ur2_batch)
1549 [ # # ]: 0 : ABI_FREE(ur12_batch)
1550 [ # # ]: 0 : ABI_FREE(ug12_batch)
1551 : 0 : ABI_FREE(sqrt_vc)
1552 : :
1553 [ # # ]: 0 : if (psps%usepaw == 1) then
1554 : 0 : call pawpwij_free(pwij)
1555 [ # # # # : 0 : ABI_FREE(pwij)
# # # # ]
1556 : 0 : call pawcprj_free(cprj1)
1557 [ # # # # : 0 : ABI_FREE(cprj1)
# # # # #
# ]
1558 [ # # ]: 0 : ABI_FREE(paw_rhotwg)
1559 : : end if
1560 : :
1561 : 0 : call cwtime_report(" cc4s_gamma", cpu, wall, gflops)
1562 : :
1563 [ # # # # : 0 : end subroutine cc4s_gamma
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
1564 : : !!***
1565 : :
1566 : 0 : end module m_gwr_driver
1567 : : !!***
|