Branch data Line data Source code
1 : : !!****m* ABINIT/m_abstract_wf
2 : : !! NAME
3 : : !! m_abstract_wf
4 : : !!
5 : : !! FUNCTION
6 : : !! Interface with Wannier90.
7 : : !! This module contains the abstract type abstract_wf and its children.
8 : : !! The abstract_wf type is used to store the wavefunctions either in wfd or wfk format.
9 : : !! And it provide the common interface for both format.
10 : : !!
11 : : !! COPYRIGHT
12 : : !! Copyright (C) 2005-2026 ABINIT group (BAmadon, CEspejo, FJollet, TRangel, DRH)
13 : : !! This file is distributed under the terms of the
14 : : !! GNU General Public License, see ~abinit/COPYING
15 : : !! or http://www.gnu.org/copyleft/gpl.txt .
16 : : !!
17 : :
18 : : #if defined HAVE_CONFIG_H
19 : : #include "config.h"
20 : : #endif
21 : :
22 : : #include "abi_common.h"
23 : :
24 : : module m_abstract_wf
25 : :
26 : : use defs_basis
27 : : use defs_wannier90
28 : : use m_abicore
29 : : use m_errors
30 : : use m_atomdata
31 : : use m_xmpi
32 : : use m_sort
33 : : #ifdef FC_NAG
34 : : use f90_unix_dir
35 : : #endif
36 : : use netcdf
37 : : use m_nctk
38 : : use m_hdr
39 : : use m_dtset
40 : : use m_dtfil
41 : :
42 : : use m_build_info, only : abinit_version
43 : : use defs_wvltypes, only : wvl_internal_type
44 : : use defs_datatypes, only : pseudopotential_type
45 : : use defs_abitypes, only : MPI_type
46 : : use m_io_tools, only : delete_file
47 : : use m_fstrings, only : strcat, sjoin, itoa
48 : : use m_fftcore, only : ngfft_seq, get_kg
49 : : use m_crystal, only : crystal_t
50 : : use m_ebands, only : ebands_t
51 : : use m_pawtab, only : pawtab_type
52 : : use m_pawrhoij, only : pawrhoij_copy
53 : : use m_pawcprj, only : pawcprj_type
54 : : use m_wfd, only : wfd_t, wave_t, WFD_STORED
55 : :
56 : : implicit none
57 : :
58 : : private
59 : :
60 : :
61 : : !!***
62 : :
63 : :
64 : : !type wann_ksetting_t:
65 : : ! This type is used to store the information about the kpoints
66 : : ! and the MPI distribution of the kpoints.
67 : : ! It is used in the wannier90 interface.
68 : : type, public:: wann_ksetting_t
69 : : logical :: has_ovikp = .False. !.True. if ovikp is allocated
70 : : type(crystal_t), pointer :: cryst => null() ! crystal structure
71 : : !nkpt: number of kpoints
72 : : !mband: number of bands
73 : : !num_nnmax: maximum number of nearest neighbors
74 : : !nntot: total number of nearest neighbors
75 : : !nsppol: number of spin polarizations
76 : : integer :: nkpt=0, mband=0, num_nnmax=0, nntot=0, nsppol=0
77 : : !rank: rank of the current process
78 : : !comm: communicator
79 : : !nprocs: number of processes
80 : : integer :: rank=-999, comm=-999, nprocs=-999
81 : : !ovikp: array of size (nkpt, num_nnmax) containing the indices of the nearest neighbors
82 : : integer, allocatable :: ovikp(:, :)
83 : : !my_nspin: number of spin polarizations for the current process
84 : : !my_nkpt: number of kpoints for the current process
85 : : !my_nkpt_pnn: number of kpoints for the current process including the nearest neighbors
86 : : integer :: my_nspin, my_nkpt, my_nkpt_pnn
87 : : !my_spins: array of size (my_nspin) containing the spin indices for the current process
88 : : !my_ikpts: array of size (my_nkpt) containing the indices of the kpoints for the current process
89 : : !my_ikpts_pnn: array of size (my_nkpt_pnn) containing the indices of the kpoints for the current process including the nearest neighbors
90 : : integer, allocatable :: my_spins(:), my_ikpts(:), my_ikpts_pnn(:)
91 : : !kkpts: array of size (nkpt, 3) containing the kpoints
92 : : !my_kkpts: array of size (my_nkpt, 3) containing the kpoints for the current process
93 : : !my_kkpts_pnn: array of size (my_nkpt_pnn, 3) containing the kpoints for the current process including the nearest neighbors
94 : : real(dp), pointer :: kkpts(:, :)=> null()
95 : : real(dp), allocatable :: my_kkpts(:, :), my_kkpts_pnn(:, :)
96 : : contains
97 : : procedure :: init => wann_ksetting_init
98 : : procedure :: set_ovikp => wann_ksetting_set_ovikp
99 : : procedure :: free => wann_ksetting_free
100 : : procedure :: get_mpw_gmax => wann_ksetting_get_mpw_gmax
101 : : procedure :: distribute_mpi => wann_ksetting_distribute_mpi
102 : : procedure :: get_bks_mask => wann_ksetting_get_bks_mask
103 : : end type wann_ksetting_t
104 : :
105 : :
106 : :
107 : : !type abstract_wf:
108 : : ! This type is used to store the information about the wavefunctions
109 : : ! and the MPI distribution of the wavefunctions.
110 : : ! It provide the common interface for the wavefunctions.
111 : : type, public :: abstract_wf
112 : : !has_paw: .True. if the wavefunctions are PAW wavefunctions
113 : : logical :: has_paw = .True.
114 : : !cryst: crystal structure
115 : : type(crystal_t), pointer :: cryst => null()
116 : : type(datafiles_type),pointer :: dtfil => null()
117 : : type(dataset_type),pointer :: dtset => null()
118 : : !hdr: header, it contains the information about the wavefunctions
119 : : type(hdr_type), pointer :: hdr => null()
120 : : !MPI_enreg: MPI type for the wavefunctions
121 : : type(mpi_type), pointer :: MPI_enreg => null()
122 : : !psps: pseudopotential information
123 : : type(pseudopotential_type), pointer :: psps => null()
124 : : !pawtab: PAW tabulated data
125 : : type(pawtab_type),pointer :: pawtab(:) => null()
126 : : !ebands: eigenvalues
127 : : type(ebands_t), pointer :: ebands => null()
128 : : !kset: kpoints information
129 : : type(wann_ksetting_t) :: kset
130 : : !natom: number of atoms
131 : : !nspinor: number of spinors
132 : : !nsppol: number of spin polarizations
133 : : !mband: number of bands
134 : : !mkmem: number of kpoints in this process
135 : : !nkpt: number of kpoints
136 : :
137 : : integer :: natom=0, nspinor=0, nsppol=0, mband=0, &
138 : : & mkmem=0, nkpt=0, rank=-999, nprocs=-999, comm=-999
139 : : contains
140 : : !procedure :: init => abstract_wf_init
141 : : procedure :: abstract_init
142 : : procedure :: free => abstract_wf_free
143 : : procedure :: cg_elem => abstract_wf_cg_elem
144 : : procedure :: cg_elem_complex => abstract_wf_cg_elem_complex
145 : : procedure :: cprj_elem =>abstract_wf_cprj_elem
146 : : procedure :: get_cg_ptr => abstract_wf_get_cprj_ptr
147 : : procedure :: get_cprj_ptr => abstract_wf_get_cprj_ptr
148 : : procedure :: load_cg => abstract_wf_load_cg
149 : : !procedure :: show_info
150 : : procedure :: get_kgs=> abstract_wf_get_kgs
151 : :
152 : : end type abstract_wf
153 : :
154 : :
155 : : !type cg_cprj:
156 : : ! This type is used to store the information about the wavefunctions
157 : : ! and the MPI distribution of the wavefunctions.
158 : : ! It is a child of the abstract_wf type and it provides the interface
159 : : ! for the wavefunctions in the CG and CPRJ format.
160 : : type, public,extends(abstract_wf) :: cg_cprj
161 : : real(dp), pointer :: cg(:, :)=>null()
162 : : type(pawcprj_type), pointer :: cprj(:,:)=>null()
163 : : integer, pointer :: iwav(:,:,:, :)=>null()
164 : : integer, allocatable :: icprj(:, :, :)
165 : : contains
166 : : procedure :: init => cg_cprj_init !initialize the cg_cprj type
167 : : procedure :: free => cg_cprj_free !free the cg_cprj type
168 : : procedure :: compute_index_cprj !compute the index of the cprj
169 : : procedure :: cg_elem
170 : : procedure :: cg_elem_complex
171 : : procedure :: cprj_elem
172 : : procedure :: get_cg_ptr => cg_cprj_get_cprj_ptr
173 : : procedure :: get_cprj_ptr => cg_cprj_get_cprj_ptr
174 : : procedure :: write_cg_and_cprj_tmpfile
175 : : procedure :: remove_tmpfile
176 : : procedure :: load_cg
177 : : end type cg_cprj
178 : :
179 : :
180 : : !type wfd_t:
181 : : ! wavefunctions in the WFD format.
182 : : type, public, extends(abstract_wf) :: wfd_wf
183 : : ! The working wfd, ebands, etc
184 : : type(wfd_t), pointer :: wfd => null()
185 : :
186 : : type(wave_t), pointer :: waveprt => null()
187 : :
188 : : ! if wfd is in IBZ, expand to fullBZ
189 : : logical :: expanded = .False.
190 : : integer, allocatable :: bz2ibz(:, :)
191 : : type(wfd_t), pointer :: wfd_ibz => null()
192 : : type(ebands_t), pointer :: ebands_ibz => null()
193 : : type(hdr_type), pointer :: hdr_ibz => null()
194 : :
195 : : logical, allocatable :: bks_mask(:, :, :)
196 : : logical, allocatable :: keep_ur(:, :, :)
197 : :
198 : : type(wfd_t) :: wfd_bz
199 : : type(ebands_t) :: ebands_bz
200 : : type(hdr_type) :: hdr_bz
201 : : type(dataset_type) :: dtset_bz
202 : : type(MPI_type) :: mpi_enreg_bz
203 : : contains
204 : : procedure :: init => wfd_wf_init
205 : : procedure :: free => wfd_wf_free
206 : : !procedure :: get_ug => wfd_wf_ug
207 : : procedure :: cg_elem => wfd_cg_elem
208 : : procedure :: cg_elem_complex => wfd_cg_elem_complex
209 : : procedure :: cprj_elem =>wfd_cprj_elem
210 : : procedure :: load_cg => wfd_load_cg
211 : : end type wfd_wf
212 : :
213 : : public :: init_mywfc, compute_iwav, write_cg_and_cprj
214 : :
215 : : contains
216 : :
217 : : !-----------------------------------------------------------------------------
218 : : !> Initialize the wann_ksetting_t type
219 : : !> @param self: the wann_ksetting_t type
220 : : !> @param cryst: the crystal structure
221 : : !> @param nkpt: number of kpoints
222 : : !> @param mband: number of bands
223 : : !> @param nsppol: number of spin polarizations
224 : : !> @param kkpts: the kpoints
225 : : !> @param comm: MPI communicator
226 : : !> @param nprocs: number of processes
227 : : !> @param rank: rank of the process
228 : : !-----------------------------------------------------------------------------
229 : 5 : subroutine wann_ksetting_init(self, cryst, nkpt, mband, &
230 [ - + ]: 5 : & nsppol, kkpts, comm, nprocs, rank)
231 : : class(wann_ksetting_t), intent(inout) :: self
232 : : type(crystal_t), target, intent(in):: cryst
233 : : integer, intent(in) :: nkpt, mband, nsppol, comm, nprocs, rank
234 : : real(dp), target, intent(in) :: kkpts(:, :)
235 : 5 : self%comm=comm
236 : 5 : self%nprocs=nprocs
237 : 5 : self%rank=rank
238 : 5 : self%cryst=>cryst
239 : 5 : self%nkpt=nkpt
240 : 5 : self%mband=mband
241 : 5 : self%nsppol=nsppol
242 : 5 : self%my_nspin = nsppol
243 : 5 : self%kkpts=> kkpts
244 : 5 : end subroutine wann_ksetting_init
245 : :
246 : :
247 : :
248 : : !-----------------------------------------------------------------------------
249 : : !> compute the ovikp array (the overlap information of the kpoints)
250 : : !> @param self: the wann_ksetting_t type
251 : : !> @param ovikp: the overlap information of the kpoints
252 : : !> @param nntot: number of nearest neighbors
253 : : !> @param num_nnmax: maximum number of nearest neighbors
254 : : !> @param mpi_enreg: MPI information
255 : : !-----------------------------------------------------------------------------
256 [ - + ]: 5 : subroutine wann_ksetting_set_ovikp(self, ovikp, nntot, num_nnmax, mpi_enreg)
257 : : class(wann_ksetting_t), intent(inout) :: self
258 : : integer, intent(in) :: nntot, num_nnmax
259 : : integer, intent(in) :: ovikp(:, :)
260 : : type(mpi_type), intent(inout) :: mpi_enreg
261 [ - + ]: 5 : if (self%has_ovikp) then
262 : 0 : ABI_ERROR("ovikp already set!")
263 : : end if
264 : 5 : self%has_ovikp = .True.
265 : 5 : self%nntot = nntot
266 : 5 : self%num_nnmax=num_nnmax
267 [ - + + - : 20 : ABI_MALLOC(self%ovikp, (self%nkpt, num_nnmax))
- + + - +
- + - - +
- + - + ]
268 [ + + + + ]: 314 : self%ovikp(:,:) = ovikp(:, :)
269 : 5 : call self%distribute_mpi(mpi_enreg)
270 : 5 : end subroutine wann_ksetting_set_ovikp
271 : :
272 : :
273 : : !-----------------------------------------------------------------------------
274 : : !> free the wann_ksetting_t type
275 : : !> @param self: the wann_ksetting_t type
276 : : !-----------------------------------------------------------------------------
277 : 33 : subroutine wann_ksetting_free(self)
278 : : class(wann_ksetting_t), intent(inout) :: self
279 : 33 : nullify(self%cryst)
280 : 33 : nullify(self%kkpts)
281 [ + + ]: 33 : if (self%has_ovikp) then
282 [ + - ]: 5 : ABI_SFREE(self%ovikp)
283 [ - + ]: 5 : ABI_FREE(self%my_spins)
284 [ - + ]: 5 : ABI_FREE(self%my_ikpts)
285 [ - + ]: 5 : ABI_FREE(self%my_kkpts)
286 [ - + ]: 5 : ABI_FREE(self%my_ikpts_pnn)
287 [ - + ]: 5 : ABI_FREE(self%my_kkpts_pnn)
288 : : end if
289 : 33 : end subroutine wann_ksetting_free
290 : :
291 : :
292 : : !-----------------------------------------------------------------------------
293 : : !> set the mpi distribution using the information in the wann_ksetting_t type
294 : : !> @param self: the wann_ksetting_t type
295 : : !> @param mpi_enreg: MPI information
296 : : !-----------------------------------------------------------------------------
297 : 5 : subroutine wann_ksetting_distribute_mpi(self, mpi_enreg)
298 : : class(wann_ksetting_t), intent(inout) :: self
299 : : type(MPI_type), intent(inout) :: mpi_enreg
300 : : integer :: ikpt, inn, ik_me, ik_nn, ispin
301 : 10 : logical :: belongs(self%nkpt)
302 : : integer :: counter
303 : 5 : MPI_enreg%comm_cell=self%comm
304 : 5 : mpi_enreg%me=self%rank
305 : 5 : mpi_enreg%me_kpt=self%rank
306 : 5 : mpi_enreg%nproc = self%nprocs
307 : 5 : MPI_enreg%paral_spinor=0
308 : : !write(std_out,*) "Distributed mpi:", "rank:", self%rank, "comm", self%comm
309 : : !write(std_out,*) "nprocs:", self%nprocs, "me:", mpi_enreg%me, "me_kpt:", mpi_enreg%me_kpt
310 [ + - ]: 5 : if (.not. allocated(mpi_enreg%proc_distrb))then
311 [ - + + - : 25 : ABI_MALLOC(mpi_enreg%proc_distrb, (self%nkpt, self%mband, self%nsppol) )
- + + - -
+ + - + -
+ - - + -
+ - + ]
312 : : end if
313 [ + + + + : 3386 : mpi_enreg%proc_distrb(:, :, :) =-999
+ + ]
314 : :
315 : :
316 : 5 : self%my_nkpt=0
317 : 5 : self%my_nkpt_pnn=0
318 : :
319 [ - + + - : 15 : ABI_MALLOC(self%my_spins, (self%nsppol))
+ - + - -
+ - + -
+ ]
320 : 5 : self%my_nspin=self%nsppol
321 [ + + ]: 10 : do ispin =1, self%nsppol
322 : 10 : self%my_spins(ispin)=ispin
323 : : end do
324 : : ! split kpoints
325 [ - + ]: 5 : call xmpi_split_block(self%nkpt, self%comm, self%my_nkpt, self%my_ikpts)
326 : :
327 [ - + + - : 15 : ABI_MALLOC(self%my_kkpts, (3, self%my_nkpt))
+ - + - -
+ - + -
+ ]
328 : :
329 [ + + ]: 309 : belongs(:)=.False.
330 [ + + ]: 309 : do ikpt=1, self%my_nkpt
331 : 304 : ik_me=self%my_ikpts(ikpt)
332 [ + + ]: 1216 : self%my_kkpts(:, ikpt) = self%kkpts(:, ik_me)
333 : 304 : belongs(ik_me) = .True.
334 [ + + + + ]: 3936 : MPI_enreg%proc_distrb(ik_me,:,:)= self%rank
335 [ + + ]: 613 : do inn=1, self%nntot
336 : 304 : ik_nn=self%ovikp(ikpt, inn)
337 : 608 : belongs(ik_nn) = .True.
338 : : end do
339 : : end do
340 : :
341 : 5 : self%my_nkpt_pnn=0
342 [ + + ]: 309 : do ikpt =1, self%nkpt
343 [ + - ]: 309 : if (belongs(ikpt)) self%my_nkpt_pnn=self%my_nkpt_pnn+1
344 : : end do
345 : :
346 [ - + + - : 15 : ABI_MALLOC(self%my_ikpts_pnn, (self%my_nkpt_pnn))
+ - + - -
+ - + -
+ ]
347 [ - + + - : 15 : ABI_MALLOC(self%my_kkpts_pnn, (3, self%my_nkpt_pnn))
+ - + - -
+ - + -
+ ]
348 : :
349 : 5 : counter=0
350 [ + + ]: 309 : do ikpt =1, self%nkpt
351 [ + - ]: 309 : if (belongs(ikpt)) then
352 : 304 : counter =counter+1
353 : 304 : self%my_ikpts_pnn(counter) = ikpt
354 [ + + ]: 1216 : self%my_kkpts_pnn(:, counter) = self%kkpts(:, ikpt)
355 : : end if
356 : : end do
357 : :
358 : :
359 : 5 : end subroutine wann_ksetting_distribute_mpi
360 : :
361 : : !-----------------------------------------------------------------------------
362 : : !> using the kpoint information in the wann_ksetting_t type, set the
363 : : !> bks_mask and keep_ur arrays.
364 : : !> @param self: the wann_ksetting_t type
365 : : !> @param bks_mask: the bks_mask array
366 : : !> @param keep_ur: the keep_ur array
367 : : !> @param nband: the number of bands
368 : : !> @param nsppol: the number of spins
369 : : !> @param keep_ur_value: the value to set the keep_ur array to
370 : : !-----------------------------------------------------------------------------
371 : 5 : subroutine wann_ksetting_get_bks_mask(self, bks_mask, keep_ur, nband, nsppol, keep_ur_value)
372 : : class(wann_ksetting_t), intent(inout) :: self
373 : : integer, intent(in) :: nband, nsppol
374 : : logical, allocatable, intent(inout) :: bks_mask(:, :, :) ! bank, kpt, spin
375 : : logical, allocatable, intent(inout) :: keep_ur(:, :, :)
376 : : logical, intent(in) :: keep_ur_value
377 : : integer :: ikpt, ispin, inn, ik_nn, ik_me
378 : :
379 [ - + + - : 25 : ABI_MALLOC(bks_mask, (nband, self%nkpt, nsppol))
- + + - -
+ + - + -
+ - - + -
+ - + ]
380 [ - + + - : 20 : ABI_MALLOC(keep_ur, (nband, self%nkpt, nsppol))
- + + - -
+ + - - +
- + - + ]
381 [ + + + + : 3642 : bks_mask(:, :, :) = .False.
+ + ]
382 [ + + + + : 3642 : keep_ur(:, :, :) = .False.
+ + ]
383 [ + + ]: 10 : do ispin =1, nsppol
384 [ + + ]: 314 : do ikpt =1 , self%my_nkpt
385 : 304 : ik_me = self%my_ikpts(ikpt)
386 [ + + + + ]: 3936 : bks_mask(:, ik_me, :) =.True.
387 [ + + + + ]: 3936 : keep_ur(:, ik_me, :) = keep_ur_value
388 [ + + ]: 613 : do inn =1, self%nntot
389 : 304 : ik_nn=self%ovikp(ikpt, inn)
390 [ + + ]: 3632 : bks_mask(:, ik_nn, ispin)=.True.
391 [ + + ]: 3936 : keep_ur(:, ik_nn, ispin) = keep_ur_value
392 : : end do
393 : : end do
394 : : end do
395 : 5 : end subroutine wann_ksetting_get_bks_mask
396 : :
397 : :
398 : : !-----------------------------------------------------------------------------
399 : : !> using the kpoint information in the wann_ksetting_t type, set the
400 : : !> ecut, mpw, and gmax values.
401 : : !> @param self: the wann_ksetting_t type
402 : : !> @param ecut: the ecut value
403 : : !> @param mpw: the mpw value
404 : : !> @param gmax: the gmax array
405 : : !-----------------------------------------------------------------------------
406 : 5 : subroutine wann_ksetting_get_mpw_gmax(self, ecut, mpw, gmax)
407 : : class(wann_ksetting_t), intent(inout) :: self
408 : : real(dp),intent(in) :: ecut
409 : : integer,intent(out) :: mpw, gmax(3)
410 : : integer,parameter :: istwfk1 = 1
411 : : !real(dp) :: cpu, wall, gflops !weight_k,
412 : : !type(gqk_t),pointer :: gqk
413 : : !arrays
414 : : integer :: my_gmax(3), onpw, ipw, ii, my_mpw, ierr
415 : 5 : integer,allocatable :: gtmp(:,:)
416 : : real(dp) :: kk(3)
417 : :
418 : : integer :: spin, my_ik
419 : :
420 : : !----------------------------------------------------------------------
421 : :
422 : 5 : mpw = 0; gmax = 0
423 : :
424 : : ! TODO: This is an hotspot due to the double loop over k and q.
425 : : ! Should use a geometrical approach to compute mpw and gmax.
426 : :
427 : 5 : call wrtout(std_out, " Computing mpw. This may take some time for dense k/q meshes...")
428 : : !call cwtime(cpu, wall, gflops, "start")
429 : :
430 : : !do my_is=1,gstore%my_nspins
431 : : ! gqk => gstore%gqk(my_is)
432 : : ! spin = gstore%my_spins(my_is)
433 [ + + ]: 10 : do spin =1, self%nsppol
434 : :
435 [ + + ]: 314 : do my_ik=1,self%my_nkpt_pnn
436 [ + + ]: 1216 : kk = self%my_kkpts_pnn(:, my_ik)
437 : :
438 : : ! Compute G sphere, returning npw. Note istwfk == 1.
439 [ - + ]: 304 : call get_kg(kk, istwfk1, ecut, self%cryst%gmet, onpw, gtmp)
440 : 304 : mpw = max(mpw, onpw)
441 [ + + ]: 69743 : do ipw=1,onpw
442 [ + + ]: 278060 : do ii=1,3
443 : 277756 : gmax(ii) = max(gmax(ii), abs(gtmp(ii,ipw)))
444 : : end do
445 : : end do
446 [ - + ]: 309 : ABI_FREE(gtmp)
447 : : end do ! my_ik
448 : : end do ! my_is
449 : :
450 : 5 : my_mpw = mpw; call xmpi_max(my_mpw, mpw, self%comm, ierr)
451 : 5 : my_gmax = gmax; call xmpi_max(my_gmax, gmax, self%comm, ierr)
452 : :
453 : 5 : call wrtout(std_out, sjoin(' Optimal value of mpw: ', itoa(mpw)))
454 : : !call cwtime_report(" gmax and mpw", cpu, wall, gflops)
455 : :
456 [ - + ]: 5 : end subroutine wann_ksetting_get_mpw_gmax
457 : :
458 : :
459 : : !-----------------------------------------------------------------------------
460 : : !> Initialize the abstract_wf type, depending on the type of wavefunction
461 : : !> If the optional wfd, cg/cprj input are present, then the abstract_wf
462 : : !> is initialized as the wfd_wf type or the cg_cprj_wf type.
463 : : !> @param mywfc: the abstract_wf type
464 : : !> @param ebands: the ebands type
465 : : !> @param wfd: the wfd type (optional)
466 : : !> @param cg: the cg array (optional)
467 : : !> @param cprj: the cprj array (optional)
468 : : !> @param cryst: the crystal_t type
469 : : !> @param dtset: the dataset_type type
470 : : !> @param dtfil: the datafiles_type type
471 : : !> @param hdr: the header_type type
472 : : !> @param MPI_enreg: the mpi_type type
473 : : !> @param nprocs: the number of processors
474 : : !> @param psps: the psps_type type
475 : : !> @param pawtab: the pawtab_type type
476 : : !> @param rank: the rank of the processor
477 : : !> @param comm: the communicator
478 : : !-----------------------------------------------------------------------------
479 [ + + + - : 19 : subroutine init_mywfc(mywfc, ebands, wfd , cg, cprj, cryst, &
- + + + +
- - + ]
480 [ + - + - : 19 : & dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
- + ]
481 : : class(abstract_wf), pointer, intent(inout) :: mywfc
482 : : type(crystal_t), target, intent(in) :: cryst
483 : : type(ebands_t), target, optional, intent(in) :: ebands
484 : : type(wfd_t), target, optional, intent(inout) :: wfd
485 : : real(dp), target, optional, intent(in):: cg(:, :)
486 : : type(pawcprj_type), target, optional, intent(in):: cprj(:,:)
487 : : type(dataset_type),target, intent(in) :: dtset
488 : : type(datafiles_type),target, intent(in) :: dtfil
489 : : type(mpi_type), target, intent(inout) :: MPI_enreg
490 : : type(pseudopotential_type), target, intent(in) :: psps
491 : : type(pawtab_type), target, optional, intent(in) :: pawtab(:)
492 : : type(hdr_type), target, intent(in) :: hdr
493 : : integer, intent(in) :: nprocs, rank, comm
494 : :
495 [ + + ]: 19 : if(present(cg)) then
496 [ - + ]: 14 : ABI_MALLOC_TYPE_SCALAR(cg_cprj, mywfc)
497 [ + - ]: 5 : else if (present(wfd)) then
498 [ - + + + : 815 : ABI_MALLOC_TYPE_SCALAR(wfd_wf, mywfc)
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + ]
499 : : end if
500 : : select type(mywfc)
501 : : type is(cg_cprj)
502 : : call mywfc%init( ebands=ebands, cg=cg, cprj=cprj, cryst=cryst, dtset=dtset, &
503 : : & dtfil=dtfil, hdr=hdr, MPI_enreg=mpi_enreg, nprocs=nprocs, &
504 [ - + - + : 14 : & psps=psps, pawtab=pawtab, rank=rank, comm=comm)
- + ]
505 : : type is(wfd_wf)
506 [ - + ]: 5 : call mywfc%init( ebands, wfd, cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
507 : : !call wfd_print_norm(mywfc%wfd, mywfc%hdr)
508 : : end select
509 : 19 : end subroutine init_mywfc
510 : :
511 : : !-----------------------------------------------------------------------------
512 : : !> Initialize the abstract_wf type, common part for both wfd_wf and cg_cprj
513 : : !> @param self: the abstract_wf type
514 : : !> @param ebands: the ebands type
515 : : !> @param cryst: the crystal_t type
516 : : !> @param dtset: the dataset_type type
517 : : !> @param dtfil: the datafiles_type type
518 : : !> @param hdr: the header_type type
519 : : !> @param MPI_enreg: the mpi_type type
520 : : !> @param nprocs: the number of processors
521 : : !> @param psps: the psps_type type
522 : : !> @param pawtab: the pawtab_type type
523 : : !> @param rank: the rank of the processor
524 : : !> @param comm: the communicator
525 : : !-----------------------------------------------------------------------------
526 [ + - + - : 19 : subroutine abstract_init(self, ebands, cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
- + ]
527 : : class(abstract_wf), intent(inout) :: self
528 : : type(crystal_t), target, intent(in) :: cryst
529 : : type(ebands_t), target, intent(in) :: ebands
530 : : type(dataset_type),target, intent(in) :: dtset
531 : : type(datafiles_type),target, intent(in) :: dtfil
532 : : type(mpi_type), target, intent(inout) :: MPI_enreg
533 : : type(pseudopotential_type), target, intent(in) :: psps
534 : : type(pawtab_type), target, optional, intent(in) :: pawtab(:)
535 : : type(hdr_type), target, intent(in) :: hdr
536 : : integer, intent(in) :: nprocs, rank, comm
537 : 19 : if(present(pawtab)) self%pawtab => pawtab
538 : 19 : self%ebands => ebands
539 : 19 : self%cryst => cryst
540 : 19 : self%dtset => dtset
541 : 19 : self%dtfil => dtfil
542 : 19 : self%hdr => hdr
543 : 19 : self%MPI_enreg => MPI_enreg
544 : 19 : self%psps => psps
545 : 19 : self%natom = hdr%natom
546 : 19 : self%nspinor = hdr%nspinor
547 : 19 : self%nsppol = hdr%nsppol
548 : 19 : self%mband= hdr%mband
549 : 19 : self%mkmem = dtset%mkmem
550 : 19 : self%nkpt = hdr%nkpt
551 : 19 : self%rank = rank
552 : 19 : self%nprocs = nprocs
553 : 19 : self%comm=comm
554 : 19 : end subroutine abstract_init
555 : :
556 : : !-----------------------------------------------------------------------------
557 : : !> get one element of the wavefunction for any abstract_wf type
558 : : !> @param self: the abstract_wf type
559 : : !> @param icplx: the complex flag
560 : : !> @param ig: the index of the G vector
561 : : !> @param ispinor: the index of the spinor
562 : : !> @param iband: the index of the band
563 : : !> @param ikpt: the index of the k point
564 : : !> @param isppol: the index of the spin polarization
565 : : !> @return: the element of the wavefunction
566 : : !-----------------------------------------------------------------------------
567 : 0 : function abstract_wf_cg_elem(self, icplx, ig, ispinor, iband, ikpt, isppol ) result(res)
568 : : class(abstract_wf), intent(inout) :: self
569 : : integer, intent(in) :: icplx, ig, ispinor, iband, ikpt, isppol
570 : : real(dp) :: res
571 : 0 : ABI_UNUSED_A(self)
572 : : ABI_UNUSED(icplx)
573 : : ABI_UNUSED(ig)
574 : : ABI_UNUSED(ispinor)
575 : : ABI_UNUSED(iband)
576 : : ABI_UNUSED(ikpt)
577 : : ABI_UNUSED(isppol)
578 : : ABI_UNUSED(res)
579 : 0 : ABI_ERROR("Function should be overrided:")
580 : 0 : end function abstract_wf_cg_elem
581 : :
582 : : !-----------------------------------------------------------------------------
583 : : !> get one element of the wavefunction for any abstract_wf type, complex version
584 : : !-----------------------------------------------------------------------------
585 : 0 : function abstract_wf_cg_elem_complex(self, ig, ispinor, iband, ikpt, isppol ) result(res)
586 : : class(abstract_wf), intent(inout) :: self
587 : : integer, intent(in) :: ig, ispinor, iband, ikpt, isppol
588 : : complex(dp) :: res
589 : 0 : ABI_UNUSED_A(self)
590 : : ABI_UNUSED(ig)
591 : : ABI_UNUSED(ispinor)
592 : : ABI_UNUSED(iband)
593 : : ABI_UNUSED(ikpt)
594 : : ABI_UNUSED(isppol)
595 : : ABI_UNUSED(res)
596 : 0 : ABI_ERROR("Function should be overrided:")
597 : 0 : end function abstract_wf_cg_elem_complex
598 : :
599 : : !-----------------------------------------------------------------------------
600 : : !> get a block of the wavefunction for any abstract_wf type.
601 : : !> It should be overrided for each type.
602 : : !> @param self: the abstract_wf type
603 : : !> @param ikpt2: the index of the k point
604 : : !> @param isppol: the index of the spin polarization
605 : : !> @param cg_read: the wavefunction block
606 : : !-----------------------------------------------------------------------------
607 : 0 : subroutine abstract_wf_load_cg(self, ikpt2, isppol, cg_read)
608 : : class(abstract_wf), intent(inout) :: self
609 : : integer, intent(in) :: ikpt2, isppol
610 : : real(dp), intent(inout) :: cg_read(:, :) ! (2, nspinor*mpw*mband )
611 : 0 : ABI_UNUSED_A(self)
612 : : ABI_UNUSED(ikpt2)
613 : : ABI_UNUSED(isppol)
614 : : ABI_UNUSED(cg_read)
615 : 0 : ABI_ERROR("This function abstarct_wf_load_cg should be overrided.")
616 : 0 : end subroutine abstract_wf_load_cg
617 : :
618 : :
619 : :
620 : : !-----------------------------------------------------------------------------
621 : : !> get one cprj element of the wavefunction for any abstract_wf type, complex version,
622 : : !> @param self: the abstract_wf type
623 : : !> @param icplx: the complex flag
624 : : !> @param ispinor: the index of the spinor
625 : : !> @param iband: the index of the band
626 : : !> @param ikpt: the index of the k point
627 : : !> @param isppol: the index of the spin polarization
628 : : !> @param iatom: the index of the atom
629 : : !> @param ilmn: the index of the lmn
630 : : !> @return: the element of the wavefunction
631 : : !-----------------------------------------------------------------------------
632 : 0 : function abstract_wf_cprj_elem(self,icplx,ispinor, iband, ikpt, isppol, iatom, ilmn) result(res)
633 : : class(abstract_wf), intent(inout) :: self
634 : : integer, intent(in) :: icplx, ispinor, iband, ikpt, isppol, ilmn, iatom
635 : : real(dp) :: res
636 : 0 : ABI_UNUSED_A(self)
637 : : ABI_UNUSED(icplx)
638 : : ABI_UNUSED(ispinor)
639 : : ABI_UNUSED(iband)
640 : : ABI_UNUSED(ikpt)
641 : : ABI_UNUSED(isppol)
642 : : ABI_UNUSED(iatom)
643 : : ABI_UNUSED(ilmn)
644 : : ABI_UNUSED(res)
645 : 0 : ABI_ERROR("Function should be overrided:")
646 : 0 : end function abstract_wf_cprj_elem
647 : :
648 : : !-----------------------------------------------------------------------------
649 : : !> get a pointer to the cg part of wavefunction for any abstract_wf type.
650 : : !> It should be overrided for each type.
651 : : !> @param self: the abstract_wf type
652 : : !> @return: the pointer to the wavefunction block, in the form of a 2D array.
653 : : !-----------------------------------------------------------------------------
654 : : function abstract_wf_get_cg_ptr(self) result(cg)
655 : : class(abstract_wf), target, intent(inout) :: self
656 : : real(dp), pointer :: cg(:,:)
657 : : ABI_UNUSED_A(self)
658 : : ABI_UNUSED(cg)
659 : : ABI_ERROR("The function abstract_wf%get_cg_ptr is not implemented")
660 : : end function abstract_wf_get_cg_ptr
661 : :
662 : : !-----------------------------------------------------------------------------
663 : : !> get a pointer to the cprj part of wavefunction for any abstract_wf type.
664 : : !> It should be overrided for each type.
665 : : !> @param self: the abstract_wf type
666 : : !> @return: the pointer to the wavefunction block, in the form of a 2D array.
667 : : !-----------------------------------------------------------------------------
668 : 0 : function abstract_wf_get_cprj_ptr(self) result(cprj)
669 : : class(abstract_wf), target, intent(inout) :: self
670 : : type(pawcprj_type), pointer :: cprj(:, :)
671 : 0 : ABI_UNUSED_A(self)
672 : 0 : ABI_UNUSED_A(cprj)
673 : 0 : ABI_ERROR("The function abstract_wf%get_cprj_ptr is not implemented")
674 : 0 : end function abstract_wf_get_cprj_ptr
675 : :
676 : : !-----------------------------------------------------------------------------
677 : : !> get a pointer to the kg of wavefunction for any abstract_wf type.
678 : : !> @param self: the abstract_wf type
679 : : !> @return: the pointer to the kg, in the form of a 2D array.
680 : : !-----------------------------------------------------------------------------
681 [ - + ]: 5 : subroutine abstract_wf_get_kgs(self, ptr_kg)
682 : : class(abstract_wf), intent(inout) :: self
683 : : integer, intent(inout) :: ptr_kg(:, :)
684 : : integer :: npw_k, ik, ikg, ik_me
685 : : real(dp) :: ecut_eff
686 : 5 : integer, allocatable :: kg_k(:,:)
687 : : integer, parameter :: istwfk_1=1
688 [ + + + + ]: 288165 : ptr_kg(:,:)=zero
689 : : !ecut_eff = dtset%ecut * dtset%dilatmx **2
690 : 5 : ecut_eff=self%hdr%ecut_eff
691 : 5 : ikg=0
692 [ + + ]: 309 : do ik=1, self%kset%my_nkpt
693 : 304 : ik_me = self%kset%my_ikpts(ik)
694 : 304 : npw_k = self%hdr%npwarr(ik_me)
695 : : call get_kg(self%ebands%kptns(:,ik_me),istwfk_1,ecut_eff, &
696 [ - + ]: 304 : & self%cryst%gmet,npw_k,kg_k)
697 [ + + + + ]: 278060 : ptr_kg(:,1+ikg:npw_k+ikg)=kg_k(:, :) !wfd%Kdata(ik)%kg_k(:,:)
698 : 304 : ikg =ikg+npw_k
699 [ - + ]: 309 : ABI_FREE(kg_k)
700 : : end do
701 [ - + ]: 5 : end subroutine abstract_wf_get_kgs
702 : :
703 : :
704 : : !-----------------------------------------------------------------------------
705 : : !> free the memory of the abstract_wf type
706 : : !-----------------------------------------------------------------------------
707 : 33 : subroutine abstract_wf_free(self)
708 : : class(abstract_wf), intent(inout) :: self
709 : 33 : call self%kset%free()
710 : 33 : nullify(self%cryst)
711 : 33 : nullify(self%dtset)
712 : 33 : nullify(self%dtfil)
713 : 33 : nullify(self%hdr)
714 : 33 : nullify(self%MPI_enreg)
715 : 33 : nullify(self%psps)
716 : 33 : nullify(self%pawtab)
717 : 33 : end subroutine abstract_wf_free
718 : :
719 : : ! subroutine show_info(self)
720 : : ! class(abstract_wf), intent(inout) :: self
721 : : ! ! cg_elem
722 : : ! integer :: ipw=3, ispinor=1, ikpt=2, iband=4, isppol=1
723 : : ! print *, "========showing wf info=============="
724 : : ! print *, "ipw:", ipw, " ispinor:", ispinor, " ikpt:", ikpt, " iband:", iband, " isppol:", isppol
725 : : ! print *, "cg_elem:", self%cg_elem_complex(ipw, ispinor, ikpt, iband, isppol)
726 : : ! print *, "====end showing wf info=============="
727 : : ! end subroutine show_info
728 : :
729 : : !-----------------------------------------------------------------------------
730 : : !> free the memory of the wfd_wf type
731 : : !-----------------------------------------------------------------------------
732 : 5 : subroutine wfd_wf_free(self)
733 : : class(wfd_wf), intent(inout) :: self
734 : : ! TODO reenable this
735 [ + - ]: 5 : if (self%expanded) then
736 : 5 : call self%wfd_bz%free()
737 : 5 : call self%hdr_bz%free()
738 : 5 : call self%ebands_bz%free()
739 : 5 : call self%dtset_bz%free()
740 : : !call self%mpi_enreg_bz%free()
741 [ - + ]: 5 : ABI_FREE(self%bz2ibz)
742 [ - + ]: 5 : ABI_FREE(self%bks_mask)
743 [ - + ]: 5 : ABI_FREE(self%keep_ur)
744 : : end if
745 : 5 : call self%abstract_wf%free()
746 : :
747 : 5 : end subroutine wfd_wf_free
748 : :
749 : :
750 : : !-----------------------------------------------------------------------------
751 : : !> Initialize the wfd_wf type
752 : : !-----------------------------------------------------------------------------
753 [ + - + - : 5 : subroutine wfd_wf_init(self, ebands, wfd,cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
- + ]
754 : : class(wfd_wf), target, intent(inout) :: self
755 : : type(ebands_t), target, intent(in) :: ebands
756 : : type(crystal_t), target, intent(in) :: cryst
757 : : type(wfd_t), target, intent(inout) :: wfd
758 : : type(dataset_type),target, intent(in) :: dtset
759 : : type(datafiles_type),target, intent(in) :: dtfil
760 : : type(mpi_type), target, intent(inout) :: MPI_enreg
761 : : type(pseudopotential_type), target, intent(in) :: psps
762 : : type(pawtab_type), target, optional, intent(in) :: pawtab(:)
763 : : type(hdr_type), target, intent(in) :: hdr
764 : : integer, intent(in) :: nprocs, rank, comm
765 : :
766 : :
767 : :
768 : 5 : self%comm=comm
769 : 5 : self%rank=rank
770 : 5 : self%nprocs=nprocs
771 : : !print *, "set mpi info to wfd_wf", "self%comm", "self%rank", "self%nprocs"
772 : :
773 : 5 : self%expanded=(dtset%kptopt==1 .or. dtset%kptopt==2)
774 [ + - ]: 5 : if (self%expanded) then
775 : : ! expand the kpoints to the full BZ
776 : 5 : self%expanded=.True.
777 : 5 : self%ebands_ibz => ebands
778 : 5 : self%wfd_ibz => wfd
779 : 5 : self%hdr_ibz => hdr
780 : 5 : call ebands_and_hdr_expandk()
781 : : call self%kset%init(cryst=cryst,nkpt=self%hdr_bz%nkpt, mband=self%hdr_bz%mband, &
782 : : & nsppol=self%hdr_bz%nsppol,kkpts= self%hdr_bz%kptns, &
783 : 5 : & comm=self%comm, nprocs=self%nprocs, rank=self%rank)
784 : :
785 : 5 : self%hdr=> self%hdr_bz
786 : 5 : call set_fake_ovikp()
787 : :
788 : 5 : call wfd_expandk()
789 : 5 : self%wfd=> self%wfd_bz
790 : 5 : call dtset_expandk()
791 : : call self%abstract_wf%abstract_init(self%ebands_bz, cryst, self%dtset_bz, dtfil, &
792 [ - + ]: 5 : & self%hdr_bz, MPI_enreg, nprocs, psps, pawtab, rank, comm)
793 : : else ! the kpoints are already in the full BZ and does not need to be expanded
794 : 0 : self%expanded=.False.
795 : 0 : self%wfd => wfd
796 : 0 : self%ebands => ebands
797 : 0 : self%hdr=> hdr
798 : : call self%kset%init(cryst=cryst,nkpt=hdr%nkpt, mband=hdr%mband, &
799 : : & nsppol=hdr%nsppol,kkpts= hdr%kptns, &
800 : 0 : & comm=self%comm, nprocs=self%nprocs, rank=self%rank)
801 : 0 : call set_fake_ovikp()
802 [ # # ]: 0 : call self%abstract_wf%abstract_init(ebands,cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
803 : : end if
804 : : contains
805 : :
806 : : !-----------------------------------------------------------------------------
807 : : !> subsubroutine of wfd_wf_init
808 : : !> set the ovikp of the kset. fake means that all the kpoints are assumed to be neighbors
809 : : !-----------------------------------------------------------------------------
810 : 5 : subroutine set_fake_ovikp()
811 : 10 : integer :: ovikp(self%hdr%nkpt, 1), i
812 [ + + ]: 309 : do i=1, self%hdr%nkpt
813 : 309 : ovikp(i, 1)=i
814 : : end do
815 : 5 : call self%kset%set_ovikp(ovikp, 1 , 1, mpi_enreg)
816 : 5 : end subroutine set_fake_ovikp
817 : :
818 : :
819 : :
820 : : !-----------------------------------------------------------------------------
821 : : !> subsubroutine of wfd_wf_init
822 : : !> expand the kpoints to the full BZ
823 : : !-----------------------------------------------------------------------------
824 : 5 : subroutine dtset_expandk()
825 : : integer :: nkpt
826 [ - + - + : 5 : self%dtset_bz = dtset%copy()
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + ]
827 [ - + ]: 5 : ABI_FREE(self%dtset_bz%kpt)
828 [ - + ]: 5 : ABI_FREE(self%dtset_bz%kptns)
829 [ - + ]: 5 : ABI_FREE(self%dtset_bz%istwfk)
830 [ - + ]: 5 : ABI_FREE(self%dtset_bz%nband)
831 [ - + ]: 5 : ABI_FREE(self%dtset_bz%wtk)
832 : 5 : nkpt=self%ebands_bz%nkpt
833 : 5 : self%dtset_bz%kptopt=3
834 : 5 : self%dtset_bz%nkpt = nkpt
835 [ - + + - : 15 : ABI_MALLOC(self%dtset_bz%kpt, (3,nkpt))
+ - + - -
+ - + -
+ ]
836 [ - + + - : 10 : ABI_MALLOC(self%dtset_bz%kptns, (3,nkpt ))
- + - + -
+ ]
837 [ - + + - : 15 : ABI_MALLOC(self%dtset_bz%istwfk, (nkpt ))
+ - + - -
+ - + -
+ ]
838 [ - + + - : 10 : ABI_MALLOC(self%dtset_bz%nband, (nkpt ))
- + - + -
+ ]
839 [ - + + - : 15 : ABI_MALLOC(self%dtset_bz%wtk, (nkpt))
+ - + - -
+ - + -
+ ]
840 [ + + + + ]: 1221 : self%dtset_bz%kpt(:,:) = self%ebands_bz%kptns(:,:)
841 [ + + + + ]: 1221 : self%dtset_bz%kptns(:,:) = self%ebands_bz%kptns(:,:)
842 [ + + ]: 309 : self%dtset_bz%istwfk(:) = 1
843 [ + + ]: 309 : self%dtset_bz%nband(:) = self%hdr_bz%nband(:)
844 [ + + ]: 309 : self%dtset_bz%wtk(:) = self%hdr_bz%wtk(:)
845 : 5 : self%dtset_bz%mkmem = self%kset%my_nkpt
846 : 5 : end subroutine dtset_expandk
847 : :
848 : : !-----------------------------------------------------------------------------
849 : : !> subsubroutine of wfd_wf_init
850 : : !> expand the ebands and hdr to the full BZ
851 : : !-----------------------------------------------------------------------------
852 : 5 : subroutine ebands_and_hdr_expandk()
853 : : real(dp) :: ecut_eff, dksqmax
854 : 5 : type(wvl_internal_type) :: dummy_wvl
855 : : integer:: kptopt3=3
856 : : character(len=200) :: msg
857 : : ! NOTE: is this OK to assume so?
858 : 5 : ecut_eff = dtset%ecut * dtset%dilatmx **2
859 : : call ebands%expandk(cryst=cryst, ecut_eff=ecut_eff, &
860 : : & force_istwfk1=.True., dksqmax=dksqmax, &
861 [ - + ]: 5 : & bz2ibz=self%bz2ibz, outb=self%ebands_bz)
862 : : ! Note: test if force_istwfk1 is not set to True, force rotate
863 [ - + ]: 5 : if (dksqmax > tol12) then
864 : : write(msg, '(3a,es16.6,4a)' )&
865 : 0 : 'At least one of the k points could not be generated from a symmetrical one.',ch10,&
866 : 0 : 'dksqmax=',dksqmax,ch10,&
867 : 0 : 'Action: check your WFK file and k-point input variables',ch10,&
868 : 0 : ' (e.g. kptopt or shiftk might be wrong in the present dataset or the preparatory one.'
869 : 0 : ABI_ERROR(msg)
870 : : end if
871 : :
872 : : call self%hdr_bz%init_lowlvl(self%ebands_bz,psps,pawtab,dummy_wvl,abinit_version,&
873 : : hdr%pertcase,hdr%natom,hdr%nsym,hdr%nspden,hdr%ecut,dtset%pawecutdg,hdr%ecutsm,dtset%dilatmx,&
874 : : hdr%intxc,hdr%ixc,hdr%stmbias,hdr%usewvl,dtset%pawcpxocc,dtset%pawspnorb,dtset%ngfft,dtset%ngfftdg,hdr%so_psp,&
875 : : hdr%qptn,cryst%rprimd,cryst%xred,hdr%symrel,hdr%tnons,hdr%symafm,hdr%typat,hdr%amu,hdr%icoulomb,&
876 : : kptopt3,dtset%nelect,dtset%ne_qFD,dtset%nh_qFD,dtset%ivalence,dtset%cellcharge(1),&
877 : : dtset%kptrlatt_orig,dtset%kptrlatt,&
878 [ - + - - : 5 : dtset%nshiftk_orig,dtset%nshiftk,dtset%shiftk_orig,dtset%shiftk)
- - - + ]
879 : : ! End CP modified
880 : :
881 [ - + ]: 5 : if (psps%usepaw == 1) call pawrhoij_copy(hdr%pawrhoij, self%hdr_bz%pawrhoij)
882 : 5 : end subroutine ebands_and_hdr_expandk
883 : :
884 : : !-----------------------------------------------------------------------------
885 : : !> subsubroutine of wfd_wf_init
886 : : !> whether the kpoint is irreducible
887 : : !@param[in] ik the index of the kpoint in the full BZ
888 : : !@return true if the kpoint is irreducible
889 : : !-----------------------------------------------------------------------------
890 : : logical function isirr(ik)
891 : : integer, intent(in) :: ik
892 : : integer :: isym, itimrev, g0(3)
893 : : !ik_ibz = bz2ibz(ikf,1)
894 : : isym = self%bz2ibz(ik,2)
895 : : itimrev = self%bz2ibz(ik,6)
896 : : g0 = self%bz2ibz(ik,3:5) ! IS(k_ibz) + g0 = k_bz
897 : : isirr = (isym == 1 .and. itimrev == 0 .and. all(g0 == 0))
898 : : end function isirr
899 : :
900 : :
901 : : !-----------------------------------------------------------------------------
902 : : !> subsubroutine of wfd_wf_init
903 : : !> expand the wavefunctions to the full BZ
904 : : !-----------------------------------------------------------------------------
905 : 5 : subroutine wfd_expandk()
906 : 5 : integer, allocatable :: istwfk(:)
907 : : integer :: ik, spin, band
908 : 5 : complex(gwp), allocatable :: ug(:)
909 : : integer :: work_ngfft(18),gmax(3),indkk(6,1)
910 : 5 : real(dp),allocatable :: work(:,:,:,:), cg_kbz(:, :, :)
911 : : integer ::mpw, mband, npw_kbz, npw_check, size, ik_ibz
912 : 5 : integer,allocatable :: kg_kbz(:,:), kg_check(:,:)
913 : : real(dp):: kk_bz(3), kk_ibz(3)
914 : : character(len=500) :: msg
915 : :
916 : 5 : mband= dtset%mband
917 [ - + + - : 15 : ABI_MALLOC(istwfk, (self%ebands_bz%nkpt))
+ - + - -
+ - + ]
918 [ + + ]: 309 : istwfk(:) = 1
919 : :
920 : 5 : call self%kset%get_mpw_gmax(dtset%ecut, mpw, gmax)
921 : :
922 : : !mpw = maxval(self%hdr_bz%npwarr)
923 : 5 : mband = self%hdr_bz%mband
924 : : !call gstore%get_mpw_gmax(ecut, mpw, gmax)
925 [ + + ]: 20 : gmax = gmax + 4 ! FIXME: this is to account for umklapp
926 [ + + ]: 20 : gmax = 2*gmax + 1
927 : 5 : call ngfft_seq(work_ngfft, gmax)
928 : :
929 : :
930 [ - + + - : 25 : ABI_MALLOC(work, (2, work_ngfft(4), work_ngfft(5), work_ngfft(6)))
- + + - -
+ + - + -
+ - - + -
+ ]
931 [ - + + - : 15 : ABI_MALLOC(kg_kbz, (3, mpw))
+ - + - -
+ - + ]
932 [ - + + - : 20 : ABI_MALLOC(cg_kbz, (2, mpw*self%hdr_bz%nspinor, self%hdr_bz%mband))
- + + - +
- + - - +
- + ]
933 : :
934 : :
935 : : call self%kset%get_bks_mask( bks_mask=self%bks_mask, keep_ur=self%keep_ur, &
936 : 5 : & nband=self%hdr_bz%mband, nsppol=hdr%nsppol, keep_ur_value=.False.)
937 [ + + + + : 3642 : self%bks_mask(:,:,:)=.True.
+ + ]
938 : : call self%wfd_bz%init(Cryst=cryst,Pawtab=pawtab,Psps=psps, &
939 : : & keep_ur=self%keep_ur,mband=self%hdr_bz%mband,nband=self%ebands_bz%nband, &
940 : : &nkibz=self%ebands_bz%nkpt,nsppol=dtset%nsppol,bks_mask=self%bks_mask,&
941 : : &nspden=dtset%nspden,nspinor=hdr%nspinor,ecut=dtset%ecut, &
942 : : &ecutsm=dtset%ecutsm,dilatmx=dtset%dilatmx, &
943 : : &istwfk=istwfk,kibz=self%ebands_bz%kptns,ngfft=wfd%ngfft, &
944 : : &nloalg=wfd%nloalg,prtvol=dtset%prtvol,pawprtvol=dtset%pawprtvol,comm=comm,&
945 [ - + - - : 5 : & use_fnl_dir0der0 = .False.) ! optional
- - - + ]
946 : :
947 [ + + ]: 10 : do spin =1, dtset%nsppol
948 [ + + ]: 314 : do ik=1, self%ebands_bz%nkpt
949 [ + + + + : 4566752 : work(:, :, :, :) =0.0_dp
+ + + + ]
950 [ + + + + ]: 288464 : kg_kbz(:, :)=0
951 [ + + + + : 2299856 : cg_kbz(:, :, :)=0.0_dp
+ + ]
952 : 304 : npw_kbz=self%hdr_bz%npwarr(ik)
953 : 304 : size =self%hdr_bz%nspinor*npw_kbz
954 : : !print *, "size", npw_kbz
955 : : !print *, "size", size
956 [ + + ]: 2128 : indkk(:, 1) = self%bz2ibz(ik,: )
957 : : !TODO: ecut or ecut_eff?
958 : : !print *, "indkk: ", indkk(:, 1)
959 : :
960 : 304 : ik_ibz =self%bz2ibz(ik, 1)
961 [ + + ]: 1216 : kk_bz=self%ebands_bz%kptns(:, ik)
962 [ + + ]: 1216 : kk_ibz=self%ebands_ibz%kptns(:,ik_ibz )
963 : :
964 : :
965 : : !Note that we use force_rotate here.
966 : : !Otherwise the sym_ug_kg gives different npw_kbz as in ebands_bz or hdr_bz.
967 : : !if the kpoint is in the IBZ.
968 : : call wfd%sym_ug_kg(ecut=dtset%ecut, &
969 : : & kk_bz=kk_bz, kk_ibz=kk_ibz, bstart=1, nband=mband, &
970 : : & spin=spin, mpw=mpw, indkk=indkk, cryst=cryst, &
971 : : & work_ngfft=work_ngfft, work=work, istwf_kbz=istwfk(ik), &
972 : : & npw_kbz=npw_kbz, kg_kbz=kg_kbz, cgs_kbz=cg_kbz, &
973 : 304 : & force_rotate=.True.)
974 : :
975 : : ! The rotated coefficients are stored in the order defined by kg_kbz.
976 : : ! get_kgs regenerates this list later for mlwfovlp, so both the set and
977 : : ! its ordering must agree exactly.
978 [ - + ]: 304 : call get_kg(kk_bz, 1, self%hdr_bz%ecut_eff, cryst%gmet, npw_check, kg_check)
979 : 304 : write(msg, '(a,i0,a,i0,a,i0)') "Inconsistent plane-wave count at full-BZ k-point ", ik, &
980 : 608 : ": sym_ug_kg gives ", npw_kbz, ", get_kg gives ", npw_check
981 [ - + ]: 304 : ABI_CHECK(npw_check == npw_kbz, msg)
982 : 304 : write(msg, '(a,i0)') "Inconsistent G-vector ordering at full-BZ k-point ", ik
983 [ + + + + : 278060 : ABI_CHECK(all(kg_check(:,1:npw_check) == kg_kbz(:,1:npw_kbz)), msg)
+ - - + ]
984 [ - + ]: 304 : ABI_FREE(kg_check)
985 : :
986 : 304 : self%hdr_bz%npwarr(ik)=npw_kbz
987 : 304 : self%ebands_bz%npwarr(ik)=npw_kbz
988 : 304 : self%wfd_bz%npwarr(ik)=npw_kbz
989 : 304 : size =self%hdr_bz%nspinor*npw_kbz
990 [ - + + - : 912 : ABI_MALLOC(ug, (size))
+ - + - -
+ - + -
+ ]
991 [ + + ]: 3632 : do band = 1, self%ebands_bz%nband(ik)
992 [ + + ]: 739804 : ug(:)= cmplx(cg_kbz(1, 1:size,band), cg_kbz(2, 1:size, band), kind=gwp)
993 : : !ug(:) = ug(:) / sqrt(sum(cg_kbz(:, 1:size, band)**2))
994 : : call self%wfd_bz%push_ug(band, ik, spin, Cryst,ug, &
995 : 3632 : & update_ur=.True., update_cprj=.False.)
996 : : end do
997 [ - + ]: 309 : ABI_FREE(ug)
998 : : end do
999 : : end do
1000 : :
1001 [ - + ]: 5 : ABI_FREE(cg_kbz)
1002 [ - + ]: 5 : ABI_FREE(kg_kbz)
1003 [ - + ]: 5 : ABI_FREE(work)
1004 [ - + ]: 5 : ABI_FREE(istwfk)
1005 [ - + - + ]: 5 : end subroutine wfd_expandk
1006 : :
1007 : :
1008 : : end subroutine wfd_wf_init
1009 : :
1010 : :
1011 : :
1012 : : !
1013 : : ! subroutine wfd_build_cache(self, iband, ik, isppol)
1014 : : ! class(wfd_wf), intent(inout) :: self
1015 : : ! integer, intent(in) :: iband, ik, isppol
1016 : : ! integer :: ik_ibz, size
1017 : : ! ik_ibz=ik
1018 : : ! size = self%wfd%npwarr(ik_ibz) * self%wfd%nspinor
1019 : : ! if(allocated(self%cg_cache)) then
1020 : : ! ABI_FREE(self%cg_cache)
1021 : : ! end if
1022 : : ! ABI_MALLOC(self%cg_cache, (2, size))
1023 : : ! call self%wfd%copy_cg(iband, ik_ibz, isppol, self%cg_cache)
1024 : : ! self%iband_c = iband
1025 : : ! self%ikpt_c = ik
1026 : : ! self%isppol_c = isppol
1027 : : ! end subroutine wfd_build_cache
1028 : :
1029 : :
1030 : : ! subroutine wfd_wf_ug(self, iband, ikpt, isppol, ug )
1031 : : ! class(wfd_Wf), intent(inout) :: self
1032 : : ! integer, intent(in) :: iband, ikpt, isppol
1033 : : ! real(dp), intent(inout) :: ug(:, :)
1034 : : ! integer :: ik_ibz
1035 : : ! integer :: npw_k
1036 : : ! type(wave_t),pointer :: wave
1037 : : ! character(len=500) :: msg
1038 : : ! ik_ibz=ikpt
1039 : : ! !if(.not. (iband==self%iband_c .and. ikpt==self%ikpt_c .and. isppol==self%isppol_c)) then
1040 : : ! !print *, "Building cache for : ", iband, ikpt, isppol
1041 : : ! !call self%build_cache(iband, ikpt, isppol)
1042 : : ! !end if
1043 : : ! ABI_CHECK(self%wfd%get_wave_ptr(iband, ik_ibz, isppol, wave, msg) == 0, msg)
1044 : : ! if (.not. wave%has_ug == WFD_STORED) then
1045 : : ! write(msg,'(a,i0,a,3i0)')" Node ",self%wfd%my_rank," doesn't have (band,ik_ibz,spin): ",iband,ik_ibz,isppol
1046 : : ! ABI_BUG(msg)
1047 : : ! end if
1048 : : ! npw_k = self%Wfd%npwarr(ik_ibz)
1049 : : ! call xcopy(npw_k*self%Wfd%nspinor, wave%ug, 1, ug, 1)
1050 : : ! end subroutine wfd_wf_ug
1051 : :
1052 : :
1053 : : !---------------------------------------------------------------------
1054 : : !> get one element of the wavefunction in the wfd_Wf object
1055 : : !> override the abstract_wf method
1056 : : !---------------------------------------------------------------------
1057 : 459503616 : function wfd_cg_elem(self, icplx, ig, ispinor, iband, ikpt, isppol ) result(res)
1058 : : class(wfd_Wf), intent(inout) :: self
1059 : : integer, intent(in) :: icplx, ig, ispinor, iband, ikpt, isppol
1060 : : integer :: ik_ibz
1061 : : real(dp) :: res
1062 : : complex(dp) :: t
1063 : : integer :: npw_k
1064 : : type(wave_t),pointer :: wave
1065 : : character(len=500) :: msg
1066 : 459503616 : ik_ibz=ikpt
1067 : : !if(.not. (iband==self%iband_c .and. ikpt==self%ikpt_c .and. isppol==self%isppol_c)) then
1068 : : !print *, "Building cache for : ", iband, ikpt, isppol
1069 : : !call self%build_cache(iband, ikpt, isppol)
1070 : : !end if
1071 [ - + ]: 459503616 : ABI_CHECK(self%wfd%get_wave_ptr(iband, ik_ibz, isppol, wave, msg) == 0, msg)
1072 [ - + ]: 459503616 : if (.not. wave%has_ug == WFD_STORED) then
1073 : 0 : write(msg,'(a,i0,a,3i0)')" Node ",self%wfd%my_rank," doesn't have (band,ik_ibz,spin): ",iband,ik_ibz,isppol
1074 : 0 : ABI_BUG(msg)
1075 : : end if
1076 : 459503616 : npw_k = self%Wfd%npwarr(ik_ibz)
1077 : : !call xcopy(npw_k*Wfd%nspinor, wave%ug, 1, ug, 1)
1078 : : !res = self%cg_cache(icplx, ig+self%hdr%npwarr(ik_ibz)*(ispinor-1))
1079 : 459503616 : t = wave%ug(ig+self%hdr%npwarr(ik_ibz)*(ispinor-1))
1080 : 689255424 : select case(icplx)
1081 : : case(1)
1082 : 229751808 : res = real(t)
1083 : : case(2)
1084 : 229751808 : res = aimag(t)
1085 : : case default
1086 [ + + - ]: 459503616 : res=-999999.99_dp
1087 : : end select
1088 : 459503616 : end function wfd_cg_elem
1089 : :
1090 : : !---------------------------------------------------------------------
1091 : : !> get one element of the wavefunction in the wfd_Wf object, complex version
1092 : : !> override the abstract_wf method
1093 : : !---------------------------------------------------------------------
1094 : 1756336 : function wfd_cg_elem_complex(self, ig, ispinor, iband, ikpt, isppol ) result(res)
1095 : : class(wfd_wf), intent(inout) :: self
1096 : : integer, intent(in) :: ig, ispinor, iband, ikpt, isppol
1097 : : complex(dp) :: res
1098 : : integer :: ik_ibz
1099 : : integer :: npw_k
1100 : : type(wave_t),pointer :: wave
1101 : : character(len=500) :: msg
1102 : 1756336 : ik_ibz=ikpt
1103 [ - + ]: 1756336 : ABI_CHECK(self%wfd%get_wave_ptr(iband, ik_ibz, isppol, wave, msg) == 0, msg)
1104 [ - + ]: 1756336 : if (.not. wave%has_ug == WFD_STORED) then
1105 : 0 : write(msg,'(a,i0,a,3i0)')" Node ",self%wfd%my_rank," doesn't have (band,ik_ibz,spin): ",iband,ik_ibz,isppol
1106 : 0 : ABI_BUG(msg)
1107 : : end if
1108 : 1756336 : npw_k = self%Wfd%npwarr(ik_ibz)
1109 : 1756336 : res = wave%ug(ig+self%hdr%npwarr(ik_ibz)*(ispinor-1))
1110 : 1756336 : end function wfd_cg_elem_complex
1111 : :
1112 : : !---------------------------------------------------------------------
1113 : : !> get a block of the wavefunction in the wfd_Wf object
1114 : : !> override the abstract_wf method
1115 : : !---------------------------------------------------------------------
1116 [ # # ]: 0 : subroutine wfd_load_cg(self, ikpt2, isppol, cg_read)
1117 : : class(wfd_wf), intent(inout) :: self
1118 : : integer, intent(in) :: ikpt2, isppol
1119 : : real(dp), intent(inout) :: cg_read(:, :)
1120 : : integer :: iband, iblk, size
1121 : 0 : iblk=0
1122 : 0 : size=self%hdr%npwarr(ikpt2) * self%nspinor
1123 [ # # ]: 0 : do iband =1, self%mband
1124 [ # # # # : 0 : call self%wfd%copy_cg(iband, ikpt2, isppol, cg_read(:, iblk+1:iblk+size))
# # # # #
# ]
1125 : 0 : iblk = iblk + size
1126 : : end do
1127 : 0 : end subroutine wfd_load_cg
1128 : :
1129 : :
1130 : :
1131 : : !---------------------------------------------------------------------
1132 : : !> get one cprj element of the wavefunction in the wfd_Wf object
1133 : : !> override the abstract_wf method
1134 : : !---------------------------------------------------------------------
1135 : 0 : function wfd_cprj_elem(self,icplx,ispinor, iband, ikpt, isppol, iatom, ilmn) result(res)
1136 : : class(wfd_wf), intent(inout) :: self
1137 : : integer, intent(in) :: icplx, ispinor, iband, ikpt, isppol, ilmn, iatom
1138 : : real(dp) :: res
1139 [ # # # # : 0 : type(pawcprj_type) :: cprj_out(self%natom,self%nspinor)
# # # # #
# # # ]
1140 : :
1141 : : integer :: ik_ibz
1142 : : !TODO:
1143 : 0 : ik_ibz = ikpt
1144 : : !call self%wfd%ug2cprj(band=iband,ik_ibz=ik_ibz,spin=ispin,choice=1,idir=0,natom=self%natom,Cryst=self%Cryst ,cwaveprj,sorted=.False.)
1145 : : call self%wfd%get_cprj( band=iband, ik_ibz=ik_ibz, spin=isppol, &
1146 : 0 : & Cryst=self%cryst, Cprj_out=cprj_out, sorted=.False.)
1147 : 0 : res=cprj_out(iatom, ispinor)%cp(icplx, ilmn)
1148 : 0 : end function wfd_cprj_elem
1149 : :
1150 : :
1151 : : !---------------------------------------------------------------------
1152 : : !> get one cpaw element of the wavefunction in the wfd_Wf object, complex version
1153 : : !> override the abstract_wf method
1154 : : !---------------------------------------------------------------------
1155 [ + - + - : 14 : subroutine cg_cprj_init(self, ebands, cg, cprj, cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
- + + - +
- - + + -
+ - - + ]
1156 : : class(cg_cprj), intent(inout) :: self
1157 : : type(crystal_t), target, intent(in) :: cryst
1158 : : type(ebands_t), target, intent(in) :: ebands
1159 : : real(dp), target, optional, intent(in):: cg(:, :)
1160 : : type(pawcprj_type), target, optional, intent(in):: cprj(:,:)
1161 : : type(dataset_type),target, intent(in) :: dtset
1162 : : type(datafiles_type),target, intent(in) :: dtfil
1163 : : type(mpi_type), target, intent(inout) :: MPI_enreg
1164 : : type(pseudopotential_type), target, intent(in) :: psps
1165 : : type(pawtab_type), target, optional, intent(in) :: pawtab(:)
1166 : : type(hdr_type), target, intent(in) :: hdr
1167 : : integer, intent(in) :: nprocs, rank, comm
1168 [ - + ]: 14 : call self%abstract_wf%abstract_init(ebands, cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
1169 [ + - ]: 14 : if(present(cg)) self%cg=> cg
1170 [ + - ]: 14 : if(present(cprj) .and. present(pawtab)) then
1171 : 14 : self%has_paw=.True.
1172 : : end if
1173 [ + - ]: 14 : if(present(cprj)) then
1174 : : !print *, "cprj linked"
1175 : : !print *, "before linked", cprj(1,1)%cp(:,:)
1176 : 14 : self%cprj => cprj
1177 : : !print *, "after linked", self%cprj(1,1)%cp(:,:)
1178 : : end if
1179 [ - + + - : 84 : ABI_MALLOC(self%iwav,(self%nspinor, self%mband,self%nkpt,self%nsppol))
- + + - -
+ + - - +
+ - + - +
- - + -
+ ]
1180 : 14 : call compute_iwav(MPI_enreg, dtset, hdr, self%iwav, nprocs, rank)
1181 : 14 : call self%compute_index_cprj()
1182 [ - + ]: 14 : if(nprocs>1) then
1183 : 0 : call self%write_cg_and_cprj_tmpfile()
1184 : : end if
1185 : : !call self%show_info()
1186 : 14 : end subroutine cg_cprj_init
1187 : :
1188 : : !---------------------------------------------------------------------
1189 : : !> free the cg_cprj object ant the temporary files
1190 : : !---------------------------------------------------------------------
1191 : 14 : subroutine cg_cprj_free(self)
1192 : : class(cg_cprj), intent(inout) :: self
1193 [ - + ]: 14 : if(self%nprocs>1) then
1194 : 0 : call self%remove_tmpfile()
1195 : : end if
1196 : 14 : nullify(self%cg)
1197 : 14 : nullify(self%cprj)
1198 : 14 : call self%abstract_wf%free()
1199 [ - + ]: 14 : ABI_FREE(self%iwav)
1200 : 14 : nullify(self%iwav)
1201 [ - + ]: 14 : ABI_FREE(self%icprj)
1202 : 14 : call self%abstract_wf%free()
1203 : 14 : end subroutine cg_cprj_free
1204 : :
1205 : : ! return one entry of cg.
1206 : : ! parameters:
1207 : : ! icplx: 1 for real part, 2 for imaginary part
1208 : : ! ig: index of G vector
1209 : : ! ispinor: index of spinor
1210 : : ! iband: index of band
1211 : : ! ikpt: index of k point
1212 : : ! isppol: index of spin
1213 : 1570800548 : function cg_elem(self, icplx, ig, ispinor, iband, ikpt, isppol ) result(res)
1214 : : class(cg_cprj), intent(inout) :: self
1215 : : integer, intent(in) :: icplx, ig, ispinor, iband, ikpt, isppol
1216 : : integer :: ind
1217 : : real(dp) :: res
1218 : 1570800548 : ind=ig+self%iwav(ispinor, iband,ikpt,isppol)
1219 : 1570800548 : res=self%cg(icplx,ind)
1220 : 1570800548 : end function cg_elem
1221 : :
1222 : :
1223 : :
1224 : : ! return one entry of cg in complex form.
1225 : : ! Parameters:
1226 : : ! same as cg_elem, except that icplx is not needed.
1227 : 0 : function cg_elem_complex(self, ig,ispinor, iband, ikpt, isppol) result(res)
1228 : : class(cg_cprj), intent(inout) :: self
1229 : : integer, intent(in) :: ig, ispinor, iband, ikpt, isppol
1230 : : integer :: ind
1231 : : complex(dp) :: res
1232 : 0 : ind=ig+self%iwav(ispinor, iband,ikpt,isppol)
1233 : 0 : res=CMPLX(self%cg(1,ind), self%cg(2,ind), kind=dp)
1234 : 0 : end function cg_elem_complex
1235 : :
1236 : : !return a pointer to the cg array in the cg_cprj object.
1237 : : function cg_cprj_get_cg_ptr(self) result(cg)
1238 : : class(cg_cprj), target, intent(inout) :: self
1239 : : real(dp), pointer :: cg(:,:)
1240 : : cg=> self%cg
1241 : : end function cg_cprj_get_cg_ptr
1242 : :
1243 : : !return a pointer to the cprj array in the cg_cprj object.
1244 : 2944 : function cg_cprj_get_cprj_ptr(self) result(cprj)
1245 : : class(cg_cprj), target, intent(inout) :: self
1246 : : type(pawcprj_type), pointer :: cprj(:, :)
1247 : 2944 : cprj=>self%cprj
1248 : 2944 : end function cg_cprj_get_cprj_ptr
1249 : :
1250 : : !---------------------------------------------------------------------
1251 : : !> compute the index of the cprj array.
1252 : : !---------------------------------------------------------------------
1253 : 14 : subroutine compute_index_cprj(self)
1254 : : ! FIXME:hexu: this is modified from the m_mlwfovlp,
1255 : : ! but I think it should be carefully checked.
1256 : : ! mcprj=nspinor*mband*mkmem*nsppol
1257 : : ! 1. nspinor=2 case seems to be wrong.
1258 : : class(cg_cprj), intent(inout) :: self
1259 : : integer :: ii, ikpt, isppol, iband
1260 [ - + + - : 70 : ABI_MALLOC(self%icprj, (self%mband,self%nkpt,self%nsppol))
- + + - -
+ + - + -
+ - - + -
+ - + ]
1261 : 14 : ii=0
1262 [ + + ]: 29 : do isppol=1,self%nsppol
1263 : : ! FIXME: check if it should be mkmem or nkpt.
1264 [ + + ]: 429 : do ikpt=1,self%nkpt
1265 : : ! FIXME: nband has the shape of (nsppol*nkpt).
1266 : : !nband_k=dtset%nband(ikpt+(isppol-1)*nkpt)
1267 [ + + ]: 5615 : do iband=1,self%dtset%nband(ikpt)
1268 : : ! FIXME: hexu: should cycle if the kpt is not in this node??
1269 : 5200 : ii=ii+1
1270 : 5600 : self%icprj(iband,ikpt,isppol)=ii
1271 : : end do
1272 : : end do
1273 : : end do
1274 : 14 : end subroutine compute_index_cprj
1275 : :
1276 : :
1277 : : ! get one element of cprj
1278 : 0 : function cprj_elem(self,icplx,ispinor, iband, ikpt, isppol, iatom, ilmn) result(res)
1279 : : class(cg_cprj), intent(inout) :: self
1280 : : integer, intent(in) :: icplx, ispinor, iband, ikpt, isppol, ilmn, iatom
1281 : : real(dp) :: res
1282 : : integer :: ig
1283 : : ! TODO: this seems to be better than compute_index_cprj,
1284 : : ! But should it be mband or nband(ikpt)
1285 : :
1286 : : ! mcprj=nspinor*mband*mkmem*nsppol
1287 : : ! this is the original version in m_mlwfovlp
1288 : : !ig=iband+(ikpt-1)*self%mband*self%nspinor + &
1289 : : ! &(isppol-1)*self%mkmem*self%mband*self%nspinor
1290 : :
1291 : : ig=ispinor+(iband-1)*self%nspinor+(ikpt-1)*self%mband*self%nspinor + &
1292 : 0 : &(isppol-1)*self%mkmem*self%mband*self%nspinor
1293 : 0 : res= self%cprj(iatom, ig)%cp(icplx, ilmn)
1294 : 0 : end function cprj_elem
1295 : :
1296 : : !---------------------------------------------------------------------
1297 : : !> write cg and cprj to tmpfile
1298 : : !---------------------------------------------------------------------
1299 : 0 : subroutine write_cg_and_cprj_tmpfile(self)
1300 : : class(cg_cprj), intent(inout) :: self
1301 : : call write_cg_and_cprj(self%dtset, self%cg, self%cprj, self%dtfil, self%iwav, &
1302 : : & self%hdr%npwarr, self%mband, self%natom, &
1303 : : & self%nsppol, self%nkpt, self%MPI_enreg, &
1304 : 0 : & self%rank, self%psps, self%pawtab)
1305 : 0 : end subroutine write_cg_and_cprj_tmpfile
1306 : :
1307 : : !---------------------------------------------------------------------
1308 : : !> remove tmpfile of cg and cprj
1309 : : !---------------------------------------------------------------------
1310 : 0 : subroutine remove_tmpfile(self)
1311 : : class(cg_cprj), intent(inout) :: self
1312 : : integer :: isppol, ikpt, ierr
1313 : : integer :: master=1
1314 : : character(len=fnlen) :: wfnname
1315 : : character(len=500) :: message
1316 [ # # ]: 0 : if(self%dtset%prtvol>0) then
1317 : 0 : write(message, '(3a)' ) ch10,&
1318 : 0 : & ' mlwfovlp : Removing temporary files with cg and cprj (PAW)',ch10
1319 : 0 : call wrtout(ab_out,message,'COLL')
1320 : 0 : call wrtout(std_out, message,'COLL')
1321 : : end if
1322 : : !
1323 : : ! Just master node will remove the files
1324 : : !
1325 [ # # ]: 0 : if(self%rank==master) then
1326 [ # # ]: 0 : do isppol=1,self%nsppol
1327 [ # # ]: 0 : do ikpt=1,self%nkpt
1328 : 0 : write(wfnname,'(a,I5.5,".",I1)') trim(self%dtfil%fnametmp_cg),ikpt,isppol
1329 : 0 : call delete_file(wfnname,ierr)
1330 [ # # ]: 0 : if(self%psps%usepaw==1) then
1331 : 0 : write(wfnname,'(a,I5.5,".",I1)') trim(self%dtfil%fnametmp_cprj),ikpt,isppol
1332 : 0 : call delete_file(wfnname,ierr)
1333 : : end if
1334 : : end do !ikpt
1335 : : end do !isppol
1336 : : end if
1337 : 0 : end subroutine remove_tmpfile
1338 : :
1339 : :
1340 : : !---------------------------------------------------------------------
1341 : : !> read cg from tmpfile
1342 : : !@param[in] ikpt2 index of kpt
1343 : : !@param[in] isppol index of spin
1344 : : !@param[out] cg_read cg read from tmpfile
1345 : : !---------------------------------------------------------------------
1346 [ # # ]: 0 : subroutine load_cg(self, ikpt2, isppol, cg_read)
1347 : : class(cg_cprj), intent(inout) :: self
1348 : : integer, intent(in) :: ikpt2, isppol
1349 : : real(dp), intent(inout) :: cg_read(:, :)
1350 : : character(len=fnlen) :: cg_file
1351 : : integer :: npw_k2, ios, ii
1352 : : character(len=500) :: message
1353 : :
1354 : : integer :: iunit , iband2, ipw, index
1355 : 0 : write(cg_file,'(a,I5.5,".",I1)') trim(self%dtfil%fnametmp_cg),ikpt2,isppol
1356 : 0 : iunit=1000+ikpt2+ikpt2*(isppol-1)
1357 : 0 : npw_k2=self%hdr%npwarr(ikpt2)
1358 : :
1359 : 0 : open (unit=iunit, file=cg_file,form='unformatted',status='old',iostat=ios)
1360 [ # # ]: 0 : if(ios /= 0) then
1361 : 0 : write(message,*) " mlwfovlp_pw: file",trim(cg_file), "not found"
1362 : 0 : ABI_ERROR(message)
1363 : : end if
1364 : : !
1365 [ # # ]: 0 : do iband2=1,self%mband
1366 [ # # ]: 0 : do ipw=1,npw_k2*self%nspinor
1367 : 0 : index=ipw+(iband2-1)*npw_k2*self%nspinor
1368 : 0 : read(iunit) (cg_read(ii,index),ii=1,2)
1369 : : ! if(me==0 .and. ikpt2==4)write(300,*)'ipw,iband2,index',ipw,iband2,index,cg_read(:,index)
1370 : : ! if(me==1 .and. ikpt2==4)write(301,*)'ipw,iband2,index',ipw,iband2,index,cg_read(:,index)
1371 : : end do
1372 : : end do
1373 : 0 : close(iunit)
1374 : 0 : end subroutine load_cg
1375 : :
1376 : :
1377 : : !---------------------------------------------------------------------
1378 : : !> compute the index of the wavefunctions in the cg array
1379 : : !---------------------------------------------------------------------
1380 [ - + ]: 14 : subroutine compute_iwav(MPI_enreg, dtset, hdr, iwav, nprocs, rank)
1381 : : type(mpi_type), intent(in) :: MPI_enreg
1382 : : type(dataset_type), intent(in) :: dtset
1383 : : type(hdr_type), intent(in) :: hdr
1384 : : integer, intent(inout) :: iwav(:, :, :, :)
1385 : : ! dimension: (nspinor, mband,nkpt,nsppol))
1386 : : integer, intent(in) :: nprocs, rank
1387 : : character(len=500) :: message
1388 : 28 : integer :: icg(hdr%nsppol, hdr%nkpt)
1389 : : integer :: icgtemp, isppol, ikpt, nband_k, npw_k, iband, ispinor
1390 : :
1391 : 14 : write(message, '(a,a)' ) ch10,&
1392 : 28 : & ' mlwfovlp : compute shifts for g-points '
1393 : 14 : call wrtout(std_out, message,'COLL')
1394 : : !----------------------------------------------------------------------
1395 : : !Compute shifts for g points (icg,iwav)
1396 : : !(here mband is not used, because shifts are internal variables of abinit)
1397 : : !----------------------------------------------------------------------
1398 : : !write(std_out,*) mpw*dtset%nspinor*mband*mkmem*nsppol
1399 : : !ABI_MALLOC(icg,(nsppol,nkpt))
1400 [ + + + + ]: 750 : icg=0
1401 : 29 : icgtemp=0
1402 : : !ABI_MALLOC(iwav,(dtset%mband,nkpt,nsppol))
1403 [ + + + + : 12365 : iwav(:,:,:, :)=0
+ + + + ]
1404 [ + + ]: 29 : do isppol=1,hdr%nsppol
1405 [ + + ]: 429 : do ikpt=1,hdr%nkpt
1406 : : ! MPI:cycle over k-points not treated by this node
1407 [ - + ]: 400 : if (nprocs>1 ) then !sometimes we can have just one processor
1408 [ # # ]: 0 : if ( ABS(MPI_enreg%proc_distrb(ikpt,1,isppol)-rank) /=0) CYCLE
1409 : : end if
1410 : :
1411 : : ! write(std_out,*)'rank',rank,'ikpt',ikpt,'isppol',isppol
1412 : 400 : nband_k=dtset%nband(ikpt+(isppol-1)*hdr%nkpt)
1413 : : ! write(std_out,*) ikpt+(isppol-1)*nkpt,nkpt
1414 : 400 : npw_k=hdr%npwarr(ikpt)
1415 [ + + ]: 5615 : do iband=1,nband_k
1416 [ - + ]: 5200 : if(iband.gt. dtset%mband) then
1417 : 0 : write(message,'(a,3i0)')" mband",iband,dtset%mband,nband_k
1418 : 0 : ABI_ERROR(message)
1419 : : end if
1420 [ + + ]: 11936 : do ispinor =1, dtset%nspinor
1421 : : iwav(ispinor, iband,ikpt,isppol)= &
1422 : : !& (iband-1)*npw_k*dtset%nspinor+icgtemp &
1423 : 11936 : & (ispinor-1)*npw_k +icgtemp
1424 : : end do
1425 : : !icgtemp=icgtemp+ npw_k*dtset%nspinor*nband_k
1426 : 5600 : icgtemp = icgtemp + npw_k
1427 : : end do ! iband
1428 : : ! icg(isppol,ikpt)=icgtemp
1429 : : ! write(std_out,*) "icg", isppol,ikpt,icg(isppol,ikpt)
1430 : : end do ! ikpt
1431 : : end do ! isppol
1432 : : !write(std_out,*) "shift for cg computed"
1433 : : !
1434 : : !Shifts computed.
1435 : 14 : end subroutine compute_iwav
1436 : :
1437 : : !---------------------------------------------------------------------
1438 : : !> write the cg and cprj arrays into a list of files
1439 : : !> The name of the files are given by dtset%fnametmp_cg and dtset%fnametmp_cprj
1440 : : !> The files are written in unformatted format
1441 : : !---------------------------------------------------------------------
1442 [ # # # # ]: 0 : subroutine write_cg_and_cprj(dtset, cg, cprj, dtfil, iwav, npwarr, mband, natom, &
1443 [ # # # # ]: 0 : &nsppol, nkpt, MPI_enreg, rank, psps, pawtab)
1444 : :
1445 : : type(dataset_type),intent(in) :: dtset
1446 : : type(MPI_type),intent(in) :: mpi_enreg
1447 : : type(datafiles_type),intent(in) :: dtfil
1448 : : integer,intent(in):: iwav(:,:,:,:)
1449 : : real(dp),intent(in) :: cg(:, :)
1450 : : type(pawcprj_type), intent(in) :: cprj(:, :)
1451 : : integer, intent(in) :: rank, nsppol, nkpt, mband, natom
1452 : : integer, intent(in) :: npwarr(nkpt)
1453 : : type(pseudopotential_type),intent(in) :: psps
1454 : : !type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
1455 : : type(pawtab_type),intent(in) :: pawtab(:)
1456 : :
1457 : : integer :: ikpt, ikpt2, isppol, iun_plot, npw_k, iband, i, ipw, ispinor, ig
1458 : : integer :: iatom, itypat, lmn_size, ilmn
1459 : : character(len=fnlen) :: wfnname
1460 : : character(len=1000) :: message
1461 : :
1462 [ # # ]: 0 : if(dtset%prtvol>0) then
1463 : 0 : write(message, '(3a)' ) ch10,&
1464 : 0 : & ' mlwfovlp : Creating temporary files with cg and cprj (PAW)',ch10
1465 : 0 : call wrtout(ab_out,message,'COLL')
1466 : 0 : call wrtout(std_out, message,'COLL')
1467 : : end if
1468 : : !
1469 [ # # ]: 0 : do isppol=1,nsppol
1470 [ # # ]: 0 : do ikpt=1,nkpt
1471 : : !
1472 : : ! MPI:cycle over k-points not treated by this node
1473 : : !
1474 [ # # ]: 0 : if ( ABS(MPI_enreg%proc_distrb(ikpt,1,isppol)-rank) /=0) CYCLE
1475 : :
1476 : : ! write(std_out,*)'writing kpt ',ikpt,'isppol',isppol,' by node ', rank
1477 : 0 : write(wfnname,'(a,I5.5,".",I1)') trim(dtfil%fnametmp_cg),ikpt,isppol
1478 : 0 : iun_plot=1000+ikpt+ikpt*(isppol-1)
1479 : :
1480 : 0 : open (unit=iun_plot, file=wfnname,form='unformatted')
1481 : 0 : npw_k=npwarr(ikpt)
1482 [ # # ]: 0 : do iband=1,mband
1483 [ # # ]: 0 : do ispinor = 1, dtset%nspinor
1484 [ # # ]: 0 : do ipw=1,npw_k
1485 [ # # # # ]: 0 : write(iun_plot) (cg(i,ipw+iwav(ispinor, iband,ikpt,isppol)),i=1,2)
1486 : : end do
1487 : : end do
1488 : : end do
1489 : 0 : close(iun_plot)
1490 : : end do !ikpt
1491 : : end do !isppol
1492 : : !
1493 : : ! In the PAW case we also need to write out cprj into files
1494 : : !
1495 [ # # ]: 0 : if(psps%usepaw==1) then
1496 : : !
1497 : : ! big loop on atoms, kpts, bands and lmn
1498 : : !print *, "nsppol", nsppol
1499 : : !print *, "nkpt", nkpt
1500 : : !print *, "mkmem", dtset%mkmem
1501 : : !
1502 : 0 : ikpt2=0
1503 [ # # ]: 0 : do isppol=1,nsppol
1504 [ # # ]: 0 : do ikpt=1,nkpt
1505 : : !
1506 : : ! MPI:cycle over k-points not treated by this node
1507 : : !
1508 [ # # ]: 0 : if ( ABS(MPI_enreg%proc_distrb(ikpt,1,isppol)-MPI_enreg%me) /=0) CYCLE
1509 : :
1510 : 0 : ikpt2=ikpt2+1 !sums just on the k-points treated by this node
1511 : : !
1512 : 0 : write(wfnname,'(a,I5.5,".",I1)') trim(dtfil%fnametmp_cprj),ikpt,isppol
1513 : 0 : iun_plot=1000+ikpt
1514 : 0 : open (unit=iun_plot, file=wfnname,form='unformatted')
1515 : : !
1516 [ # # ]: 0 : do iband=1,mband*dtset%nspinor
1517 : : !ig=iband+(ikpt2-1)*mband*dtset%nspinor +(isppol-1)*nkpt*mband*dtset%nspinor !index for cprj(:,ig)
1518 : : ! cprj: only mkmem k-points are stored in this node.
1519 : 0 : ig=iband+(ikpt2-1)*mband*dtset%nspinor +(isppol-1)*dtset%mkmem*mband*dtset%nspinor !index for cprj(:,ig)
1520 : : !
1521 [ # # ]: 0 : do iatom=1,natom
1522 : 0 : itypat=dtset%typat(iatom)
1523 : 0 : lmn_size=pawtab(itypat)%lmn_size
1524 : : !
1525 [ # # ]: 0 : do ilmn=1,lmn_size
1526 [ # # # # ]: 0 : write(iun_plot) (( cprj(iatom,ig)%cp(i,ilmn)),i=1,2)
1527 : : end do !ilmn
1528 : : end do !iatom
1529 : : end do !iband
1530 : :
1531 : 0 : close(iun_plot)
1532 : : end do !ikpt
1533 : : end do !isppol
1534 : : end if !usepaw==1
1535 : 0 : end subroutine write_cg_and_cprj
1536 : :
1537 : :
1538 : : ! subroutine wfd_print_norm(wfd, hdr)
1539 : : ! type(wfd_t), intent(in) :: wfd
1540 : : ! type(hdr_type), intent(in) :: hdr
1541 : : ! integer :: spin, band, ikpt, size
1542 : : ! real(dp), allocatable :: cgtemp(:, :)
1543 : : ! do spin=1, wfd%nsppol
1544 : : ! do ikpt=1, wfd%nkibz
1545 : : ! size=wfd%nspinor * hdr%npwarr(ikpt)
1546 : : ! ABI_MALLOC(cgtemp, (2, size))
1547 : : ! do band=1, wfd%mband
1548 : : ! cgtemp(:, :)=0
1549 : : ! !if(isirr(ik)) then
1550 : : ! call wfd%copy_cg(band,ikpt, spin, cgtemp)
1551 : : ! !print *, "spin:", spin, "band:", band, "ik:", ikpt, "delta:", sum(cgtemp**2)
1552 : : ! end do
1553 : : ! ABI_FREE(cgtemp)
1554 : : ! end do
1555 : : ! end do
1556 : : ! end subroutine wfd_print_norm
1557 : :
1558 : :
1559 [ + + + + : 119 : end module m_abstract_wf
+ + - + +
+ - + - +
+ + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - - - -
- - - - -
- - - - +
- + - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - - -
- - - - -
- - - - -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + ]
|