Line data Source code
1 : !!****m* ABINIT/m_rwwf
2 : !! NAME
3 : !! m_rwwf
4 : !!
5 : !! FUNCTION
6 : !! Read/Write wavefunctions.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 1998-2026 ABINIT group (DCA,XG,GMR,MVer,MB,MT)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : module m_rwwf
23 :
24 : use defs_basis
25 : use m_errors
26 : use m_wffile
27 : use m_abicore
28 : use m_xmpi
29 : USE_MPI
30 : use m_nctk
31 : use netcdf
32 :
33 : use defs_abitypes, only : mpi_type
34 : use m_time, only : timab
35 :
36 : implicit none
37 :
38 : private
39 :
40 : #if defined HAVE_MPI1
41 : include 'mpif.h'
42 : #endif
43 :
44 : !!***
45 :
46 : public :: rwwf
47 : public :: WffReadSkipK
48 : !!***
49 :
50 : contains
51 : !!***
52 :
53 : !!****f* m_rwwf/rwwf
54 : !! NAME
55 : !! rwwf
56 : !!
57 : !! FUNCTION
58 : !! This subroutine reads (different options) or write (option=2) the block of records
59 : !! related to one k point, and one spin-polarization, that
60 : !! contains the wavefunctions (as well as the eigenvalues and occupations).
61 : !! If called with option -1, the records will be skipped.
62 : !! If called with option -2, only the wavefunctions are read.
63 : !! The disk file unitwf should have been prepared
64 : !! outside of this routine, in order to read or write the correct records.
65 : !!
66 : !! INPUTS
67 : !! formeig=format of the eigenvalues
68 : !! 0 => vector of eigenvalues
69 : !! 1 => hermitian matrix of eigenvalues
70 : !! headform=format of the header of the wf file, also governing the k block format
71 : !! in case headform=0, use the default (current) format and headform
72 : !! icg=shift to be given to the location of the cg array
73 : !! ikpt=index of current k point (only needed for error message)
74 : !! isppol=spin polarization currently treated (only needed for error message)
75 : !! mband=maximum number of bands (dimension of cg, eigen and occ)
76 : !! mcg=dimention of cg
77 : !! nband=number of bands actually in cg, eigen and occ
78 : !! (if writing mode : must be larger or equal to nband_disk, only nband_disk bands are written ;
79 : !! if reading mode : can be equal, larger or smaller than nband_disk, but
80 : !! cg, eigen and occ will not be completely filled if nband>nband_disk)
81 : !! nband_disk=number of bands on the disk file
82 : !! npw=number of plane waves
83 : !! nspinor=number of spinorial components of the wavefunctions (on current proc)
84 : !! option= 2 for writing cg, eigen and occ,
85 : !! 1 for reading cg and eigen,
86 : !! -1 for reading/skipping,
87 : !! -2 for reading cg only
88 : !! 3 for reading the eigenvalues only
89 : !! 4 for writing a file containing only eigenvalues and occupations (need to be read with option 4)
90 : !! 5 for writing a file containing only eigenvalues and occupations, that can however be read with option 3)
91 : !! -4 for reading a file written with 4
92 : !! (different from 3 which reads a normal option 2 file)
93 : !! optkg= if 1 , read or write kg_k ; if 0, do not care about kg_k
94 : !! tim_rwwf=timing code of the calling routine (set to 0 if not attributed)
95 : !! wff=struct info for wavefunction
96 : !! | unitwf=unit number for wavefunction
97 : !!
98 : !! SIDE EFFECTS
99 : !! cg(2,npw*nspinor*mband)=planewave coefficients of wavefunctions,
100 : !! input if option=2; output if option=1 or -2
101 : !! eigen((2*mband)**formeig *mband)=array for holding eigenvalues (hartree)
102 : !! input if option=2 or 4 or 5; output if option=1
103 : !! kg_k(3,optkg*npw)=k+g data (only if optkg==1)
104 : !! input if option=2; output if option=1 or -2
105 : !! nband_disk=number of bands on disk
106 : !! input if option=2 or 4 or 5; output in the other cases
107 : !! occ(mband)=array for holding eigenvalues (hartree)
108 : !! input if option=2 or 4 or 5; output if option=1
109 : !! no meaning if frmeig/=0
110 : !!
111 : !! NOTES
112 : !! WARNING : occ is not read in the present status of this routine
113 : !! WARNING : skipping k-blocks is also done in the randac subroutine
114 : !! WARNING : reading the two first records is also done in the rdnpw routine
115 : !! WARNING : writing the two first records is also done in the dfpt_vtowfk routine
116 : !!
117 : !! TODO! if (mpi_enreg%flag_ind_kg_mpi_to_seq==1 ) then
118 : !! Some arguments are contained in the wff datastructure, and should be eliminated.
119 : !! option 3 should be called -3 (reading -> negative option) and others (-1,1) re-shuffled.
120 : !!
121 : !! SOURCE
122 :
123 64222 : subroutine rwwf(cg,eigen,formeig,headform,icg,ikpt,isppol,kg_k,mband,mcg,mpi_enreg,&
124 64222 : & nband,nband_disk,npw,nspinor,occ,option,optkg,tim_rwwf,wff)
125 :
126 : !Arguments ------------------------------------
127 : integer,intent(in) :: formeig,headform,icg,ikpt,isppol,mband,mcg,nband,npw
128 : integer,intent(inout) :: nband_disk
129 : integer,intent(in) :: nspinor,option,optkg,tim_rwwf
130 : integer,intent(inout),target :: kg_k(3,optkg*npw)
131 : real(dp),intent(inout),target :: cg(2,mcg),eigen((2*mband)**formeig*mband),occ(mband)
132 : type(wffile_type),intent(inout) :: wff
133 : type(MPI_type), intent(in) :: mpi_enreg
134 :
135 : !Local variables-------------------------------
136 : !scalars
137 : character(len=500) :: msg
138 : !arrays
139 : real(dp) :: tsec(2)
140 :
141 : ! *************************************************************************
142 :
143 64222 : call timab(270+tim_rwwf,1,tsec)
144 :
145 : !Might check that icg+npw*nband*nspinor is smaller than mcg
146 :
147 : !Check that nband is smaller than mband, if one will not skip the records.
148 64222 : if (nband>mband .and. option/=-1)then
149 0 : write(msg,'(a,i0,a,i0,a)')' One should have nband<=mband. However, nband=',nband,', and mband=',mband,'.'
150 0 : ABI_BUG(msg)
151 : end if
152 :
153 : !Check that formeig is 0 or 1.
154 64222 : if ( ALL(formeig/=(/0,1/)) ) then
155 0 : write(msg,'(a,i0,a)')' The argument formeig should be 0 or 1. However, formeig=',formeig,'.'
156 0 : ABI_BUG(msg)
157 : end if
158 :
159 : !Check the value of option
160 64638 : if ( ALL( option /= (/1,2,3,4,5,-1,-2,-4/) )) then
161 0 : write(msg,'(a,i0,a)')' The argument option should be between 1 and 5, or -1, -2, -4. However, option=',option,'.'
162 0 : ABI_BUG(msg)
163 : end if
164 :
165 64222 : if (option/=2.and.option/=4 .and. option/=5 ) then ! read
166 : call readwf(cg,eigen,formeig,headform,icg,ikpt,isppol,kg_k,mband,mcg,mpi_enreg,&
167 63806 : & nband,nband_disk,npw,nspinor,occ,option,optkg,wff)
168 : else ! write
169 : call writewf(cg,eigen,formeig,icg,ikpt,isppol,kg_k,mband,mcg,mpi_enreg,&
170 416 : & nband,nband_disk,npw,nspinor,occ,option,optkg,wff)
171 : end if
172 :
173 64222 : call timab(270+tim_rwwf,2,tsec)
174 :
175 64222 : end subroutine rwwf
176 : !!***
177 :
178 : !!****f* m_rwwf/WffReadSkipK
179 : !! NAME
180 : !! WffReadSkipK
181 : !!
182 : !! FUNCTION
183 : !! (Wavefunction file, read action : skip one k-point blok)
184 : !! This subroutine skips the block of records
185 : !! related to one k point, and one spin-polarization, that
186 : !! contains the wavefunctions as well as the eigenvalues and occupations,
187 : !! in a wavefunction file that has been already initialized.
188 : !!
189 : !! INPUTS
190 : !! formeig=format of the eigenvalues
191 : !! 0 => vector of eigenvalues (for Ground-State files)
192 : !! 1 => hermitian matrix of eigenvalues (for Response-Function files)
193 : !! headform=format of the header of the wf file, also governing the k block format
194 : !! in case headform=0, use the default (current) format and headform
195 : !! ikpt=index of current k point (only needed for error message)
196 : !! isppol=spin polarization currently treated (only needed for error message)
197 : !! mpi_enreg=information about MPI parallelization
198 : !! wff=structured info for wavefunction file
199 : !!
200 : !! OUTPUT
201 : !!
202 : !! NOTES
203 : !!
204 : !! SOURCE
205 :
206 2120 : subroutine WffReadSkipK(formeig,headform,ikpt,isppol,mpi_enreg,wff)
207 :
208 : !Arguments ------------------------------------
209 : !scalars
210 : integer,intent(in) :: formeig,headform,ikpt,isppol
211 : type(MPI_type),intent(in) :: mpi_enreg
212 : type(wffile_type),intent(inout) :: wff
213 :
214 : !Local variables-------------------------------
215 : !scalars
216 : integer :: icg,mband,mcg,nband,nband_disk,option,optkg,tim_rwwf
217 : integer,parameter :: nspinor1=1,npw1=1
218 : !arrays
219 2120 : integer,allocatable :: kg_dum(:,:)
220 : real(dp) :: cg_dum(2,1),occ_dum(1)
221 2120 : real(dp),allocatable :: eig_dum(:)
222 :
223 : ! *************************************************************************
224 :
225 : ! No need to skip if netcdf
226 2120 : if (wff%iomode == IO_MODE_ETSF) return
227 :
228 0 : option=-1
229 0 : tim_rwwf=0 ; mcg=1 ; mband=1 ; icg=0 ; optkg=0 ; nband=0
230 0 : ABI_MALLOC(eig_dum,(2**formeig))
231 0 : ABI_MALLOC(kg_dum,(3,optkg*npw1))
232 :
233 : call rwwf(cg_dum,eig_dum,formeig,headform,icg,ikpt,isppol,kg_dum,mband,mcg,mpi_enreg,nband,&
234 0 : & nband_disk,npw1,nspinor1,occ_dum,option,optkg,tim_rwwf,wff)
235 :
236 0 : ABI_FREE(eig_dum)
237 0 : ABI_FREE(kg_dum)
238 :
239 : end subroutine WffReadSkipK
240 : !!***
241 :
242 : ! -------------------------------------------------------------------------------------------------
243 :
244 : !!****f* m_rwwf/readwf
245 : !! NAME
246 : !! readwf
247 : !!
248 : !! FUNCTION
249 : !! This subroutine reads the block of records related to one k point, and one spin-polarization, that
250 : !! contains the wavefunctions (as well as the eigenvalues).
251 : !! The disk file unitwf should have been prepared outside of this routine, in order to read the correct records.
252 : !!
253 : !! INPUTS
254 : !! formeig=format of the eigenvalues
255 : !! 0 => vector of eigenvalues
256 : !! 1 => hermitian matrix of eigenvalues
257 : !! icg=shift to be given to the location of the cg array
258 : !! ikpt=index of current k point (only needed for error message)
259 : !! isppol=spin polarization currently treated (only needed for error message)
260 : !! kg_k(3,optkg*npw)=k+g data (only if optkg==1)
261 : !! mband=maximum number of bands (dimension of cg, eigen and occ)
262 : !! mcg=dimension of cg
263 : !! nband=number of bands actually in cg, eigen and occ
264 : !! nband_disk=number of bands on the disk file
265 : !! npw=number of plane waves (on current proc)
266 : !! nspinor=number of spinorial components of the wavefunctions (on current proc)
267 : !! option= 1 for reading cg, eigen and occ,
268 : !! -1 for reading/skipping,
269 : !! -2 for reading cg only
270 : !! 3 for reading the eigenvalues only
271 : !! -4 for reading a file written with 4
272 : !! optkg= if 1 , read or write kg_k ; if 0, do not care about kg_k
273 : !! wff=struct info for wavefunction
274 : !!
275 : !! SIDE EFFECTS
276 : !! Current kpt and spin updated
277 : !! cg(2,npw*nspinor*mband)=planewave coefficients of wavefunctions,
278 : !! eigen((2*mband)**formeig *mband)=array for holding eigenvalues (hartree)
279 : !! occ(mband)=array for holding electronic occupations
280 : !!
281 : !! NOTES
282 : !! WARNING : occ is not read in the present status of this routine
283 : !! WARNING : skipping k-blocks is also done in the randac subroutine
284 : !! WARNING : reading the two first records is also done in the rdnpw routine
285 : !!
286 : !! SOURCE
287 :
288 63806 : subroutine readwf(cg,eigen,formeig,headform,icg,ikpt,isppol,kg_k,mband,mcg,mpi_enreg,&
289 63806 : & nband,nband_disk,npw,nspinor,occ,option,optkg,wff)
290 :
291 : !Arguments ------------------------------------
292 : integer,intent(in) :: formeig,headform,icg,ikpt,isppol,mband,mcg,nband,npw
293 : integer,intent(in) :: nspinor,option,optkg
294 : integer,intent(inout) :: nband_disk
295 : integer,intent(inout),target :: kg_k(3,optkg*npw)
296 : real(dp),intent(inout),target :: cg(2,mcg),eigen((2*mband)**formeig*mband),occ(mband)
297 : type(MPI_type),intent(in) :: mpi_enreg
298 : type(wffile_type),intent(inout) :: wff
299 :
300 : !Local variables-------------------------------
301 : integer :: iband,indxx,ios,ipw,ispinor_index,nband1,ncid_hdr
302 : integer :: npw1,npwso,npwso1,npwsotot,npwtot,nrec,nspinor1,nspinortot,unitwf,use_f90
303 : integer :: band1,band2,ierr
304 : character(len=500) :: msg
305 : character(len=fnlen) :: fname
306 : integer :: ikpt_this_proc,ispinor
307 63806 : integer,allocatable :: ind_cg_mpi_to_seq(:)
308 : integer :: kg_varid,eig_varid,occ_varid,cg_varid,h1_varid,mband_varid,ncerr,ii,mband_file
309 63806 : integer,allocatable :: gall(:,:)
310 63806 : real(dp),allocatable :: cg_all(:,:,:),h1mat(:,:,:)
311 : ! *********************************************************************
312 :
313 : !write(std_out,*)"rwwf with ikpt, isppol, option, etsf",ikpt, isppol, option, wff%iomode == IO_MODE_ETSF
314 :
315 : !Check the options
316 63806 : if ( ALL(option /= [1,3,-1,-2,-4])) then
317 0 : write(msg,'(a,i0,a)')'The argument option should be -4, -2, -1, 1 or 3. However, option=',option,'.'
318 0 : ABI_BUG(msg)
319 : end if
320 :
321 63806 : npwtot=npw; npwso=npw*nspinor
322 63806 : npwsotot=npwso
323 63806 : nspinortot=min(2,(1+mpi_enreg%paral_spinor)*nspinor)
324 :
325 63806 : unitwf=wff%unwff
326 63806 : ncid_hdr=unitwf
327 :
328 63806 : use_f90=0
329 63806 : if (wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) use_f90=1
330 :
331 63806 : if (option==1.or.option==-2) then
332 :
333 : ! Compute mapping my_gtable --> sequential gtable.
334 63806 : if (any(wff%iomode==[IO_MODE_MPI, IO_MODE_ETSF]).and.nband>0) then
335 63806 : call xmpi_sum(npwsotot,wff%spaceComm_mpiio,ios)
336 63806 : npwtot=npwsotot/nspinortot
337 191418 : ABI_MALLOC(ind_cg_mpi_to_seq,(npwso))
338 127612 : if (allocated(mpi_enreg%my_kgtab)) then
339 532 : ikpt_this_proc=mpi_enreg%my_kpttab(ikpt)
340 532 : if ( ikpt_this_proc <= 0 ) then
341 0 : ABI_BUG("rwwf: ikpt_this_proc <= 0")
342 : end if
343 1064 : do ispinor=1,nspinor
344 532 : ispinor_index=ispinor
345 532 : if (mpi_enreg%nproc_spinor>1) ispinor_index=mpi_enreg%me_spinor + 1
346 : ind_cg_mpi_to_seq(1+npw*(ispinor-1):npw*ispinor)=npwtot*(ispinor_index-1) &
347 81632 : & + mpi_enreg%my_kgtab(1:npw,ikpt_this_proc)
348 : end do
349 : else
350 15164552 : ind_cg_mpi_to_seq(1:npwso) = (/(ipw,ipw=1,npwso)/)
351 : end if
352 : end if
353 : end if
354 :
355 : !---------------------------------------------------------------------------
356 : !Read the first record: npw, nspinor, nband_disk
357 : !---------------------------------------------------------------------------
358 :
359 63806 : if (headform>=40.or.headform==0) then ! headform==0 refers to the current headform
360 63806 : call WffReadNpwRec(ios,ikpt,isppol,nband_disk,npw1,nspinor1,wff)
361 63806 : npwso1=npw1*nspinor1
362 63806 : if(ios/=0)then
363 0 : inquire (unit=unitwf, NAME=fname)
364 : write(msg,'(3a,i4,2a,i4,4a)') &
365 0 : & 'Reading option of rwwf. Trying to read',ch10,&
366 0 : & 'the (npw,nspinor,nband) record of a wf file, unit=',unitwf,ch10,&
367 0 : & 'gave iostat=',ios,'. Your file is likely not correct.',ch10,&
368 0 : & 'Action: check your input wf file:',trim(fname)
369 0 : ABI_ERROR(msg)
370 : end if
371 :
372 : else
373 : ! Old format
374 0 : if(use_f90==1)then
375 0 : read (unitwf,iostat=ios) npwso1,nband_disk
376 0 : else if(wff%iomode==IO_MODE_MPI)then
377 0 : call xderiveRRecInit(wff,ios)
378 0 : call xderiveRead(wff,npwso1,ios)
379 0 : call xderiveRead(wff,nband_disk,ios)
380 0 : call xderiveRRecEnd(wff,ios)
381 : end if
382 0 : if(ios/=0)then
383 0 : inquire (unit=unitwf, NAME=fname)
384 : write(msg,'(3a,i4,2a,i4,4a)') &
385 0 : & 'Reading option of rwwf. Trying to read',ch10,&
386 0 : & 'the (npw,nband) record of a wf file with headform <40 , unit=',unitwf,ch10,&
387 0 : & 'gave iostat=',ios,'. Your file is likely not correct.',ch10,&
388 0 : & 'Action: check your input wf file:',trim(fname)
389 0 : ABI_ERROR(msg)
390 : end if
391 : end if ! headform
392 :
393 63806 : if (option==1.or.option==-2) then ! Will read the wavefunction and/or kg data, so check npw and nspinor
394 :
395 63806 : if (headform>=40.or.headform==0) then ! New format. headform==0 refers to the current headform
396 63806 : if (npwtot/=npw1) then
397 : write(msg,'(3a,i0,a,i0,a)') &
398 0 : & 'Reading option of rwwf. One should have npwtot=npw1',ch10,&
399 0 : & 'However, npwtot= ',npwtot,', and npw1= ',npw1,'.'
400 0 : ABI_BUG(msg)
401 : end if
402 63806 : if(nspinortot/=nspinor1)then
403 : write(msg,'(3a,i0,a,i0,a)') &
404 0 : & 'Reading option of rwwf. One should have nspinor=nspinor1',ch10,&
405 0 : & 'However, nspinortot= ',nspinortot,', and nspinor1= ',nspinor1,'.'
406 0 : ABI_BUG(msg)
407 : end if
408 : else ! Treat the Old format.
409 0 : if(npwsotot/=npwso1)then
410 : write(msg,'(3a,i0,a,i0,a)') &
411 0 : & 'Reading option of rwwf. One should have npwso=npwso1',ch10,&
412 0 : & 'However, npwsotot= ',npwsotot,', and npwso1= ',npwso1,'.'
413 0 : ABI_BUG(msg)
414 : end if
415 : end if ! headform
416 : !
417 : end if ! option==1.or.option==2
418 :
419 : !---------------------------------------------------------------------------
420 : !Read the second record: (k+G) vectors
421 : !---------------------------------------------------------------------------
422 :
423 63806 : if (headform>=40.or.headform==0) then ! headform==0 refers to the current headform
424 :
425 63806 : if ((option==1.or.option==-2.or.option==3).and.optkg/=0 )then
426 :
427 0 : if(use_f90==1)then
428 0 : read(unitwf,iostat=ios) kg_k(1:3,1:npw)
429 :
430 0 : else if(wff%iomode==IO_MODE_MPI)then
431 0 : call xderiveRRecInit(wff,ios)
432 0 : if (allocated(mpi_enreg%my_kgtab)) then
433 0 : ikpt_this_proc=mpi_enreg%my_kpttab(ikpt)
434 : call xderiveRead(wff,kg_k(1:3,1:npw),3,npw,wff%spaceComm_mpiio,&
435 0 : & mpi_enreg%my_kgtab(1:npw,ikpt_this_proc),ios)
436 : else
437 : ! MG The call below uses MPI_SCAN but here we want to read the full set of G.
438 0 : call xderiveRead(wff,kg_k(1:3,1:npw),3,npw,wff%spaceComm_mpiio,ios)
439 0 : call xmpi_read_int2d(wff,kg_k(1:3,1:npw),wff%spaceComm_mpiio,xmpio_collective,ios)
440 : end if
441 0 : call xderiveRRecEnd(wff,ios)
442 :
443 0 : else if (wff%iomode == IO_MODE_ETSF) then
444 : ! Read reduced_coordinates_of_plane_waves for this k point (npw1 is npw_disk).
445 : ! TODO: spinor parallelism
446 0 : NCF_CHECK(nf90_inq_varid(wff%unwff, "reduced_coordinates_of_plane_waves", kg_varid))
447 0 : if (npw == npw1) then
448 0 : ncerr = nf90_get_var(wff%unwff, kg_varid, kg_k, start=[1,1,ikpt], count=[3,npw1,1])
449 0 : NCF_CHECK_MSG(ncerr, "getting kg_k")
450 : else
451 0 : write(std_out,*)"ETSF Reading distributed kg_k"
452 0 : ABI_MALLOC(gall, (3, npw1))
453 0 : ncerr = nf90_get_var(wff%unwff, kg_varid, gall, start=[1,1,ikpt], count=[3,npw1,1])
454 0 : NCF_CHECK_MSG(ncerr, "getting kg_k")
455 0 : do ipw=1,npw
456 0 : kg_k(:,ipw) = gall(:,ind_cg_mpi_to_seq(ipw))
457 : end do
458 0 : ABI_FREE(gall)
459 : end if
460 : end if
461 :
462 : else ! option
463 63806 : call WffReadSkipRec(ios,1,wff) ! Skip the record
464 : end if
465 :
466 63806 : if(ios/=0)then
467 0 : inquire (unit=unitwf, NAME=fname)
468 : write(msg,'(3a,i4,2a,i4,4a)') &
469 0 : & 'Reading option of rwwf. Trying to read',ch10,&
470 0 : & 'the k+g record of a wf file, unit=',unitwf,ch10,&
471 0 : & 'gave iostat=',ios,'. Your file is likely not correct.',ch10,&
472 0 : & 'Action: check your input wf file:',trim(fname)
473 0 : ABI_ERROR(msg)
474 : end if
475 : end if ! headform
476 :
477 : !---------------------------------------------------------------------------
478 : !Read the third record: eigenvalues
479 : !---------------------------------------------------------------------------
480 : !The reading of occ should be enabled, BUT taking into account
481 : !of headform of the disk file : occ was NOT present in the disk files with headform=22
482 :
483 63806 : nband1 = min(nband,nband_disk)
484 :
485 : !===== Case formeig=0: read eigenvalues =====
486 63806 : if (formeig==0) then
487 :
488 9597 : if (option==1.or.option==3.or.option==-4) then
489 9597 : if(use_f90==1)then
490 0 : read (unitwf,iostat=ios) eigen(1:nband1)
491 9597 : else if(wff%iomode==IO_MODE_MPI)then
492 16 : call xderiveRRecInit(wff,ios)
493 16 : call xderiveRead(wff,eigen,nband1,xmpi_comm_self,ios)
494 16 : call xderiveRRecEnd(wff,ios)
495 : end if
496 : else
497 0 : call WffReadSkipRec(ios,1,wff)
498 : end if ! option
499 :
500 9597 : if(ios/=0)then
501 0 : inquire (unit=unitwf, NAME=fname)
502 : write(msg,'(3a,i4,2a,i4,4a)') &
503 0 : & 'Reading option of rwwf. Trying to read',ch10,&
504 0 : & 'an eigenvalue record of a wf file, unit=',unitwf,ch10,&
505 0 : & 'gave iostat=',ios,'. Your file is likely not correct.',ch10,&
506 0 : & 'Action: check your input wf file.',trim(fname)
507 0 : ABI_ERROR(msg)
508 : end if
509 :
510 9597 : if (wff%iomode == IO_MODE_ETSF) then
511 : ! get eigenvalues and occupations
512 9581 : NCF_CHECK(nf90_inq_varid(wff%unwff, "eigenvalues", eig_varid))
513 67067 : ncerr = nf90_get_var(wff%unwff, eig_varid, eigen, start=[1,ikpt,isppol], count=[nband1,1,1])
514 9581 : NCF_CHECK_MSG(ncerr, "getting eig_k")
515 :
516 9581 : NCF_CHECK(nf90_inq_varid(wff%unwff, "occupations", occ_varid))
517 67067 : ncerr = nf90_get_var(wff%unwff, occ_varid, occ, start=[1,ikpt,isppol], count=[nband1,1,1])
518 9581 : NCF_CHECK_MSG(ncerr, "getting occ_k")
519 : end if
520 :
521 : ! ===== Case formeig=1: read matrix of eigenvalues =====
522 : ! Will be written later (together with wave-functions)
523 : else if(formeig==1)then
524 : end if ! formeig
525 :
526 : !---------------------------------------------------------------------------
527 : !Read the wave-function coefficients
528 : !---------------------------------------------------------------------------
529 :
530 : !Select bands
531 63806 : nband1=min(nband,nband_disk)
532 63806 : if(nband1>0.and.option/=-1)then
533 :
534 : ! ===== Case formeig=0: read only wave-functions =====
535 63806 : if (formeig==0) then
536 :
537 9597 : if (option==1.or.option==-2) then
538 :
539 9597 : if (use_f90==1) then
540 0 : do iband=1,nband1
541 0 : ipw=(iband-1)*npwso+icg
542 0 : read(unitwf,iostat=ios) cg(1:2,ipw+1:ipw+npwso)
543 0 : if (ios/=0) exit
544 : end do
545 9597 : else if (wff%iomode==IO_MODE_MPI) then
546 16 : call WffReadWrite_mpio(wff,1,cg,mcg,icg,nband1,npwso,npwsotot,ind_cg_mpi_to_seq,ios)
547 : end if
548 :
549 0 : else if (option/=-4) then
550 0 : do iband=1,nband1
551 0 : call WffReadSkipRec(ios,1,wff) ! Skip the record
552 : end do
553 : end if ! option
554 :
555 9597 : if(ios/=0)then
556 0 : inquire (unit=unitwf, NAME=fname)
557 : write(msg,'(3a,i4,2a,i4,4a)') &
558 0 : & 'Reading option of rwwf. Trying to read',ch10,&
559 0 : & 'a RF wf record of a wf file, unit=',unitwf,ch10,&
560 0 : & 'gave iostat=',ios,'. Your file is likely not correct.',ch10,&
561 0 : & 'Action: check your input wf file.',trim(fname)
562 0 : ABI_ERROR(msg)
563 : end if
564 :
565 9597 : if (wff%iomode == IO_MODE_ETSF) then
566 : ! The coefficients_of_wavefunctions on file have shape [cplex, mpw, nspinor, mband, nkpt, nsppol]
567 9581 : NCF_CHECK(nf90_inq_varid(wff%unwff, "coefficients_of_wavefunctions", cg_varid))
568 9581 : if (npw == npw1) then
569 : ncerr = nf90_get_var(wff%unwff, cg_varid, cg(:, icg+1:), start=[1,1,1,1,ikpt,isppol], &
570 117845 : count=[2,npw,nspinor,nband1,1,1])
571 9065 : NCF_CHECK_MSG(ncerr, "getting cg_k")
572 : else
573 516 : write(std_out,*)"ETSF Reading distributed cg"
574 2064 : ABI_MALLOC_OR_DIE(cg_all, (2, npw1*nspinor, nband1), ierr)
575 : ncerr = nf90_get_var(wff%unwff, cg_varid, cg_all, start=[1,1,1,1,ikpt,isppol], &
576 6708 : count=[2,npw1,nspinor,nband1,1,1])
577 516 : NCF_CHECK_MSG(ncerr, "getting cg_k")
578 516 : ii = icg
579 6860 : do iband=1,nband1
580 1525502 : do ipw=1,npw
581 1518642 : ii = ii + 1
582 4562270 : cg(:,ii) = cg_all(:,ind_cg_mpi_to_seq(ipw),iband)
583 : end do
584 : end do
585 516 : ABI_FREE(cg_all)
586 : end if
587 : end if
588 :
589 : ! ===== Case formeig=1: read eigenvalues, occupations and wave-functions =====
590 54209 : else if(formeig==1)then
591 : ! write(std_out,*)"nband1",nband1
592 : ! ABI_CHECK(nband1==nband_disk,"nband != nband_disk")
593 :
594 54209 : if (wff%iomode /= IO_MODE_ETSF) then
595 : indxx=0
596 0 : do iband=1,nband1
597 :
598 0 : if (option==1.or.option==3.or.option==-4) then
599 0 : if(use_f90==1)then
600 0 : read (unitwf,iostat=ios) eigen(1+indxx:2*nband1+indxx)
601 0 : else if(wff%iomode==IO_MODE_MPI)then
602 : ! Should use an access with a "view"
603 0 : call xderiveRRecInit(wff,ios)
604 0 : call xderiveRead(wff,eigen(1+indxx:2*nband1+indxx),2*nband1,xmpi_comm_self,ios)
605 0 : call xderiveRRecEnd(wff,ios)
606 : end if
607 0 : indxx=indxx+2*nband1
608 : else
609 0 : call WffReadSkipRec(ios,1,wff) ! Skip the record
610 : end if
611 :
612 0 : if(ios/=0)then
613 0 : inquire (unit=unitwf, NAME=fname)
614 : write(msg,'(3a,i4,2a,i4,4a)') &
615 0 : & 'Reading option of rwwf. Trying to read',ch10,&
616 0 : & 'a RF eigenvalue record of a wf file, unit=',unitwf,ch10,&
617 0 : & 'gave iostat=',ios,'. Your file is likely not correct.',ch10,&
618 0 : & 'Action: check your input wf file.',trim(fname)
619 0 : ABI_ERROR(msg)
620 : end if
621 :
622 0 : if(option==1.or.option==-2)then
623 0 : ipw=(iband-1)*npwso+icg
624 0 : if(use_f90==1)then
625 0 : ipw=(iband-1)*npwso+icg
626 0 : read(unitwf,iostat=ios) cg(1:2,ipw+1:ipw+npwso)
627 0 : else if(wff%iomode==IO_MODE_MPI)then
628 : ! Should use an access with a "view"
629 0 : call xderiveRRecInit(wff,ios)
630 0 : call xderiveRead(wff,cg(1:2,ipw+1:ipw+npwso),2,npwso,wff%spaceComm_mpiio,ind_cg_mpi_to_seq,ios)
631 0 : call xderiveRRecEnd(wff,ios)
632 : end if
633 0 : else if (option/=-4) then
634 0 : call WffReadSkipRec(ios,1,wff) ! Skip the record
635 : end if ! option
636 :
637 0 : if(ios/=0)then
638 0 : inquire (unit=unitwf, NAME=fname)
639 : write(msg,'(3a,i4,2a,i4,4a)') &
640 0 : & 'Reading option of rwwf. Trying to read',ch10,&
641 0 : & 'a RF wf record of a wf file, unit=',unitwf,ch10,&
642 0 : & 'gave iostat=',ios,'. Your file is likely not correct.',ch10,&
643 0 : & 'Action: check your input wf file.',trim(fname)
644 0 : ABI_ERROR(msg)
645 : end if
646 : end do ! iband
647 :
648 : else
649 : ! ETSF-IO
650 54209 : if (any(option == [1, 3, -4])) then
651 : ! Read eigen. Remember that the matrix on file has shape [2, mband, mband, nkpt, nspin]
652 : ! whereas the eigen array used in Abinit is packed. Read the full matrix first, then pack data.
653 54209 : NCF_CHECK(nf90_inq_dimid(wff%unwff, "max_number_of_states", mband_varid))
654 54209 : NCF_CHECK(nf90_inquire_dimension(wff%unwff, mband_varid, len=mband_file))
655 54209 : h1_varid = nctk_idname(wff%unwff, "h1_matrix_elements")
656 :
657 216836 : ABI_MALLOC(h1mat, (2, mband_file, mband_file))
658 325254 : ncerr = nf90_get_var(wff%unwff, h1_varid, h1mat, start=[1,1,1,ikpt,isppol])
659 54209 : NCF_CHECK_MSG(ncerr, "getting h1_matrix_elements")
660 :
661 : indxx=1
662 333461 : do band2=1,nband1
663 2761725 : do band1=1,nband1
664 7284792 : eigen(indxx:indxx+1) = h1mat(:,band1,band2)
665 2707516 : indxx = indxx + 2
666 : end do
667 : end do
668 54209 : ABI_FREE(h1mat)
669 : end if
670 :
671 54209 : if (any(option == [1, -2])) then
672 : ! Read wavefunctions.
673 : ! The coefficients_of_wavefunctions on file have shape [cplex, mpw, nspinor, mband, nkpt, nsppol]
674 54209 : ABI_CHECK(npw == npw1, "npw != npw1 not coded")
675 :
676 54209 : cg_varid = nctk_idname(wff%unwff, "coefficients_of_wavefunctions")
677 : ncerr = nf90_get_var(wff%unwff, cg_varid, cg(:, icg+1:), start=[1,1,1,1,ikpt,isppol], &
678 704717 : count=[2,npw,nspinor,nband1,1,1])
679 54209 : NCF_CHECK_MSG(ncerr, "getting cg_k")
680 : end if
681 : end if
682 :
683 : end if ! formeig == 1
684 :
685 : end if ! nband >0
686 :
687 : !If fewer than all bands were read wind disk file forward to end of bands for this k point.
688 : !Will have to fill the non-filled bands outside of this routine ...
689 63806 : if (nband<nband_disk .or. option==-1) then
690 72 : nrec=(formeig+1)*(nband_disk-nband)
691 72 : if(option==-1)nrec=(formeig+1)*nband_disk
692 72 : call WffReadSkipRec(ios,nrec,wff)
693 : end if
694 :
695 : !---------------------------------------------------------------------------
696 : ! Free memory
697 : !---------------------------------------------------------------------------
698 63806 : ABI_SFREE(ind_cg_mpi_to_seq)
699 :
700 63806 : end subroutine readwf
701 : !!***
702 :
703 : ! -------------------------------------------------------------------------------------------------
704 :
705 : !!****f* m_rwwf/writewf
706 : !! NAME
707 : !! writewf
708 : !!
709 : !! FUNCTION
710 : !! This subroutine writes the block of records
711 : !! related to one k point, and one spin-polarization, that
712 : !! contains the wavefunctions (as well as the eigenvalues and occupations).
713 : !! The disk file unitwf should have been prepared
714 : !! outside of this routine, in order to write the correct records.
715 : !!
716 : !! INPUTS
717 : !! cg(2,npw*nspinor*mband)=planewave coefficients of wavefunctions,
718 : !! eigen((2*mband)**formeig *mband)=array for holding eigenvalues (hartree)
719 : !! formeig=format of the eigenvalues
720 : !! 0 => vector of eigenvalues
721 : !! 1 => hermitian matrix of eigenvalues
722 : !! icg=shift to be given to the location of the cg array
723 : !! ikpt=index of current k point (only needed for error message)
724 : !! isppol=spin polarization currently treated (only needed for error message)
725 : !! kg_k(3,optkg*npw)=k+g data (only if optkg==1)
726 : !! mband=maximum number of bands (dimension of cg, eigen and occ)
727 : !! mcg=dimension of cg
728 : !! nband=number of bands actually in cg, eigen and occ
729 : !! (must be larger or equal to nband_disk, only nband_disk bands are written)
730 : !! nband_disk=number of bands on the disk file
731 : !! npw=number of plane waves
732 : !! nspinor=number of spinorial components of the wavefunctions (on current proc)
733 : !! occ(mband)=array for holding electronic occupations
734 : !! option= 2 for writing cg, eigen and occ,
735 : !! 4 for writing a file containing only eigenvalues and occupations
736 : !! optkg= if 1 , read or write kg_k ; if 0, do not care about kg_k
737 : !! wff=struct info for wavefunction
738 : !!
739 : !! OUTPUT
740 : !! (none, only writing)
741 : !!
742 : !! SIDE EFFECTS
743 : !!
744 : !! NOTES
745 : !! WARNING : skipping k-blocks is also done in the randac subroutine
746 : !! WARNING : writing the two first records is also done in the dfpt_vtowfk routine
747 : !!
748 : !! SOURCE
749 :
750 416 : subroutine writewf(cg,eigen,formeig,icg,ikpt,isppol,kg_k,mband,mcg,mpi_enreg,&
751 416 : & nband,nband_disk,npw,nspinor,occ,option,optkg,wff)
752 :
753 : !Arguments ------------------------------------
754 : integer,intent(in) :: formeig,icg,ikpt,isppol,mband,mcg,nband,nband_disk,npw,nspinor,option,optkg
755 : integer,intent(in),target :: kg_k(3,optkg*npw)
756 : real(dp),intent(in),target :: cg(2,mcg),eigen((2*mband)**formeig*mband),occ(mband)
757 : type(MPI_type),intent(in) :: mpi_enreg
758 : type(wffile_type),intent(inout) :: wff
759 :
760 : !Local variables-------------------------------
761 : integer :: iband,ii,ios,ipw,ispinor_index,nband2,ncid_hdr,npwso,npwsotot,npwtot,nspinortot
762 : integer :: unitwf,use_f90
763 : character(len=500) :: msg
764 : integer :: ikpt_this_proc,ispinor,me_cart_3d
765 416 : integer,allocatable :: ind_cg_mpi_to_seq(:)
766 416 : real(dp),contiguous, pointer :: cg_ptr(:,:)
767 : integer :: kg_varid,eig_varid,occ_varid,cg_varid,ncerr
768 : character(len=nctk_slen) :: kdep
769 : #ifdef HAVE_MPI
770 : integer(kind=MPI_OFFSET_KIND) :: off(1)
771 : #endif
772 : ! *********************************************************************
773 :
774 : !Check the options
775 416 : if ( ALL(option /= (/2,4,5/)) ) then
776 0 : write(msg,'(a,i0)')' The argument option should be 2, 4 or 5. However, option=',option
777 0 : ABI_BUG(msg)
778 : end if
779 :
780 416 : if(wff%iomode==IO_MODE_MPI)then
781 52 : if(option==5)then
782 0 : write(msg,'(a,i0)')' With MPI-IO activated, the argument option should be 2 or 4. However, option=',option
783 0 : ABI_BUG(msg)
784 : end if
785 : end if
786 :
787 416 : if (wff%iomode==IO_MODE_ETSF) then
788 : ! outkss still calls this routine!
789 0 : ABI_WARNING("You should use outwff or ncwrite_cg to write data in netcdf format!")
790 : end if
791 :
792 : !Check that nband_disk is not larger than nband (only for writing)
793 416 : if (nband<nband_disk) then
794 : write(msg,'(3a,i5,a,i5,a)') &
795 0 : & 'Writing option of rwwf. One should have nband<=nband_disk',ch10,&
796 0 : & 'However, nband= ',nband,', and nband_disk= ',nband_disk,'.'
797 0 : ABI_BUG(msg)
798 : end if
799 :
800 416 : npwtot=npw; npwso=npw*nspinor
801 416 : unitwf=wff%unwff; ncid_hdr=unitwf
802 416 : npwsotot=npwso
803 416 : nspinortot=min(2,(1+mpi_enreg%paral_spinor)*nspinor)
804 :
805 416 : use_f90=0
806 416 : if (wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode ==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) use_f90=1
807 :
808 416 : if (wff%iomode==IO_MODE_MPI) then
809 :
810 52 : call xmpi_sum(npwsotot,wff%spaceComm_mpiio,ios)
811 52 : npwtot=npwsotot/nspinortot
812 :
813 52 : if (option/=4) then
814 156 : ABI_MALLOC(ind_cg_mpi_to_seq,(npwso))
815 52 : if (allocated(mpi_enreg%my_kgtab)) then
816 52 : ikpt_this_proc=mpi_enreg%my_kpttab(ikpt)
817 112 : do ispinor=1,nspinor
818 60 : ispinor_index=ispinor
819 60 : if (mpi_enreg%nproc_spinor > 1) ispinor_index = mpi_enreg%me_spinor + 1
820 : ind_cg_mpi_to_seq(1+npw*(ispinor-1):npw*ispinor)=npwtot*(ispinor_index-1) &
821 14402 : & + mpi_enreg%my_kgtab(1:npw,ikpt_this_proc)
822 : end do
823 : else
824 0 : ind_cg_mpi_to_seq(1:npwso) = (/(ipw,ipw=1,npwso)/)
825 : end if
826 : !write(std_out,*)"MPI-IO ind_cg_mpi_to_seq", ind_cg_mpi_to_seq(1:5)
827 : end if
828 : end if
829 :
830 : !---------------------------------------------------------------------------
831 : !Write the first record: npw, nspinor, nband_disk
832 : !---------------------------------------------------------------------------
833 : !Not modified for netCDF: no need to add writing of nband_disk,npw,nspinor
834 :
835 416 : call WffWriteNpwRec(ios,nband_disk,npwtot,nspinortot,wff,opt_paral=2)
836 :
837 : !---------------------------------------------------------------------------
838 : !Write the second record: (k+G) vectors
839 : !---------------------------------------------------------------------------
840 :
841 416 : if (optkg/=0.and.option/=4) then
842 416 : if(use_f90==1)then
843 364 : write(unitwf) kg_k(1:3,1:optkg*npw)
844 52 : else if (wff%iomode==IO_MODE_MPI) then
845 :
846 52 : if (allocated(mpi_enreg%my_kgtab)) then
847 52 : me_cart_3d=xmpi_comm_rank(mpi_enreg%comm_bandspinorfft)
848 52 : ikpt_this_proc=mpi_enreg%my_kpttab(ikpt)
849 52 : call xderiveWRecInit(wff,ios,me_cart_3d)
850 52 : if (mpi_enreg%me_spinor==0) then
851 : call xderiveWrite(wff,kg_k,3,npw,mpi_enreg%comm_bandfft, &
852 38 : & mpi_enreg%my_kgtab(1:npw,ikpt_this_proc),ios)
853 : end if
854 52 : call xderiveWRecEnd(wff,ios,me_cart_3d)
855 : else
856 : ! MG does it work if we are not using FFT distribution ?
857 0 : call xderiveWRecInit(wff,ios )
858 0 : if (mpi_enreg%me_spinor==0) then
859 0 : call xderiveWrite(wff,kg_k,3,optkg*npw,Wff%spaceComm_mpiio,ios)
860 : end if
861 0 : call xderiveWRecEnd(wff,ios)
862 : end if
863 :
864 0 : else if (wff%iomode == IO_MODE_ETSF) then
865 : ! Write the reduced_coordinates_of_plane_waves for this k point.
866 0 : NCF_CHECK(nf90_inq_varid(wff%unwff, "reduced_coordinates_of_plane_waves", kg_varid))
867 0 : NCF_CHECK(nf90_get_att(wff%unwff, kg_varid, "k_dependent", kdep))
868 0 : if (kdep == "no") then
869 0 : ncerr = nf90_put_var(wff%unwff, kg_varid, kg_k, start=[1,1], count=[3,npw])
870 : else
871 0 : ncerr = nf90_put_var(wff%unwff, kg_varid, kg_k, start=[1,1,ikpt], count=[3,npw,1])
872 : end if
873 0 : NCF_CHECK_MSG(ncerr, "putting kg_k")
874 : end if ! end if wff%iomode
875 : else ! Still skip the record
876 0 : if (use_f90==1) then
877 0 : write(unitwf)
878 0 : else if (wff%iomode==IO_MODE_MPI) then
879 0 : call xderiveWRecInit(wff,wff%spaceComm_mpiio,ios)
880 0 : call xderiveWRecEnd(wff,wff%spaceComm_mpiio,ios)
881 : end if
882 : end if
883 :
884 : !---------------------------------------------------------------------------
885 : !Write the third record: eigenvalues and occupations
886 : !---------------------------------------------------------------------------
887 :
888 : !===== Case formeig=0: write eigenvalues and occupations =====
889 416 : if (formeig==0) then
890 416 : if (use_f90==1) then
891 364 : write(unitwf) (eigen(iband),iband=1,nband_disk),(occ(iband),iband=1,nband_disk)
892 52 : else if(wff%iomode==IO_MODE_MPI) then
893 52 : if (wff%me_mpiio==0) then
894 15 : call xderiveWRecInit(wff,ios)
895 15 : call xderiveWrite(wff,eigen,nband_disk,xmpi_comm_self,ios)
896 15 : call xderiveWrite(wff,occ,nband_disk,xmpi_comm_self,ios)
897 15 : call xderiveWRecEnd(wff,ios)
898 : end if
899 : #ifdef HAVE_MPI
900 52 : off(1)=wff%offwff
901 52 : call MPI_BCAST(off,1,wff%offset_mpi_type,0,wff%spaceComm_mpiio,ios)
902 52 : wff%offwff=off(1)
903 : #endif
904 0 : else if (wff%iomode == IO_MODE_ETSF) then
905 : ! Write eigenvalues and occupation factors.
906 0 : NCF_CHECK(nf90_inq_varid(wff%unwff, "eigenvalues", eig_varid))
907 0 : ncerr = nf90_put_var(wff%unwff, eig_varid, eigen, start=[1,ikpt,isppol], count=[mband,1,1])
908 0 : NCF_CHECK_MSG(ncerr, "putting eig_k")
909 :
910 0 : NCF_CHECK(nf90_inq_varid(wff%unwff, "occupations", occ_varid))
911 0 : ncerr = nf90_put_var(wff%unwff, occ_varid, occ, start=[1,ikpt,isppol], count=[mband,1,1])
912 0 : NCF_CHECK_MSG(ncerr, "putting occ_k")
913 : end if
914 :
915 : ! ===== Case formeig=1: write matrix of eigenvalues =====
916 : ! Will be written later (together with wave-functions)
917 : else if(formeig==1)then
918 : end if ! formeig
919 :
920 : !---------------------------------------------------------------------------
921 : !Write the wave-function coefficients
922 : !---------------------------------------------------------------------------
923 :
924 : !===== Case formeig=0: write only wave-functions =====
925 416 : if (formeig==0) then
926 : ! If option=4, do not write wave functions
927 416 : if (option/=4) then
928 416 : if (use_f90==1) then
929 5484 : do iband=1,nband_disk
930 5120 : ipw=(iband-1)*npwso+icg
931 5484 : if(option/=5)then
932 5120 : write(unitwf) cg(1:2,ipw+1:ipw+npwso) ! VALGRIND complains some elements of cg are not initialized, but written
933 : else
934 0 : write(unitwf)
935 : end if
936 : end do
937 52 : else if(wff%iomode==IO_MODE_MPI)then
938 52 : cg_ptr => cg ! Need pointer to bypass "inout" intent attribute
939 52 : call WffReadWrite_mpio(wff,2,cg_ptr,mcg,icg,nband_disk,npwso,npwsotot,ind_cg_mpi_to_seq,ios)
940 52 : nullify(cg_ptr)
941 0 : else if (wff%iomode == IO_MODE_ETSF .and. option/=5) then
942 :
943 0 : NCF_CHECK(nf90_inq_varid(wff%unwff, "reduced_coordinates_of_plane_waves", kg_varid))
944 0 : NCF_CHECK(nf90_get_att(wff%unwff, kg_varid, "k_dependent", kdep))
945 :
946 : ! The coefficients_of_wavefunctions on file have shape [cplex, mpw, nspinor, mband, nkpt, nsppol]
947 0 : NCF_CHECK(nf90_inq_varid(wff%unwff, "coefficients_of_wavefunctions", cg_varid))
948 : !write(std_out,*)"put cg, count: ",[2,npw,nspinor,nband,1,1]
949 : ncerr = nf90_put_var(wff%unwff, cg_varid, cg(:, icg+1:), start=[1,1,1,1,ikpt,isppol], &
950 0 : count=[2,npw,nspinor,nband,1,1])
951 0 : NCF_CHECK_MSG(ncerr, "putting cg_k")
952 : !write(std_out,*)"after cg"
953 : end if
954 : end if ! option/=4
955 :
956 : ! ===== Case formeig=1: write eigenvalues and wave-functions =====
957 0 : else if(formeig==1)then
958 :
959 : ! Not available for NETCDF and ETSF_IO
960 0 : ABI_CHECK(wff%iomode /= IO_MODE_ETSF, "ETSF-write-eigen1 not coded!")
961 :
962 : ! ABI_CHECK(nband_disk==nband,"nband_disk!=nband")
963 :
964 0 : nband2=2*nband_disk
965 0 : do iband=1,nband_disk
966 0 : ipw=(iband-1)*npwso+icg
967 0 : ii=(iband-1)*nband2
968 0 : if(use_f90==1)then
969 0 : write(unitwf) eigen(1+ii:nband2+ii)
970 0 : if (option/=5) then
971 0 : write(unitwf) cg(1:2,1+ipw:npwso+ipw)
972 : else
973 0 : write(unitwf)
974 : end if
975 0 : else if(wff%iomode==IO_MODE_MPI)then
976 : ! Should use an access with a "view"
977 0 : call xderiveWRecInit(wff,ios)
978 0 : call xderiveWrite(wff,eigen(1+ii:ii+nband2),nband2,wff%spaceComm_mpiio,ios)
979 0 : call xderiveWRecEnd(wff,ios)
980 0 : if (option/=4) then
981 0 : call xderiveWRecInit(wff,ios)
982 0 : call xderiveWrite(wff,cg(1:2,ipw+1:ipw+npwso),2,npwso,wff%spaceComm_mpiio,ios)
983 0 : call xderiveWRecEnd(wff,ios)
984 : end if
985 : end if
986 : end do
987 :
988 : end if ! formeig
989 :
990 : !---------------------------------------------------------------------------
991 : !Final statements
992 : !---------------------------------------------------------------------------
993 :
994 416 : ABI_SFREE(ind_cg_mpi_to_seq)
995 :
996 : RETURN
997 :
998 : !Silence compiler warning.
999 : ABI_UNUSED((/ii,mpi_enreg%me/))
1000 :
1001 416 : end subroutine writewf
1002 : !!***
1003 :
1004 : end module m_rwwf
1005 : !!***
|