Line data Source code
1 : !!****m* ABINIT/m_wfutils
2 : !! NAME
3 : !! m_wfutils
4 : !!
5 : !! FUNCTION
6 : !! parameters and function for wave functions copy
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2001-2026 ABINIT group (CS,GZ,FB)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~ABINIT/Infos/copyright
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_wfutils
23 :
24 : use defs_basis
25 : use m_abicore
26 : use m_errors
27 :
28 : use m_time, only : timab
29 :
30 : implicit none
31 :
32 : private
33 :
34 : public :: setWFParameter ! Definition of wave functions parameters for copy functions.
35 : public :: wfcopy ! Copy of wave functions arrays.
36 :
37 : ! Global variables
38 : integer,save,public ABI_PROTECTED :: x_cplx ! fortran data type for wave functions arrays real or complex.
39 : integer,save,public ABI_PROTECTED :: x_me_g0 ! processor number
40 : integer,save,public ABI_PROTECTED :: x_npw_k ! number of plane waves at this k point
41 : integer,save,public ABI_PROTECTED :: x_nspinor! number of spinorial components of the wavefunctions on current proc
42 : integer,save,public ABI_PROTECTED :: x_icg ! shift to be applied on the location of data in the array cg
43 : integer,save,public ABI_PROTECTED :: x_igsc ! shift to be applied on the location of data in the array gsc
44 : integer,save,public ABI_PROTECTED :: x_blocksize
45 :
46 : contains
47 : !!***
48 :
49 : !!****f* m_wfutils/setWFParameter
50 : !! NAME
51 : !!
52 : !! setWFParameter
53 : !!
54 : !! FUNCTION
55 : !! Initialize wave functions parameters for copy functions
56 : !!
57 : !! INPUTS
58 : !! cplx=fortran data type for wave functions arrays real or complex
59 : !! me_g0=1 if this node treats G=0.
60 : !! npw_k=number of plane waves at this k point
61 : !! nspinor=number of spinorial components of the wavefunctions on current proc
62 : !! icg=shift to be applied on the location of data in the array cg
63 : !! igsc=shift to be applied on the location of data in the array gsc
64 : !! blocksize=size of blocks
65 : !!
66 : !! SOURCE
67 : !!
68 5636 : subroutine setWFParameter(cplx,me_g0,npw_k,nspinor,icg,igsc,blocksize)
69 :
70 : !Arguments ------------------------------------
71 : integer, intent(in) :: cplx,me_g0,npw_k,nspinor
72 : integer, intent(in) :: icg,igsc,blocksize
73 :
74 : ! *********************************************************************
75 :
76 : ! Copy values in global variables
77 5636 : x_cplx=cplx
78 5636 : x_me_g0=me_g0
79 5636 : x_npw_k=npw_k
80 5636 : x_nspinor=nspinor
81 5636 : x_icg=icg
82 5636 : x_igsc=igsc
83 5636 : x_blocksize=blocksize
84 :
85 5636 : end subroutine setWFParameter
86 : !!***
87 :
88 : ! correspondence with abinit. here for real wf
89 : ! this is the index of a given band in cg array
90 8343 : integer function x_cgindex(iblocksize)
91 :
92 : integer, intent(in) :: iblocksize
93 :
94 8343 : x_cgindex=x_npw_k*x_nspinor*(iblocksize-1)+x_icg+1
95 :
96 : end function x_cgindex
97 :
98 : ! correspondence with abinit. here for real wf
99 : ! this is the index of a given band in gsc array
100 2525 : integer function x_gscindex(iblocksize)
101 :
102 : integer, intent(in) :: iblocksize
103 :
104 2525 : x_gscindex=x_npw_k*x_nspinor*(iblocksize-1)+x_igsc+1
105 :
106 : end function x_gscindex
107 :
108 86506 : integer function x_windex(iblocksize)
109 :
110 : integer, intent(in) :: iblocksize
111 :
112 86506 : x_windex=x_npw_k*x_nspinor*(iblocksize-1)+1
113 :
114 : end function x_windex
115 :
116 97374 : integer function wfindex(iblocksize,indtype)
117 :
118 : integer, intent(in) :: iblocksize
119 : character(len=1), intent(in) :: indtype
120 :
121 8343 : select case(indtype)
122 : case ('C')
123 8343 : wfindex=x_cgindex(iblocksize)
124 : case ('S')
125 2525 : wfindex=x_gscindex(iblocksize)
126 : case ('W')
127 86506 : wfindex=x_windex(iblocksize)
128 : case default
129 97374 : ABI_ERROR("Wrong indtype: "//trim(indtype))
130 : end select
131 :
132 97374 : end function wfindex
133 :
134 : !!****f* m_wfutils/wfcopy
135 : !! NAME
136 : !!
137 : !! wfcopy
138 : !!
139 : !! FUNCTION
140 : !! copy of wave functions arrays.
141 : !! called from lobpcg in REAL or COMPLEX wave functions.
142 : !!
143 : !! INPUTS
144 : !! direction=copy direction
145 : !! 'D' direct (global array to local)
146 : !! 'I' indirect (local to global)
147 : !! size=number of elements
148 : !! tsrc=source array
149 : !! incsrc=size increment for tsrc array
150 : !! tdest=destination array
151 : !! incdest=increment for tdest array
152 : !! blockiter=number of block iteration in case REAL
153 : !! iblock=block index
154 : !! indtype=indexation type in array
155 : !! withbbloc=apply block on band for each block
156 : !!
157 : !! TODO
158 : !! Split the two cases so that we can avoid the array descriptors.
159 : !!
160 : !! SOURCE
161 : !!
162 126373 : subroutine wfcopy(direction,size,tsrc,incsrc,tdest,incdest,blockiter,iblock,indtype,&
163 : & withbbloc,timopt,tim_wfcopy) ! optional arguments
164 :
165 : !Arguments ------------------------------------
166 : character(len=1), intent(in) :: direction
167 : integer, intent(in) :: size,incsrc,incdest
168 : integer, intent(in) :: blockiter,iblock
169 : character(len=1), intent(in) :: indtype
170 : logical, optional, intent(in) :: withbbloc
171 : integer, intent(in), optional :: timopt,tim_wfcopy
172 : !arrays
173 : real(dp), DEV_CONTARRD intent(in) :: tsrc(:,:)
174 : real(dp), DEV_CONTARRD intent(inout) :: tdest(:,:)
175 :
176 : !Local variables ------------------------------------
177 : integer,parameter :: ndat1=1
178 : logical :: bblock=.false.
179 : integer :: lig,g1,g2,vectsize,rvectsize
180 : integer :: blocksize,bblocksize,iblocksize,iband
181 : real(dp) :: factor
182 : real(dp) :: tsec(2)
183 :
184 : ! *********************************************************************
185 :
186 126373 : if (present(tim_wfcopy).and.present(timopt)) then
187 126373 : if(abs(timopt)==3) then
188 0 : call timab(tim_wfcopy,1,tsec)
189 : end if
190 : end if
191 :
192 126373 : if (present(withbbloc)) bblock=withbbloc
193 :
194 126373 : if (indtype == 'C') then
195 14658 : lig=x_icg
196 111715 : else if (indtype == 'S') then
197 8062 : lig=x_igsc
198 : else
199 : lig=0
200 : endif
201 :
202 126373 : rvectsize=x_npw_k*x_nspinor
203 126373 : if (x_me_g0 == 1) then
204 47413 : vectsize=2*rvectsize-1
205 : else
206 78960 : vectsize=2*rvectsize
207 : endif
208 126373 : if (x_cplx == 2) vectsize=x_npw_k*x_nspinor
209 :
210 126373 : blocksize = x_blocksize
211 126373 : bblocksize=(iblock-1)*blocksize
212 :
213 126373 : if (direction == 'D') then
214 :
215 81382 : if (x_cplx == 1) then
216 : ! Pack real and imag part.
217 4555 : factor=sqrt(two)
218 28641 : do iblocksize=1,blockiter
219 24086 : iband=iblocksize
220 24086 : if (bblock) then
221 1422 : iband=iblocksize+bblocksize
222 : endif
223 28641 : if (x_me_g0 == 1) then
224 10862 : tdest(1 ,iblocksize)=tsrc(1,wfindex(iband,indtype))
225 10862 : g1 = wfindex(iband, indtype)+1
226 10862 : g2 = wfindex(iband+1,indtype)-1
227 815782 : call dcopy(rvectsize-1,tsrc(1,g1:g2),1,tdest(2:rvectsize,iblocksize),1)
228 413322 : tdest(2:rvectsize,iblocksize) = factor * tdest(2:rvectsize,iblocksize)
229 :
230 815782 : call dcopy(rvectsize-1,tsrc(2,g1:g2),1,tdest(rvectsize+1:vectsize,iblocksize),1)
231 413322 : tdest(rvectsize+1:vectsize,iblocksize) = factor * tdest(rvectsize+1:vectsize,iblocksize)
232 : ! MG FIXME: Here gfortran4.9 allocates temporary arrays due to factor.
233 : else
234 13224 : g1 = wfindex(iband, indtype)
235 13224 : g2 = wfindex(iband+1,indtype)-1
236 462840 : call dcopy(rvectsize,tsrc(1,g1:g2),1,tdest(1:rvectsize,iblocksize),1)
237 238032 : tdest(1:rvectsize,iblocksize) = factor * tdest(1:rvectsize,iblocksize)
238 :
239 462840 : call dcopy(rvectsize,tsrc(2,g1:g2),1,tdest(rvectsize+1:vectsize,iblocksize),1)
240 238032 : tdest(rvectsize+1:vectsize,iblocksize) = factor * tdest(rvectsize+1:vectsize,iblocksize)
241 : end if
242 : end do
243 : else
244 76827 : if (indtype == 'C') then
245 8670 : if (bblock) then
246 5369 : g1 = vectsize*((iblock-1)*blocksize)+lig+1
247 5369 : g2 = vectsize*(iblock*blocksize)+lig
248 5369 : call zcopy(size,tsrc(:,g1:g2),incsrc,tdest(:,1:blocksize),incdest)
249 : else
250 3301 : g1 = lig+1
251 3301 : g2 = vectsize*((iblock-1)*blocksize)+lig
252 3301 : call zcopy(size,tsrc(:,g1:g2),incsrc,tdest(:,1:bblocksize),incdest)
253 : end if
254 68157 : else if (indtype == 'S') then
255 3213 : g1 = lig+1
256 3213 : g2 = vectsize*((iblock-1)*blocksize)+lig
257 3213 : call zcopy(size,tsrc(:,g1:g2),incsrc,tdest(:,1:bblocksize),incdest)
258 : else
259 64944 : call zcopy(size,tsrc,incsrc,tdest,incdest)
260 : endif
261 : end if
262 :
263 44991 : else if (direction == 'I') then
264 44991 : if (x_cplx == 1) then
265 : ! Unpack real and imag blocks.
266 2485 : factor=one/sqrt(two)
267 15778 : do iblocksize=1,blockiter
268 13293 : iband=iblocksize
269 13293 : if ( bblock ) then
270 2156 : iband=iblocksize+(iblock-1)*blocksize
271 : end if
272 15778 : if (x_me_g0 == 1) then
273 5877 : tdest(1,wfindex(iband,indtype))=tsrc(1,iblocksize)
274 5877 : tdest(2,wfindex(iband,indtype))=zero
275 :
276 5877 : g1 = wfindex(iband,indtype)+1
277 5877 : g2 = wfindex(iband+1,indtype)-1
278 451377 : call dcopy(rvectsize-1,tsrc(2:rvectsize,iblocksize),1,tdest(1,g1:g2),1)
279 228627 : tdest(1,g1:g2) = factor * tdest(1,g1:g2)
280 :
281 451377 : call dcopy(rvectsize-1,tsrc(rvectsize+1:vectsize,iblocksize),1,tdest(2,g1:g2),1)
282 228627 : tdest(2,g1:g2) = factor * tdest(2,g1:g2)
283 : else
284 7416 : g1 = wfindex(iband,indtype)
285 7416 : g2 = wfindex(iband+1,indtype)-1
286 259560 : call dcopy(rvectsize,tsrc(1:rvectsize,iblocksize),1,tdest(1,g1:g2),1)
287 133488 : tdest(1,g1:g2) = factor * tdest(1,g1:g2)
288 259560 : call dcopy(rvectsize,tsrc(rvectsize+1:vectsize,iblocksize),1,tdest(2,g1:g2),1)
289 133488 : tdest(2,g1:g2) = factor * tdest(2,g1:g2)
290 : end if
291 : end do
292 : else
293 42506 : if (indtype == 'C') then
294 5369 : g1 = vectsize*((iblock-1)*blocksize)+lig+1
295 5369 : g2 = vectsize*(iblock*blocksize)+lig
296 5369 : call zcopy(size,tsrc,1,tdest(:,g1:g2),1)
297 37137 : else if ( indtype == 'S' ) then
298 4665 : g1 = vectsize*((iblock-1)*blocksize)+lig+1
299 4665 : g2 = vectsize*(iblock*blocksize)+lig
300 4665 : call zcopy(size,tsrc,1,tdest(:,g1:g2),1)
301 : else
302 32472 : call zcopy(size,tsrc,1,tdest,1)
303 : end if
304 : end if
305 : else
306 0 : ABI_ERROR("Wrong direction: "//trim(direction))
307 : endif
308 :
309 126373 : if (present(tim_wfcopy).and.present(timopt)) then
310 126373 : if(abs(timopt)==3) then
311 0 : call timab(tim_wfcopy,2,tsec)
312 : end if
313 : end if
314 :
315 126373 : end subroutine wfcopy
316 : !!***
317 :
318 : end module m_wfutils
319 : !!***
|