Branch data Line data Source code
1 : : !!****m* ABINIT/m_sgfft
2 : : !! NAME
3 : : !! m_sgfft
4 : : !!
5 : : !! FUNCTION
6 : : !! This module provides low-level interfaces to Goedecker's FFT library.
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright by Stefan Goedecker, Ithaca, NY USA, July 14, 1993
10 : : !! Copyright (C) 1998-2026 ABINIT group (DCA, XG)
11 : : !! This file is distributed under the terms of the
12 : : !! GNU General Public License, see ~abinit/COPYING
13 : : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : : !!
15 : : !! SOURCE
16 : :
17 : : #if defined HAVE_CONFIG_H
18 : : #include "config.h"
19 : : #endif
20 : :
21 : : #include "abi_common.h"
22 : :
23 : : MODULE m_sgfft
24 : :
25 : : use defs_basis
26 : : use m_abicore
27 : : use m_errors
28 : : use m_fftcore
29 : :
30 : : use m_fstrings, only : sjoin, itoa
31 : : use defs_fftdata, only : mg
32 : :
33 : : implicit none
34 : :
35 : : private
36 : :
37 : : ! Public API.
38 : : public :: sg_fft_cc ! Complex-Complex version (full box)
39 : : public :: sg_fft_rc ! Real-Complex version (full box)
40 : : public :: sg_fftpad ! Zero-padding version of "fft".
41 : : public :: sg_fftrisc ! Fourier transforms of wavefunctions
42 : : public :: sg_fftrisc_2
43 : : public :: sg_poisson ! Solve the poisson equation in G-space starting from n(r).
44 : :
45 : : CONTAINS !====================================================================
46 : : !!***
47 : :
48 : :
49 : : !!****f* m_sgfft/sg_fft_cc
50 : : !! NAME
51 : : !! sg_fft_cc
52 : : !!
53 : : !! FUNCTION
54 : : !! Calculates the discrete Fourier transform:
55 : : !!
56 : : !! ftarr(i1,i2,i3)=exp(ris*i*2*pi*(j1*i1/n1+j2*i2/n2+j3*i3/n3)) arr(j1,j2,j3)
57 : : !!
58 : : !! INPUTS
59 : : !! fftcache=size of the cache (kB)
60 : : !! n1,n2,n3=physical dimension of the transform
61 : : !! nd1,nd2,nd3=memory dimension of arr and ftarr
62 : : !! ndat=Number of FFT transforms
63 : : !! isign=+1 for G-->R, -1 for R-->G
64 : : !! arr(2,nd1*nd2*nd3*ndat)=input complex array with alternating real and imaginary
65 : : !! elements; data resides in 2*n1*n2*n3 of this array, spread out.
66 : : !! (see SIDE FFECTS).
67 : : !!
68 : : !! OUTPUT
69 : : !! ftarr(2,nd1*nd2*nd3*ndat)=working space for transform and contains output
70 : : !!
71 : : !! SIDE EFFECTS
72 : : !! arr(2,nd1*nd2*nd3*ndat) is modified by sg_fftx,sg_ffty,sg_fftz.
73 : : !!
74 : : !! NOTES
75 : : !! ndi must always be greater or equal to ni. Recommended choice for nd1
76 : : !! and nd2 is: ni for ni=odd or ni+1 for ni=even (hence 2*(ni/2)+1);
77 : : !! nd3 should always be n3. Note that choosing nd1 or nd2 larger than
78 : : !! the recommended value can severely degrade efficiency of this routine.
79 : : !! Avoiding even ndi for nd1 and nd2 avoids cache conflicts on cache machines.
80 : : !! Each of n1,n2,n3 must be a
81 : : !! product of the prime factors 2,3,5. If two ni s are equal
82 : : !! it is recommended to place them behind each other.
83 : : !! The largest any of these may be is set by parameter "mg" below.
84 : : !! This fft is particularly efficient for cache architectures.
85 : : !! Note that the meaning of fftcache has changed from the original
86 : : !! ncache of SG (that was the maximum number of COMPLEX*16 in the cache)
87 : : !!
88 : : !! SOURCE
89 : :
90 : 37573 : subroutine sg_fft_cc(fftcache,n1,n2,n3,nd1,nd2,nd3,ndat,isign,arr,ftarr)
91 : :
92 : : !Arguments ------------------------------------
93 : : !scalars
94 : : integer,intent(in) :: fftcache,n1,n2,n3,nd1,nd2,nd3,ndat,isign
95 : : !arrays
96 : : real(dp),intent(inout) :: arr(2,nd1*nd2*nd3*ndat)
97 : : real(dp),intent(inout) :: ftarr(2,nd1*nd2*nd3*ndat)
98 : :
99 : : !Local variables-------------------------------
100 : : !scalars
101 : : integer :: idat,start
102 : :
103 : : ! *************************************************************************
104 : :
105 [ + + ]: 75188 : do idat=1,ndat
106 : 37615 : start = 1 + (idat-1)*nd1*nd2*nd3
107 : 75188 : call fft_cc_one_nothreadsafe(fftcache,nd1,nd2,nd3,n1,n2,n3,arr(1,start),ftarr(1,start),real(isign,kind=dp))
108 : : end do
109 : :
110 : 37573 : end subroutine sg_fft_cc
111 : : !!***
112 : :
113 : : !----------------------------------------------------------------------
114 : :
115 : : !!****f* m_sgfft/fft_cc_one_nothreadsafe
116 : : !! NAME
117 : : !! fft_cc_one_nothreadsafe
118 : : !!
119 : : !! FUNCTION
120 : : !! Calculates the discrete Fourier transform:
121 : : !!
122 : : !! ftarr(i1,i2,i3)=exp(ris*i*2*pi*(j1*i1/n1+j2*i2/n2+j3*i3/n3)) arr(j1,j2,j3)
123 : : !!
124 : : !! INPUTS
125 : : !! fftcache=size of the cache (kB)
126 : : !! nd1,nd2,nd3=memory dimension of arr and ftarr
127 : : !! n1,n2,n3=physical dimension of the transform
128 : : !! arr(2,nd1,nd2,nd3)=input complex array with alternating real and imaginary
129 : : !! elements; data resides in 2*n1*n2*n3 of this array, spread out.
130 : : !! (see SIDE FFECTS).
131 : : !! ris=(real(dp)) sign of exponential in transform
132 : : !!
133 : : !! OUTPUT
134 : : !! ftarr(2,nd1,nd2,nd3)=working space for transform and contains output
135 : : !!
136 : : !! SIDE EFFECTS
137 : : !! arr(2,nd1,nd2,nd3) is modified by sg_fftx,sg_ffty,sg_fftz.
138 : : !!
139 : : !! NOTES
140 : : !! ndi must always be greater or equal to ni. Recommended choice for nd1
141 : : !! and nd2 is: ni for ni=odd or ni+1 for ni=even (hence 2*(ni/2)+1);
142 : : !! nd3 should always be n3. Note that choosing nd1 or nd2 larger than
143 : : !! the recommended value can severely degrade efficiency of this routine.
144 : : !! Avoiding even ndi for nd1 and nd2 avoids cache conflicts on cache machines.
145 : : !! Each of n1,n2,n3 must be a
146 : : !! product of the prime factors 2,3,5. If two ni s are equal
147 : : !! it is recommended to place them behind each other.
148 : : !! The largest any of these may be is set by parameter "mg" below.
149 : : !! This fft is particularly efficient for cache architectures.
150 : : !! Note that the meaning of fftcache has changed from the original
151 : : !! ncache of SG (that was the maximum number of COMPLEX*16 in the cache)
152 : : !!
153 : : !! SOURCE
154 : :
155 : 37615 : subroutine fft_cc_one_nothreadsafe(fftcache,nd1,nd2,nd3,n1,n2,n3,arr,ftarr,ris)
156 : :
157 : : !Arguments ------------------------------------
158 : : !scalars
159 : : integer,intent(in) :: fftcache,n1,n2,n3,nd1,nd2,nd3
160 : : real(dp),intent(in) :: ris
161 : : !arrays
162 : : real(dp),intent(inout) :: arr(2,nd1,nd2,nd3)
163 : : real(dp),intent(inout) :: ftarr(2,nd1,nd2,nd3) !vz_i
164 : :
165 : : !Local variables-------------------------------
166 : : !mfac sets maximum number of factors (5, 4, 3, or 2) which may be
167 : : !contained within any n1, n2, or n3
168 : : !mg sets the maximum 1 dimensional fft length (any one of n1, n2, or n3)
169 : : !scalars
170 : : integer,parameter :: mfac=11
171 : : integer :: i2,ic,n1i,n3i
172 : : character(len=500) :: message
173 : : !arrays
174 : : integer :: aft(mfac),bef(mfac),ind(mg),now(mfac)
175 : : real(dp) :: trig(2,mg)
176 : :
177 : : ! *************************************************************************
178 : :
179 : : !Check that dimension is not exceeded
180 [ + - + - : 37615 : if (n1>mg.or.n2>mg.or.n3>mg) then
- + ]
181 : : write(message, '(a,3i10,a,i10,a)' )&
182 : 0 : & 'one of the dimensions n1,n2,n3=',n1,n2,n3,&
183 : 0 : & 'exceeds allowed dimension mg=',mg,ch10
184 : 0 : ABI_BUG(message)
185 : : end if
186 : :
187 : : !transform along x direction
188 : 37615 : call sg_ctrig(n1,trig,aft,bef,now,ris,ic,ind,mfac,mg)
189 : : call sg_fftx(fftcache,mfac,mg,nd1,nd2,nd3,n2,n3,&
190 : 37615 : & arr,ftarr,trig,aft,now,bef,ris,ind,ic)
191 : :
192 : : ! This to handle 1d FFTs
193 [ - + - - ]: 37615 : if (n2 == 1 .and. n3 == 1) then
194 : : !print *, "Returning as n2, n3:", n2, n3
195 : 0 : return
196 : : end if
197 : :
198 : : !transform along y direction
199 [ + + ]: 37615 : if (n2/=n1)then
200 : 1524 : call sg_ctrig(n2,trig,aft,bef,now,ris,ic,ind,mfac,mg)
201 : : end if
202 : 37615 : n1i=1 ; n3i=1
203 : : call sg_ffty(fftcache,mfac,mg,nd1,nd2,nd3,n1i,n1,n3i,n3,&
204 : 37615 : & ftarr,arr,trig,aft,now,bef,ris,ind,ic)
205 : :
206 : : !transform along z direction
207 [ + + ]: 37615 : if (n3/=n2)then
208 : 32367 : call sg_ctrig(n3,trig,aft,bef,now,ris,ic,ind,mfac,mg)
209 : : end if
210 : :
211 : : !$OMP PARALLEL DO SHARED(aft,arr,bef,ftarr,ind,ic)&
212 : : !$OMP SHARED(nd1,nd2,nd3,now,n1,n2,ris,trig)&
213 : : !$OMP PRIVATE(i2)
214 [ + + ]: 457182 : do i2=1,n2
215 : : call sg_fftz(mfac,mg,nd1,nd2,nd3,n1,i2,i2,arr,ftarr,&
216 : 457182 : & trig,aft,now,bef,ris,ind,ic)
217 : : end do
218 : : !$OMP END PARALLEL DO
219 : :
220 : : end subroutine fft_cc_one_nothreadsafe
221 : : !!***
222 : :
223 : : !----------------------------------------------------------------------
224 : :
225 : : !!****f* m_sgfft/sg_fft_rc
226 : : !! NAME
227 : : !! sg_fft_rc
228 : : !!
229 : : !! FUNCTION
230 : : !! Conduct Fourier transform of REAL or COMPLEX function f(r)=fofr defined on
231 : : !! fft grid in real space, to create complex f(G)=fofg defined on full fft grid
232 : : !! in reciprocal space, in full storage mode, or the reverse operation.
233 : : !! For the reverse operation, the final data is divided by nfftot.
234 : : !! REAL case when cplex=1, COMPLEX case when cplex=2. Usually used for density and potentials.
235 : : !!
236 : : !! There are two different possibilities :
237 : : !! fftalgb=0 means using the complex-to-complex FFT routine,
238 : : !! irrespective of the value of cplex
239 : : !! fftalgb=1 means using a real-to-complex FFT or a complex-to-complex FFT,
240 : : !! depending on the value of cplex.
241 : : !! The only real-to-complex FFT available is from SGoedecker library.
242 : : !!
243 : : !! INPUTS
244 : : !! cplex=1 if fofr is real, 2 if fofr is complex
245 : : !! isign=sign of Fourier transform exponent: current convention uses
246 : : !! +1 for transforming from G to r
247 : : !! -1 for transforming from r to G.
248 : : !! nfft=(effective) number of FFT grid points (for this processor)
249 : : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
250 : : !!
251 : : !! OUTPUT
252 : : !! (see side effects)
253 : : !!
254 : : !! SIDE EFFECTS
255 : : !! Input/Output
256 : : !! fofg(2,nfft)=f(G), complex.
257 : : !! fofr(cplex*nfft)=input function f(r) (real or complex)
258 : : !!
259 : : !! SOURCE
260 : :
261 : 7692 : subroutine sg_fft_rc(cplex,fofg,fofr,isign,nfft,ngfft)
262 : :
263 : : !Arguments ------------------------------------
264 : : !scalars
265 : : integer,intent(in) :: cplex,isign,nfft
266 : : !arrays
267 : : integer,intent(in) :: ngfft(18)
268 : : real(dp),intent(inout) :: fofg(2,nfft),fofr(cplex*nfft)
269 : :
270 : : !Local variables-------------------------------
271 : : !scalars
272 : : integer,parameter :: mfac=11
273 : : integer :: fftalg,fftalga,fftalgb,fftcache,i1,i2,i3,ic1,ic2,ic3,index
274 : : integer :: n1,n1half1,n1halfm,n2,n2half1,n3,n4,n4half1,n5,n5half1,n6
275 : : real(dp) :: ris,xnorm
276 : : character(len=500) :: msg
277 : : !arrays
278 : : integer :: aft1(mfac),aft2(mfac),aft3(mfac),bef1(mfac),bef2(mfac),bef3(mfac)
279 : : integer :: ind1(mg),ind2(mg),ind3(mg),now1(mfac),now2(mfac),now3(mfac)
280 : : real(dp) :: trig1(2,mg),trig2(2,mg),trig3(3,mg)
281 : 7692 : real(dp),allocatable :: wk2d_a(:,:,:,:),wk2d_b(:,:,:,:),wk2d_c(:,:,:,:)
282 : 7692 : real(dp),allocatable :: wk2d_d(:,:,:,:),work1(:,:,:,:),work2(:,:,:,:)
283 : :
284 : : ! *************************************************************************
285 : :
286 : : !DBG_ENTER("COLL")
287 : :
288 : 7692 : n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
289 : 7692 : n4=ngfft(4); n5=ngfft(5); n6=ngfft(6)
290 : :
291 : 7692 : fftcache=ngfft(8)
292 : 7692 : fftalg =ngfft(7)
293 : 7692 : fftalga =fftalg/100
294 : 7692 : fftalgb =mod(fftalg,100)/10
295 : :
296 : 7692 : ris=dble(isign)
297 : 7692 : xnorm=1.0d0/dble(n1*n2*n3)
298 : :
299 [ - + ]: 7692 : if (fftalgb/=0 .and. fftalgb/=1) then
300 : : write(msg, '(a,i4,a,a,a,a,a)' )&
301 : 0 : & 'The input algorithm number fftalg=',fftalg,' is not allowed.',ch10,&
302 : 0 : & 'The second digit (fftalg(B)) must be 0 or 1.',ch10,&
303 : 0 : & 'Action: change fftalg in your input file.'
304 : 0 : ABI_BUG(msg)
305 : : end if
306 : :
307 [ + - - + : 7692 : if (fftalgb==1 .and. ALL(fftalga/=(/1,3,4/)) )then
- - ]
308 : : write(msg,'(a,i4,5a)')&
309 : 0 : & 'The input algorithm number fftalg=',fftalg,' is not allowed.',ch10,&
310 : 0 : & 'When fftalg(B) is 1, the allowed values for fftalg(A) are 1 and 4.',ch10,&
311 : 0 : & 'Action: change fftalg in your input file.'
312 : 0 : ABI_BUG(msg)
313 : : end if
314 : :
315 [ + - - + ]: 7692 : if (n4<n1.or.n5<n2.or.n6<n3) then
316 : 0 : write(msg,'(a,3i8,a,3i8)')' Each of n4,n5,n6=',n4,n5,n6,'must be >= n1, n2, n3 =',n1,n2,n3
317 : 0 : ABI_BUG(msg)
318 : : end if
319 : :
320 : : !---------------------------------------------------------
321 : : !Here sophisticated algorithm based on S. Goedecker routines, only for the REAL case.
322 : : !Take advantage of the fact that fofr is real, and that fofg has corresponding symmetry properties.
323 : :
324 : : #ifdef DEBUG_MODE
325 : : if (n1>mg .or. n2>mg .or. n3>mg) then
326 : : write(msg, '(a,3i10,a,a,a,i10,a)' )&
327 : : & 'One of the dimensions n1,n2,n3=',n1,n2,n3,',',ch10,&
328 : : & 'exceeds allowed dimension mg=',mg,'.'
329 : : ABI_BUG(msg)
330 : : end if
331 : : #endif
332 : :
333 : 7692 : n1half1=n1/2+1 ; n1halfm=(n1+1)/2
334 : 7692 : n2half1=n2/2+1
335 : : !n4half1 or n5half1 are the odd integers >= n1half1 or n2half1
336 : 7692 : n4half1=(n1half1/2)*2+1
337 : 7692 : n5half1=(n2half1/2)*2+1
338 : :
339 : : !This sophisticated algorithm allows to decrease the memory needs.
340 [ - + + - : 38460 : ABI_MALLOC(work1,(2,n4,n5half1,n6))
- + + - -
+ + - + -
+ - - + -
+ ]
341 [ - + + - : 30768 : ABI_MALLOC(work2,(2,n4,n5half1,n6))
- + + - -
+ + - - +
- + ]
342 : :
343 [ + + ]: 7692 : if(isign==1)then
344 : :
345 : : ! Compute auxiliary arrays needed for FFTs, here forward FFT
346 : 4052 : call sg_ctrig(n1,trig1,aft1,bef1,now1,one,ic1,ind1,mfac,mg)
347 : 4052 : call sg_ctrig(n2,trig2,aft2,bef2,now2,one,ic2,ind2,mfac,mg)
348 : 4052 : call sg_ctrig(n3,trig3,aft3,bef3,now3,one,ic3,ind3,mfac,mg)
349 : :
350 : : ! Transfer fofg to the expanded fft box (only half of it)
351 : :
352 : : !$OMP PARALLEL DO PRIVATE(i1,i2,i3,index) SHARED(fofg,n1,n2,n3,work1)
353 [ + + ]: 107768 : do i3=1,n3
354 [ + + ]: 1562292 : do i2=1,n2half1
355 : 1454524 : index=n1*(i2-1+n2*(i3-1))
356 [ + + ]: 45729432 : do i1=1,n1
357 : 44171192 : work1(1,i1,i2,i3)=fofg(1,i1+index)
358 : 45625716 : work1(2,i1,i2,i3)=fofg(2,i1+index)
359 : : end do
360 : : end do
361 : : end do
362 : :
363 : : !$OMP PARALLEL DO SHARED(aft3,bef3,ind3,ic3,now3,n1,n2half1,n4,n5half1,n6,ris,trig3,work1,work2) PRIVATE(i2)
364 [ + + ]: 54779 : do i2=1,n2half1
365 : : call sg_fftz(mfac,mg,n4,n5half1,n6,n1,i2,i2,work1,work2,&
366 : 54779 : & trig3,aft3,now3,bef3,ris,ind3,ic3)
367 : : end do
368 : :
369 : : ! Loop over x-y planes
370 : :
371 : : !$OMP PARALLEL PRIVATE(i1,i2,i3,index,wk2d_a,wk2d_b,wk2d_c,wk2d_d) &
372 : : !$OMP&SHARED(aft1,aft2,bef1,bef2,fftcache,fofg,fofr,ic1,ic2,ind1,ind2) &
373 : : !$OMP&SHARED(n1,n1half1,n1halfm,n2,n2half1,n3) &
374 : : !$OMP&SHARED(n4,n5,now1,now2,ris,trig1,trig2,work2)
375 : :
376 [ - + + - : 16208 : ABI_MALLOC(wk2d_a,(2,n4,n5,1))
- + + - +
- + - - +
- + ]
377 [ - + + - : 12156 : ABI_MALLOC(wk2d_b,(2,n4,n5,1))
- + + - -
+ - + ]
378 [ + - - + : 16208 : ABI_MALLOC(wk2d_c,(2,2*n1halfm+1,n5,1))
+ - - + +
- + - + -
- + - + ]
379 [ - + + - : 12156 : ABI_MALLOC(wk2d_d,(2,2*n1halfm+1,n5,1))
- + + - -
+ + - ]
380 : :
381 : : !$OMP DO
382 [ + + ]: 107768 : do i3=1,n3
383 : :
384 [ + + ]: 1558240 : do i2=1,n2half1
385 [ + + ]: 45729432 : do i1=1,n1
386 : 44171192 : wk2d_c(1,i1,i2,1)=work2(1,i1,i2,i3)
387 : 45625716 : wk2d_c(2,i1,i2,1)=work2(2,i1,i2,i3)
388 : : end do
389 : : end do
390 : :
391 : : call sg_fftx(fftcache,mfac,mg,2*n1halfm+1,n5,1,n2half1,1,wk2d_c,wk2d_d,&
392 : 103716 : & trig1,aft1,now1,bef1,ris,ind1,ic1)
393 : :
394 [ + + ]: 1461004 : do i1=1,n1half1-1 ! Compute symmetric and antisymmetric combinations
395 : 1357288 : wk2d_a(1,i1,1,1)=wk2d_d(1,2*i1-1,1,1)
396 : 1461004 : wk2d_a(2,i1,1,1)=wk2d_d(1,2*i1 ,1,1)
397 : : end do
398 : :
399 [ + + ]: 103716 : if((2*n1half1-2)/=n1)then ! If n1 odd, must add last data
400 : 11250 : wk2d_a(1,n1half1,1,1)=wk2d_d(1,n1,1,1)
401 : 11250 : wk2d_a(2,n1half1,1,1)=0.0d0
402 : : end if
403 : :
404 [ + + ]: 1454524 : do i2=2,n2half1
405 [ + + ]: 22034116 : do i1=1,n1half1-1
406 : 20683308 : wk2d_a(1,i1,i2,1) = wk2d_d(1,2*i1-1,i2,1)-wk2d_d(2,2*i1,i2,1)
407 : 20683308 : wk2d_a(2,i1,i2,1) = wk2d_d(2,2*i1-1,i2,1)+wk2d_d(1,2*i1,i2,1)
408 : 20683308 : wk2d_a(1,i1,n2+2-i2,1)= wk2d_d(1,2*i1-1,i2,1)+wk2d_d(2,2*i1,i2,1)
409 : 22034116 : wk2d_a(2,i1,n2+2-i2,1)=-wk2d_d(2,2*i1-1,i2,1)+wk2d_d(1,2*i1,i2,1)
410 : : end do
411 [ + + ]: 1454524 : if((2*n1half1-2)/=n1)then
412 : 78750 : wk2d_a(1,n1half1,i2,1) = wk2d_d(1,n1,i2,1)
413 : 78750 : wk2d_a(2,n1half1,i2,1) = wk2d_d(2,n1,i2,1)
414 : 78750 : wk2d_a(1,n1half1,n2+2-i2,1)= wk2d_d(1,n1,i2,1)
415 : 78750 : wk2d_a(2,n1half1,n2+2-i2,1)=-wk2d_d(2,n1,i2,1)
416 : : end if
417 : : end do
418 : :
419 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,1,n1halfm,1,1,wk2d_a,wk2d_b,&
420 : 103716 : & trig2,aft2,now2,bef2,ris,ind2,ic2)
421 : :
422 [ + + ]: 2820634 : do i2=1,n2 ! Take real part data from expanded box and put it in the original box.
423 : 2712866 : index=n1*(i2-1+n2*(i3-1))
424 [ + + ]: 44158232 : do i1=1,n1half1-1 ! copy data
425 : 41445366 : fofr(2*i1-1+index)=wk2d_b(1,i1,i2,1)
426 : 44158232 : fofr(2*i1 +index)=wk2d_b(2,i1,i2,1)
427 : : end do
428 [ + + ]: 2816582 : if((2*n1half1-2)/=n1)then ! If n1 odd, must add last data
429 : 168750 : fofr(n1+index)=wk2d_b(1,n1half1,i2,1)
430 : : end if
431 : : end do
432 : :
433 : : end do ! loop over x-y planes
434 : : !$OMP END DO
435 [ - + ]: 4052 : ABI_FREE(wk2d_a)
436 [ - + ]: 4052 : ABI_FREE(wk2d_b)
437 [ - + ]: 4052 : ABI_FREE(wk2d_c)
438 [ - + ]: 4052 : ABI_FREE(wk2d_d)
439 : : !$OMP END PARALLEL
440 : :
441 [ + - ]: 3640 : else if(isign==-1)then
442 : :
443 : : ! Compute auxiliary arrays needed for FFTs, here backward FFT
444 : 3640 : call sg_ctrig(n1,trig1,aft1,bef1,now1,-one,ic1,ind1,mfac,mg)
445 : 3640 : call sg_ctrig(n2,trig2,aft2,bef2,now2,-one,ic2,ind2,mfac,mg)
446 : 3640 : call sg_ctrig(n3,trig3,aft3,bef3,now3,-one,ic3,ind3,mfac,mg)
447 : :
448 : : ! Treat first x-transform in x-y plane, and multiply
449 : : ! by overall normalization factor 1/nfftot
450 : :
451 : : ! Loop over x-y planes
452 : :
453 : : !$OMP PARALLEL PRIVATE(i1,i2,i3,index,wk2d_a,wk2d_b,wk2d_c,wk2d_d) &
454 : : !$OMP&SHARED(aft1,aft2,bef1,bef2,fftcache,fofr,ic1,ic2,ind1,ind2) &
455 : : !$OMP&SHARED(n1,n1half1,n1halfm,n2,n2half1,n3) &
456 : : !$OMP&SHARED(n4,n5,now1,now2,ris,trig1,trig2,work1,xnorm)
457 : :
458 [ - + + - : 14560 : ABI_MALLOC(wk2d_a,(2,n4,n5,1))
- + + - +
- + - - +
- + ]
459 [ - + + - : 10920 : ABI_MALLOC(wk2d_b,(2,n4,n5,1))
- + + - -
+ - + ]
460 [ + - - + : 14560 : ABI_MALLOC(wk2d_c,(2,2*n1halfm+1,n5,1))
+ - - + +
- + - + -
- + - + ]
461 [ - + + - : 10920 : ABI_MALLOC(wk2d_d,(2,2*n1halfm+1,n5,1))
- + + - -
+ + - ]
462 : :
463 : : !$OMP DO
464 [ + + ]: 103612 : do i3=1,n3
465 [ + + ]: 2816610 : do i2=1,n2
466 : 2716638 : index=n1*(i2-1+n2*(i3-1))
467 [ + + ]: 45028224 : do i1=1,n1half1-1 ! copy and normalize data
468 : 42311586 : wk2d_a(1,i1,i2,1)=fofr(2*i1-1+index)*xnorm
469 : 45028224 : wk2d_a(2,i1,i2,1)=fofr(2*i1 +index)*xnorm
470 : : end do
471 : :
472 [ + + ]: 2816610 : if((2*n1half1-2)/=n1)then ! If n1 odd, must add last data
473 : 115650 : wk2d_a(1,n1half1,i2,1)=fofr(n1+index)*xnorm
474 : 115650 : wk2d_a(2,n1half1,i2,1)=zero
475 : : end if
476 : : end do
477 : :
478 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,1,n1halfm,1,1,wk2d_a,wk2d_b,&
479 : 99972 : & trig2,aft2,now2,bef2,ris,ind2,ic2)
480 : :
481 [ + + ]: 1467654 : do i1=1,n1halfm ! Decompose symmetric and antisymmetric parts
482 : 1367682 : wk2d_c(1,2*i1-1,1,1)=wk2d_b(1,i1,1,1)
483 : 1367682 : wk2d_c(2,2*i1-1,1,1)=0.0d0
484 : 1367682 : wk2d_c(1,2*i1,1,1)=wk2d_b(2,i1,1,1)
485 : 1467654 : wk2d_c(2,2*i1,1,1)=0.0d0
486 : : end do
487 : :
488 [ + + ]: 1454436 : do i2=2,n2half1
489 [ + + ]: 22637214 : do i1=1,n1halfm
490 : 21182778 : wk2d_c(1,2*i1-1,i2,1)= (wk2d_b(1,i1,i2,1)+wk2d_b(1,i1,n2+2-i2,1))*0.5d0
491 : 21182778 : wk2d_c(2,2*i1-1,i2,1)= (wk2d_b(2,i1,i2,1)-wk2d_b(2,i1,n2+2-i2,1))*0.5d0
492 : 21182778 : wk2d_c(1,2*i1,i2,1) = (wk2d_b(2,i1,i2,1)+wk2d_b(2,i1,n2+2-i2,1))*0.5d0
493 : 22537242 : wk2d_c(2,2*i1,i2,1) =-(wk2d_b(1,i1,i2,1)-wk2d_b(1,i1,n2+2-i2,1))*0.5d0
494 : : end do
495 : : end do
496 : :
497 : : call sg_fftx(fftcache,mfac,mg,2*n1halfm+1,n5,1,n2half1,1,wk2d_c,wk2d_d,&
498 : 99972 : & trig1,aft1,now1,bef1,ris,ind1,ic1)
499 : :
500 [ + + ]: 1558048 : do i2=1,n2half1
501 [ + + ]: 46593648 : do i1=1,n1
502 : 45039240 : work1(1,i1,i2,i3)=wk2d_d(1,i1,i2,1)
503 : 46493676 : work1(2,i1,i2,i3)=wk2d_d(2,i1,i2,1)
504 : : end do
505 : : end do
506 : :
507 : : end do
508 : : !$OMP END DO
509 [ - + ]: 3640 : ABI_FREE(wk2d_a)
510 [ - + ]: 3640 : ABI_FREE(wk2d_b)
511 [ - + ]: 3640 : ABI_FREE(wk2d_c)
512 [ - + ]: 3640 : ABI_FREE(wk2d_d)
513 : : !$OMP END PARALLEL
514 : :
515 : : !$OMP PARALLEL DO SHARED(aft3,bef3,ind3,ic3,now3,n1,n2half1,n4,n5half1,n6,ris,trig3,work1,work2) PRIVATE(i2)
516 [ + + ]: 51723 : do i2=1,n2half1
517 : : call sg_fftz(mfac,mg,n4,n5half1,n6,n1,i2,i2,work1,work2,&
518 : 51723 : & trig3,aft3,now3,bef3,ris,ind3,ic3)
519 : : end do
520 : :
521 : : ! Transfer fft output to the original fft box
522 : :
523 : : !$OMP PARALLEL DO PRIVATE(i1,i2,i3,index) SHARED(fofg,n1,n2,n2half1,n3,work2)
524 [ + + ]: 103612 : do i3=1,n3
525 [ + + ]: 1554408 : do i2=1,n2half1
526 : 1454436 : index=n1*(i2-1+n2*(i3-1))
527 [ + + ]: 46593648 : do i1=1,n1
528 : 45039240 : fofg(1,i1+index)=work2(1,i1,i2,i3)
529 : 46493676 : fofg(2,i1+index)=work2(2,i1,i2,i3)
530 : : end do
531 : : end do
532 : : ! Complete missing values with complex conjugate
533 : : ! Inverse of ix is located at nx+2-ix , except for ix=1, for which it is 1.
534 [ + - ]: 103612 : if(n2half1>2)then
535 [ + + ]: 1362174 : do i2=2,n2+1-n2half1
536 : 1262202 : index=n1*((n2+2-i2)-1)
537 [ + + ]: 1262202 : if(i3/=1)index=index+n1*n2*((n3+2-i3)-1)
538 : 1262202 : fofg(1,1+index)= work2(1,1,i2,i3)
539 : 1262202 : fofg(2,1+index)=-work2(2,1,i2,i3)
540 [ + + ]: 39799554 : do i1=2,n1
541 : 38437380 : fofg(1,n1+2-i1+index)= work2(1,i1,i2,i3)
542 : 39699582 : fofg(2,n1+2-i1+index)=-work2(2,i1,i2,i3)
543 : : end do
544 : : end do
545 : : end if
546 : : end do
547 : :
548 : : end if ! choice of isign
549 : :
550 [ - + ]: 7692 : ABI_FREE(work1)
551 [ - + ]: 7692 : ABI_FREE(work2)
552 : :
553 : : !DBG_EXIT("COLL")
554 : :
555 : 7692 : end subroutine sg_fft_rc
556 : : !!***
557 : :
558 : : !----------------------------------------------------------------------
559 : :
560 : : !!****f* m_sgfft/sg_fftpad
561 : : !! NAME
562 : : !! sg_fftpad
563 : : !!
564 : : !! FUNCTION
565 : : !! Fast Fourier transform. This is the zero-padding version of "fft".
566 : : !!
567 : : !! INPUTS
568 : : !! fftcache=size of the cache (kB)
569 : : !! mgfft=maximum size of 1D FFTs
570 : : !! n1,n2,n3=physical dimension of the transform
571 : : !! nd1,nd2,nd3=memory dimension of arr and ftarr
572 : : !! ndat=Number of FFT transforms.
573 : : !! isign= sign of exponential in transform
574 : : !! gbound(2*mgfft+8,2)=sphere boundary info
575 : : !!
576 : : !! OUTPUT
577 : : !! ftarr(2,nd1,nd2,nd3*ndat)=working space for transform and contains output
578 : : !!
579 : : !! SIDE EFFECTS
580 : : !! arr(2,nd1,nd2,nd3*ndat)=input complex array with alternating real and imaginary
581 : : !! elements; data resides in 2*n1*n2*n3 of this array, spread out.
582 : : !! arr(2,nd1,nd2,nd3*ndat) is modified by sg_fftpx,sg_ffty,sg_fftz.
583 : : !!
584 : : !! NOTES
585 : : !! mfac sets maximum number of factors (5, 4, 3, or 2) which may be
586 : : !! contained within any n1, n2, or n3
587 : : !! mg sets the maximum 1 dimensional fft length (any one of n1, n2, or n3)
588 : : !! XG: the signification of mg is changed with respect to fft3dp !!!
589 : : !!
590 : : !! SOURCE
591 : :
592 : 669 : subroutine sg_fftpad(fftcache,mgfft,n1,n2,n3,nd1,nd2,nd3,ndat,gbound,isign,arr,ftarr)
593 : :
594 : : !Arguments ------------------------------------
595 : : !scalars
596 : : integer,intent(in) :: fftcache,mgfft,n1,n2,n3,nd1,nd2,nd3,ndat,isign
597 : : !arrays
598 : : integer,intent(in) :: gbound(2*mgfft+8,2)
599 : : real(dp),intent(inout) :: arr(2,nd1,nd2,nd3*ndat)
600 : : real(dp),intent(out) :: ftarr(2,nd1,nd2,nd3*ndat)
601 : :
602 : : !Local variables-------------------------------
603 : : !scalars
604 : : integer :: idat,start
605 : :
606 : : ! *************************************************************************
607 : :
608 [ + + ]: 1386 : do idat=1,ndat
609 : 717 : start = 1 + (idat-1)*nd3
610 : : call fftpad_one_nothreadsafe(fftcache,mgfft,nd1,nd2,nd3,n1,n2,n3,&
611 : 1386 : & arr(1,1,1,start),ftarr(1,1,1,start),real(isign, kind=dp),gbound)
612 : : end do
613 : :
614 : 669 : end subroutine sg_fftpad
615 : : !!***
616 : :
617 : : !----------------------------------------------------------------------
618 : :
619 : : !!****f* m_sgfft/fftpad_one_nothreadsafe
620 : : !! NAME
621 : : !! fftpad_one_nothreadsafe
622 : : !!
623 : : !! FUNCTION
624 : : !! Fast Fourier transform. This is the zero-padding version of "fft" for a single array.
625 : : !! This version is not thread-safe.
626 : : !!
627 : : !! INPUTS
628 : : !! fftcache=size of the cache (kB)
629 : : !! mgfft=maximum size of 1D FFTs
630 : : !! nd1,nd2,nd3=memory dimension of arr and ftarr
631 : : !! n1,n2,n3=physical dimension of the transform
632 : : !! arr(2,nd1,nd2,nd3)=input complex array with alternating real and imaginary
633 : : !! elements; data resides in 2*n1*n2*n3 of this array, spread out.
634 : : !! ris=(real(dp)) sign of exponential in transform
635 : : !! gbound(2*mgfft+8,2)=sphere boundary info
636 : : !!
637 : : !! OUTPUT
638 : : !! ftarr(2,nd1,nd2,nd3)=working space for transform and contains output
639 : : !!
640 : : !! SIDE EFFECTS
641 : : !! arr(2,nd1,nd2,nd3) is modified by sg_fftpx,sg_ffty,sg_fftz.
642 : : !!
643 : : !! NOTES
644 : : !! mfac sets maximum number of factors (5, 4, 3, or 2) which may be
645 : : !! contained within any n1, n2, or n3
646 : : !! mg sets the maximum 1 dimensional fft length (any one of n1, n2, or n3)
647 : : !! XG: the signification of mg is changed with respect to fft3dp !!!
648 : : !!
649 : : !! SOURCE
650 : :
651 : 717 : subroutine fftpad_one_nothreadsafe(fftcache,mgfft,nd1,nd2,nd3,n1,n2,n3,arr,ftarr,ris,gbound)
652 : :
653 : : !Arguments ------------------------------------
654 : : !scalars
655 : : integer,intent(in) :: fftcache,mgfft,n1,n2,n3,nd1,nd2,nd3
656 : : real(dp),intent(in) :: ris
657 : : !arrays
658 : : integer,intent(in) :: gbound(2*mgfft+8,2)
659 : : real(dp),intent(inout) :: arr(2,nd1,nd2,nd3)
660 : : real(dp),intent(out) :: ftarr(2,nd1,nd2,nd3)
661 : :
662 : : !Local variables-------------------------------
663 : : !scalars
664 : : integer,parameter :: mfac=11
665 : : integer :: g3max,g3min,i2,ic,n1i,n3i,n3p
666 : : #ifdef DEBUG_MODE
667 : : character(len=500) :: message
668 : : #endif
669 : : !arrays
670 : : integer :: aft(mfac),bef(mfac),ind(mg),now(mfac)
671 : : real(dp) :: trig(2,mg)
672 : :
673 : : ! *************************************************************************
674 : :
675 : : #ifdef DEBUG_MODE
676 : : !Check that dimension is not exceeded
677 : : if (n1>mg.or.n2>mg.or.n3>mg) then
678 : : write(message, '(a,3i10,a,i10)')&
679 : : & 'one of the dimensions n1,n2,n3=',n1,n2,n3,' exceeds the allowed dimension mg=',mg
680 : : ABI_BUG(message)
681 : : end if
682 : : #endif
683 : :
684 : 717 : g3min=gbound(3,2)
685 : 717 : g3max=gbound(4,2)
686 : :
687 : : !--------------------------------------------------------------------------
688 : :
689 [ + + ]: 717 : if (abs(ris-one)<tol12) then
690 : :
691 : : ! Handle G -> r transform (G sphere to fft box)
692 : :
693 : : ! Transform along x direction
694 : 409 : call sg_ctrig(n1,trig,aft,bef,now,ris,ic,ind,mfac,mg)
695 : :
696 : : ! Zero out the untransformed (0) data part of the work array
697 : : ! -- at every (y,z) there are 0 s to be added to the ends of
698 : : ! the x data so have to zero whole thing.
699 [ + + + + : 583355323 : ftarr(:,:,:,:)=0.0d0
+ + + + ]
700 : :
701 : : ! Note the passing of the relevant part of gbound
702 : : call sg_fftpx(fftcache,mfac,mg,mgfft,nd1,nd2,nd3,n2,n3,&
703 : 409 : & arr,ftarr,trig,aft,now,bef,ris,ind,ic,gbound(3,2))
704 : :
705 : : ! Transform along y direction in two regions of z
706 [ + + ]: 409 : if (n2/=n1)then
707 : 128 : call sg_ctrig(n2,trig,aft,bef,now,ris,ic,ind,mfac,mg)
708 : : end if
709 : :
710 : : ! First y transform: z=1..g3max+1
711 : 409 : n3p=g3max+1
712 : 409 : n1i=1 ; n3i=1
713 : : call sg_ffty(fftcache,mfac,mg,nd1,nd2,nd3,n1i,n1,n3i,n3p,ftarr,arr,&
714 : 409 : & trig,aft,now,bef,ris,ind,ic)
715 : :
716 : : ! Zero out the untransformed (0) data part of the work array
717 : : ! -- only need to zero specified ranges of z
718 [ + + + + : 295831474 : arr(:,:,:,n3p+1:g3min+n3)=0.0d0
+ + + + ]
719 : :
720 : : ! Second y transform: z=g3min+1..0 (wrapped around)
721 : 409 : n3p=-g3min
722 [ + - ]: 409 : if (n3p>0) then
723 : 409 : n3i=1+g3min+n3 ; n1i=1
724 : : call sg_ffty(fftcache,mfac,mg,nd1,nd2,nd3,n1i,n1,n3i,n3,ftarr,arr,&
725 : 409 : & trig,aft,now,bef,ris,ind,ic)
726 : : end if
727 : :
728 : : ! Transform along z direction
729 [ + + ]: 409 : if (n3/=n2) then
730 : 128 : call sg_ctrig(n3,trig,aft,bef,now,ris,ic,ind,mfac,mg)
731 : : end if
732 : :
733 : : !$OMP PARALLEL DO
734 [ + + ]: 25699 : do i2=1,n2
735 : : call sg_fftz(mfac,mg,nd1,nd2,nd3,n1,i2,i2,arr,ftarr,&
736 : 25699 : & trig,aft,now,bef,ris,ind,ic)
737 : : end do
738 : :
739 : : else
740 : :
741 : : ! *************************************************
742 : : ! Handle r -> G transform (from fft box to G sphere)
743 : :
744 : : ! Transform along z direction
745 : 308 : call sg_ctrig(n3,trig,aft,bef,now,ris,ic,ind,mfac,mg)
746 : :
747 : : !$OMP PARALLEL DO
748 [ + + ]: 24692 : do i2=1,n2
749 : : call sg_fftz(mfac,mg,nd1,nd2,nd3,n1,i2,i2,arr,ftarr,&
750 : 24692 : & trig,aft,now,bef,ris,ind,ic)
751 : : end do
752 : :
753 : : ! Transform along y direction in two regions of z
754 [ + + ]: 308 : if (n2/=n3) then
755 : 122 : call sg_ctrig(n2,trig,aft,bef,now,ris,ic,ind,mfac,mg)
756 : : end if
757 : :
758 : : ! First y transform: z=1..g3max+1
759 : 308 : n3p=g3max+1
760 : 308 : n1i=1 ; n3i=1
761 : : call sg_ffty(fftcache,mfac,mg,nd1,nd2,nd3,n1i,n1,n3i,n3p,ftarr,arr,&
762 : 308 : & trig,aft,now,bef,ris,ind,ic)
763 : :
764 : : ! Second y transform: z=g3min+1..0 (wrapped around)
765 : 308 : n3p=-g3min
766 [ + - ]: 308 : if (n3p>0) then
767 : 308 : n1i=1 ; n3i=1+g3min+n3
768 : : call sg_ffty(fftcache,mfac,mg,nd1,nd2,nd3,n1i,n1,n3i,n3,ftarr,arr,&
769 : 308 : & trig,aft,now,bef,ris,ind,ic)
770 : : end if
771 : :
772 : : ! Transform along x direction
773 [ + + ]: 308 : if (n1/=n2) then
774 : 122 : call sg_ctrig(n1,trig,aft,bef,now,ris,ic,ind,mfac,mg)
775 : : end if
776 : :
777 : : ! Zero out the untransformed (0) data part of the work array
778 : : ! -- at every (y,z) there are 0 s to be added to the ends of
779 : : ! the x data so have to zero whole thing.
780 [ + + + + : 621364664 : ftarr(:,:,:,:)=0.0d0
+ + + + ]
781 : :
782 : : ! Note the passing of the relevant part of gbound
783 : : call sg_fftpx(fftcache,mfac,mg,mgfft,nd1,nd2,nd3,n2,n3,&
784 : 308 : & arr,ftarr,trig,aft,now,bef,ris,ind,ic,gbound(3,2))
785 : :
786 : : ! Data is now ready to be extracted from fft box to sphere
787 : : end if
788 : :
789 : 717 : end subroutine fftpad_one_nothreadsafe
790 : : !!***
791 : :
792 : : !----------------------------------------------------------------------
793 : :
794 : : !!****f* m_sgfft/sg_fftpx
795 : : !! NAME
796 : : !! sg_fftpx
797 : : !!
798 : : !! FUNCTION
799 : : !! This subroutine is called by the 3-dimensional fft to conduct the
800 : : !! "x" transforms for all y and z.
801 : : !! Accomodate more optimal treatment of
802 : : !! zero padding following the method of fft3dp.
803 : : !!
804 : : !! INPUTS
805 : : !! fftcache=size of the cache (kB)
806 : : !! mfac = maximum number of factors in 1D FFTs
807 : : !! mg = maximum length of 1D FFTs
808 : : !! mgfft = effective maximum length of 1D FFTs, for dimensioning gbound
809 : : !! nd1=first dimension of (complex) arrays z and zbr (treated as real within
810 : : !! this subroutine)
811 : : !! nd2=second dimension of (complex) arrays z and zbr (treated as real within
812 : : !! this subroutine)
813 : : !! nd3=third dimension of (complex) arrays z and zbr (treated as real within
814 : : !! this subroutine)
815 : : !! n2,n3=actual length of y and z transforms
816 : : !! z(2,nd1,nd2,nd3)=INPUT array; destroyed by transformation
817 : : !! trig, aft, now, bef, ind=provided by previous call to ctrig
818 : : !! Note that in this routine (and in ctrig) the values in array trig are
819 : : !! actually cos and tan, not cos and sin. Use of tan allows advantageous
820 : : !! use of FMA on the ibm rs6000.
821 : : !! ris=sign of exponential in transform (should be 1 or -1; real)
822 : : !! ic=number of (radix) factors of x transform length (from ctrig)
823 : : !! gbound(2*mgfft+4)=sphere boundary info
824 : : !!
825 : : !! OUTPUT
826 : : !! zbr(2,nd1,nd2,nd3)=OUTPUT transformed array; no scaling applied
827 : : !!
828 : : !! SIDE EFFECTS
829 : : !!
830 : : !! NOTES
831 : : !! This routine blocks the x transforms
832 : : !! so that all transforms under consideration at one step fit within
833 : : !! the cache memory, which is crucial for optimal performance.
834 : : !! The blocking factor is set by parameter "fftcache" below, which should
835 : : !! be adjusted to be somewhat smaller (say 3/4) than the actual cache size
836 : : !! of the machine.
837 : : !!
838 : : !! TODO
839 : : !! Use latex for the equation above
840 : : !!
841 : : !! SOURCE
842 : :
843 : 32997005 : subroutine sg_fftpx(fftcache,mfac,mg,mgfft,nd1,nd2,nd3,n2,n3,&
844 : 32997005 : & z,zbr,trig,aft,now,bef,ris,ind,ic,gbound)
845 : :
846 : : !Arguments ------------------------------------
847 : : !Dimensions of aft, now, bef, ind, and trig should agree with
848 : : !those in subroutine ctrig.
849 : : !scalars
850 : : integer,intent(in) :: fftcache,ic,mfac,mg,mgfft,n2,n3,nd1,nd2,nd3
851 : : real(dp),intent(in) :: ris
852 : : !arrays
853 : : integer,intent(in) :: aft(mfac),bef(mfac),gbound(2*mgfft+4),ind(mg),now(mfac)
854 : : real(dp),intent(in) :: trig(2,mg)
855 : : real(dp),intent(inout) :: z(2,nd1,nd2,nd3)
856 : : real(dp),intent(inout) :: zbr(2,nd1,nd2,nd3) !vz_i
857 : :
858 : : !Local variables-------------------------------
859 : : !scalars
860 : : integer :: g2,g2max,g2min,g3,g3max,g3min,gg3,i,ia,ib,igb,ihalfy,indx,j
861 : : integer :: len3,lot,lowlim,ma,mb,ntb,upplim
862 : : !no_abirules
863 : : real(dp),parameter :: &
864 : : & cos2=0.3090169943749474d0,& !cos(2.d0*pi/5.d0)
865 : : & cos4=-0.8090169943749474d0,& !cos(4.d0*pi/5.d0)
866 : : & sin42=0.6180339887498948d0 !sin(4.d0*pi/5.d0)/sin(2.d0*pi/5.d0)
867 : : real(dp) :: bb,cr2,cr2s,cr3,cr3p,cr4,cr5,ct2,ct3,ct4,ct5,&
868 : : & factor,r,r1,r2,r25,r3,r34,r4,r5,s,sin2,s1,s2,s25,s3,s34,s4,s5
869 : :
870 : : ! *************************************************************************
871 : :
872 : 32997005 : g3min=gbound(1)
873 : 32997005 : g3max=gbound(2)
874 : 32997005 : igb=3
875 : 32997005 : len3=g3max-g3min+1
876 : :
877 : :
878 : : !Do x transforms in blocks of size "lot" which is set by how
879 : : !many x transform arrays (of size nd1 each) fit into the nominal
880 : : !cache size "fftcache".
881 : : !Loop over blocks in the loop below.
882 : :
883 : 32997005 : factor=0.75d0
884 : 32997005 : lot=(fftcache*factor*1000d0)/(nd1*8*2)
885 : 32997005 : if(lot.lt.1) lot=1
886 : : !Express loop over y, z in terms of separate z and y loops
887 : :
888 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
889 : : !$OMP SHARED(aft,bef,gbound,g3max,ic,ind,len3,lot)&
890 : : !$OMP SHARED(n2,n3,nd2,now,ris,trig,z,zbr)
891 [ + + ]: 66018532 : do gg3=1,len3
892 : :
893 [ + + ]: 33021527 : if (gg3<=g3max+1) then
894 : : g3=gg3
895 : : else
896 : : ! wrap around for negative gg3
897 : 12394 : g3=gg3-len3+n3
898 : : end if
899 : :
900 : 33021527 : igb=gg3*2+1
901 : 33021527 : g2min=gbound(igb)
902 : 33021527 : g2max=gbound(igb+1)
903 : :
904 : : ! Split the y loop into positive and wrapped-around negative parts
905 : :
906 [ + + ]: 132061586 : do ihalfy=1,2
907 : :
908 : : ! Start at 1 for ihalfy=1; g2min+1+n2 for ihalfy=2
909 : 66043054 : lowlim=1+(ihalfy-1)*(g2min+n2)
910 : : ! End at g2max+1 for ihalfy=1; n2 for ihalfy=2
911 : 66043054 : upplim=g2max+1+(ihalfy-1)*(n2-g2max-1)
912 : :
913 [ + + + + ]: 165247709 : do g2=lowlim,upplim,lot
914 : :
915 : : ! Find array starting address ma and ending address mb
916 : : ! modified xg 980107
917 : : ! ma=g2+(g3-1)*nd2
918 : 66183128 : ma=g2
919 : : ! Perform "lot" transforms at a time (until out of data)
920 : : ! mb=min(g2+(lot-1),upplim)+(g3-1)*nd2
921 : 66183128 : mb=min(g2+(lot-1),upplim)
922 : :
923 : : ! -------------------------------------------------------------------------
924 : : !
925 : : ! Direct transformation
926 : :
927 : : ! Run over all factors except the last (to ic-1), performing
928 : : ! x transform
929 : :
930 : : ! Note: fortran should skip this loop if ic=1; beware "onetrip"
931 : : ! compiler option which forces each loop at least once
932 : :
933 [ + + ]: 154027544 : do i=1,ic-1
934 : 87844416 : ntb=now(i)*bef(i)
935 : :
936 : : ! Treat radix 4
937 [ + + ]: 154027544 : if (now(i)==4) then
938 : 84693424 : ia=0
939 : :
940 : : ! First step of factor 4
941 [ + + ]: 84693424 : do ib=1,bef(i)
942 [ + + ]: 371005788 : do j=ma,mb
943 : 286312364 : r4=z(1,ia*ntb+3*bef(i)+ib,j,g3)
944 : 286312364 : s4=z(2,ia*ntb+3*bef(i)+ib,j,g3)
945 : 286312364 : r3=z(1,ia*ntb+2*bef(i)+ib,j,g3)
946 : 286312364 : s3=z(2,ia*ntb+2*bef(i)+ib,j,g3)
947 : 286312364 : r2=z(1,ia*ntb+bef(i)+ib,j,g3)
948 : 286312364 : s2=z(2,ia*ntb+bef(i)+ib,j,g3)
949 : 286312364 : r1=z(1,ia*ntb+ib,j,g3)
950 : 286312364 : s1=z(2,ia*ntb+ib,j,g3)
951 : :
952 : 286312364 : r=r1 + r3
953 : 286312364 : s=r2 + r4
954 : 286312364 : z(1,ia*ntb+ib,j,g3) = r + s
955 : 286312364 : z(1,ia*ntb+2*bef(i)+ib,j,g3) = r - s
956 : 286312364 : r=r1 - r3
957 : 286312364 : s=s2 - s4
958 : 286312364 : z(1,ia*ntb+bef(i)+ib,j,g3) = r - s*ris
959 : 286312364 : z(1,ia*ntb+3*bef(i)+ib,j,g3) = r + s*ris
960 : 286312364 : r=s1 + s3
961 : 286312364 : s=s2 + s4
962 : 286312364 : z(2,ia*ntb+ib,j,g3) = r + s
963 : 286312364 : z(2,ia*ntb+2*bef(i)+ib,j,g3) = r - s
964 : 286312364 : r=s1 - s3
965 : 286312364 : s=r2 - r4
966 : 286312364 : z(2,ia*ntb+bef(i)+ib,j,g3) = r + s*ris
967 : 355200440 : z(2,ia*ntb+3*bef(i)+ib,j,g3) = r - s*ris
968 : : end do
969 : : end do
970 : :
971 : : ! Second step of factor 4
972 [ + - ]: 15805348 : do ia=1,aft(i)-1
973 : 0 : indx=ind(ia*4*bef(i)+1)-1
974 : 0 : indx=indx*bef(i)
975 : 0 : cr2=trig(1,indx)
976 : 0 : ct2=trig(2,indx)
977 : 0 : cr3=trig(1,2*indx)
978 : 0 : ct3=trig(2,2*indx)
979 : 0 : cr4=trig(1,3*indx)
980 : 0 : ct4=trig(2,3*indx)
981 : 0 : cr4=cr4/cr2
982 : 0 : cr2s=cr2*ris
983 [ - - ]: 15805348 : do ib=1,bef(i)
984 [ # # ]: 0 : do j=ma,mb
985 : : r4=z(1,ia*ntb+3*bef(i)+ib,j,g3) - &
986 : 0 : & z(2,ia*ntb+3*bef(i)+ib,j,g3)*ct4
987 : : s4=z(1,ia*ntb+3*bef(i)+ib,j,g3)*ct4 + &
988 : 0 : & z(2,ia*ntb+3*bef(i)+ib,j,g3)
989 : : r3=z(1,ia*ntb+2*bef(i)+ib,j,g3) - &
990 : 0 : & z(2,ia*ntb+2*bef(i)+ib,j,g3)*ct3
991 : : s3=z(1,ia*ntb+2*bef(i)+ib,j,g3)*ct3 + &
992 : 0 : & z(2,ia*ntb+2*bef(i)+ib,j,g3)
993 : : r2=z(1,ia*ntb+bef(i)+ib,j,g3) - &
994 : 0 : & z(2,ia*ntb+bef(i)+ib,j,g3)*ct2
995 : : s2=z(1,ia*ntb+bef(i)+ib,j,g3)*ct2 + &
996 : 0 : & z(2,ia*ntb+bef(i)+ib,j,g3)
997 : 0 : r1=z(1,ia*ntb+ib,j,g3)
998 : 0 : s1=z(2,ia*ntb+ib,j,g3)
999 : :
1000 : 0 : r=r1 + r3*cr3
1001 : 0 : s=r2 + r4*cr4
1002 : 0 : z(1,ia*ntb+ib,j,g3) = r + s*cr2
1003 : 0 : z(1,ia*ntb+2*bef(i)+ib,j,g3) = r - s*cr2
1004 : 0 : r=r1 - r3*cr3
1005 : 0 : s=s2 - s4*cr4
1006 : 0 : z(1,ia*ntb+bef(i)+ib,j,g3) = r - s*cr2s
1007 : 0 : z(1,ia*ntb+3*bef(i)+ib,j,g3) = r + s*cr2s
1008 : 0 : r=s1 + s3*cr3
1009 : 0 : s=s2 + s4*cr4
1010 : 0 : z(2,ia*ntb+ib,j,g3) = r + s*cr2
1011 : 0 : z(2,ia*ntb+2*bef(i)+ib,j,g3) = r - s*cr2
1012 : 0 : r=s1 - s3*cr3
1013 : 0 : s=r2 - r4*cr4
1014 : 0 : z(2,ia*ntb+bef(i)+ib,j,g3) = r + s*cr2s
1015 : 0 : z(2,ia*ntb+3*bef(i)+ib,j,g3) = r - s*cr2s
1016 : : end do
1017 : : end do
1018 : : end do
1019 : :
1020 : : ! Treat radix 2
1021 [ - + ]: 72039068 : else if (now(i)==2) then
1022 : 0 : ia=0
1023 : :
1024 : : ! First step of factor 2
1025 [ # # ]: 0 : do ib=1,bef(i)
1026 [ # # ]: 0 : do j=ma,mb
1027 : 0 : r1=z(1,ia*ntb+ib,j,g3)
1028 : 0 : s1=z(2,ia*ntb+ib,j,g3)
1029 : 0 : r2=z(1,ia*ntb+bef(i)+ib,j,g3)
1030 : 0 : s2=z(2,ia*ntb+bef(i)+ib,j,g3)
1031 : 0 : z(1,ia*ntb+ib,j,g3) = r2 + r1
1032 : 0 : z(2,ia*ntb+ib,j,g3) = s2 + s1
1033 : 0 : z(1,ia*ntb+bef(i)+ib,j,g3) = -r2 + r1
1034 : 0 : z(2,ia*ntb+bef(i)+ib,j,g3) = -s2 + s1
1035 : : end do
1036 : : end do
1037 : :
1038 : : ! Second step of radix 2
1039 [ # # ]: 0 : do ia=1,aft(i)-1
1040 : 0 : indx=ind(ia*2*bef(i)+1)-1
1041 : 0 : indx=indx*bef(i)
1042 : 0 : cr2=trig(1,indx)
1043 : 0 : ct2=trig(2,indx)
1044 [ # # ]: 0 : do ib=1,bef(i)
1045 [ # # ]: 0 : do j=ma,mb
1046 : 0 : r1=z(1,ia*ntb+ib,j,g3)
1047 : 0 : s1=z(2,ia*ntb+ib,j,g3)
1048 : : r2=z(1,ia*ntb+bef(i)+ib,j,g3) - &
1049 : 0 : & z(2,ia*ntb+bef(i)+ib,j,g3)*ct2
1050 : : s2=z(1,ia*ntb+bef(i)+ib,j,g3)*ct2 + &
1051 : 0 : & z(2,ia*ntb+bef(i)+ib,j,g3)
1052 : 0 : z(1,ia*ntb+ib,j,g3) = r2*cr2 + r1
1053 : 0 : z(2,ia*ntb+ib,j,g3) = s2*cr2 + s1
1054 : 0 : z(1,ia*ntb+bef(i)+ib,j,g3) = -r2*cr2 + r1
1055 : 0 : z(2,ia*ntb+bef(i)+ib,j,g3) = -s2*cr2 + s1
1056 : : end do
1057 : : end do
1058 : : end do
1059 : :
1060 : : ! Treat radix 3
1061 [ + + ]: 72039068 : else if (now(i)==3) then
1062 : : ! .5d0*sqrt(3.d0)=0.8660254037844387d0
1063 : 37964184 : ia=0
1064 : 37964184 : bb=ris*0.8660254037844387d0
1065 : :
1066 : : ! First step of radix 3
1067 [ + + ]: 179939656 : do ib=1,bef(i)
1068 [ + + ]: 771422960 : do j=ma,mb
1069 : 591483304 : r1=z(1,ia*ntb+ib,j,g3)
1070 : 591483304 : s1=z(2,ia*ntb+ib,j,g3)
1071 : 591483304 : r2=z(1,ia*ntb+bef(i)+ib,j,g3)
1072 : 591483304 : s2=z(2,ia*ntb+bef(i)+ib,j,g3)
1073 : 591483304 : r3=z(1,ia*ntb+2*bef(i)+ib,j,g3)
1074 : 591483304 : s3=z(2,ia*ntb+2*bef(i)+ib,j,g3)
1075 : 591483304 : r=r2 + r3
1076 : 591483304 : s=s2 + s3
1077 : 591483304 : z(1,ia*ntb+ib,j,g3) = r + r1
1078 : 591483304 : z(2,ia*ntb+ib,j,g3) = s + s1
1079 : 591483304 : r1=r1 - r*.5d0
1080 : 591483304 : s1=s1 - s*.5d0
1081 : 591483304 : r2=r2-r3
1082 : 591483304 : s2=s2-s3
1083 : 591483304 : z(1,ia*ntb+bef(i)+ib,j,g3) = r1 - s2*bb
1084 : 591483304 : z(2,ia*ntb+bef(i)+ib,j,g3) = s1 + r2*bb
1085 : 591483304 : z(1,ia*ntb+2*bef(i)+ib,j,g3) = r1 + s2*bb
1086 : 733458776 : z(2,ia*ntb+2*bef(i)+ib,j,g3) = s1 - r2*bb
1087 : : end do
1088 : : end do
1089 : :
1090 : : ! Second step of radix 3
1091 [ + + ]: 85993824 : do ia=1,aft(i)-1
1092 : 48029640 : indx=ind(ia*3*bef(i)+1)-1
1093 : 48029640 : indx=indx*bef(i)
1094 : 48029640 : cr2=trig(1,indx)
1095 : 48029640 : ct2=trig(2,indx)
1096 : 48029640 : cr3=trig(1,2*indx)
1097 : 48029640 : ct3=trig(2,2*indx)
1098 : 48029640 : cr2=cr2/cr3
1099 : 48029640 : cr3p=.5d0*cr3
1100 : 48029640 : bb=ris*cr3*0.8660254037844387d0
1101 [ + + ]: 182147824 : do ib=1,bef(i)
1102 [ + + ]: 572011156 : do j=ma,mb
1103 : 427827516 : r1=z(1,ia*ntb+ib,j,g3)
1104 : 427827516 : s1=z(2,ia*ntb+ib,j,g3)
1105 : : r2=z(1,ia*ntb+bef(i)+ib,j,g3) - &
1106 : 427827516 : & z(2,ia*ntb+bef(i)+ib,j,g3)*ct2
1107 : : s2=z(1,ia*ntb+bef(i)+ib,j,g3)*ct2 + &
1108 : 427827516 : & z(2,ia*ntb+bef(i)+ib,j,g3)
1109 : : r3=z(1,ia*ntb+2*bef(i)+ib,j,g3) - &
1110 : 427827516 : & z(2,ia*ntb+2*bef(i)+ib,j,g3)*ct3
1111 : : s3=z(1,ia*ntb+2*bef(i)+ib,j,g3)*ct3 + &
1112 : 427827516 : & z(2,ia*ntb+2*bef(i)+ib,j,g3)
1113 : 427827516 : r=cr2*r2 + r3
1114 : 427827516 : s=cr2*s2 + s3
1115 : 427827516 : z(1,ia*ntb+ib,j,g3) = r*cr3 + r1
1116 : 427827516 : z(2,ia*ntb+ib,j,g3) = s*cr3 + s1
1117 : 427827516 : r1=r1 - r*cr3p
1118 : 427827516 : s1=s1 - s*cr3p
1119 : 427827516 : r2=cr2*r2-r3
1120 : 427827516 : s2=cr2*s2-s3
1121 : 427827516 : z(1,ia*ntb+bef(i)+ib,j,g3) = r1 - s2*bb
1122 : 427827516 : z(2,ia*ntb+bef(i)+ib,j,g3) = s1 + r2*bb
1123 : 427827516 : z(1,ia*ntb+2*bef(i)+ib,j,g3) = r1 + s2*bb
1124 : 523981516 : z(2,ia*ntb+2*bef(i)+ib,j,g3) = s1 - r2*bb
1125 : : end do
1126 : : end do
1127 : : end do
1128 : :
1129 : : ! Treat radix 5
1130 [ + - ]: 34074884 : else if (now(i)==5) then
1131 : : ! sin(2.d0*pi/5.d0)
1132 : 34074884 : sin2=ris*0.9510565162951536d0
1133 : 34074884 : ia=0
1134 : :
1135 : : ! First step of radix 5
1136 [ + + ]: 142541916 : do ib=1,bef(i)
1137 [ + + ]: 492315228 : do j=ma,mb
1138 : 349773312 : r1=z(1,ia*ntb+ib,j,g3)
1139 : 349773312 : s1=z(2,ia*ntb+ib,j,g3)
1140 : 349773312 : r2=z(1,ia*ntb+bef(i)+ib,j,g3)
1141 : 349773312 : s2=z(2,ia*ntb+bef(i)+ib,j,g3)
1142 : 349773312 : r3=z(1,ia*ntb+2*bef(i)+ib,j,g3)
1143 : 349773312 : s3=z(2,ia*ntb+2*bef(i)+ib,j,g3)
1144 : 349773312 : r4=z(1,ia*ntb+3*bef(i)+ib,j,g3)
1145 : 349773312 : s4=z(2,ia*ntb+3*bef(i)+ib,j,g3)
1146 : 349773312 : r5=z(1,ia*ntb+4*bef(i)+ib,j,g3)
1147 : 349773312 : s5=z(2,ia*ntb+4*bef(i)+ib,j,g3)
1148 : 349773312 : r25 = r2 + r5
1149 : 349773312 : r34 = r3 + r4
1150 : 349773312 : s25 = s2 - s5
1151 : 349773312 : s34 = s3 - s4
1152 : 349773312 : z(1,ia*ntb+ib,j,g3) = r1 + r25 + r34
1153 : 349773312 : r = r1 + cos2*r25 + cos4*r34
1154 : 349773312 : s = s25 + sin42*s34
1155 : 349773312 : z(1,ia*ntb+bef(i)+ib,j,g3) = r - sin2*s
1156 : 349773312 : z(1,ia*ntb+4*bef(i)+ib,j,g3) = r + sin2*s
1157 : 349773312 : r = r1 + cos4*r25 + cos2*r34
1158 : 349773312 : s = sin42*s25 - s34
1159 : 349773312 : z(1,ia*ntb+2*bef(i)+ib,j,g3) = r - sin2*s
1160 : 349773312 : z(1,ia*ntb+3*bef(i)+ib,j,g3) = r + sin2*s
1161 : 349773312 : r25 = r2 - r5
1162 : 349773312 : r34 = r3 - r4
1163 : 349773312 : s25 = s2 + s5
1164 : 349773312 : s34 = s3 + s4
1165 : 349773312 : z(2,ia*ntb+ib,j,g3) = s1 + s25 + s34
1166 : 349773312 : r = s1 + cos2*s25 + cos4*s34
1167 : 349773312 : s = r25 + sin42*r34
1168 : 349773312 : z(2,ia*ntb+bef(i)+ib,j,g3) = r + sin2*s
1169 : 349773312 : z(2,ia*ntb+4*bef(i)+ib,j,g3) = r - sin2*s
1170 : 349773312 : r = s1 + cos4*s25 + cos2*s34
1171 : 349773312 : s = sin42*r25 - r34
1172 : 349773312 : z(2,ia*ntb+2*bef(i)+ib,j,g3) = r + sin2*s
1173 : 458240344 : z(2,ia*ntb+3*bef(i)+ib,j,g3) = r - sin2*s
1174 : : end do
1175 : : end do
1176 : :
1177 : : ! Second step of radix 5
1178 [ + + ]: 34886724 : do ia=1,aft(i)-1
1179 : 811840 : indx=ind(ia*5*bef(i)+1)-1
1180 : 811840 : indx=indx*bef(i)
1181 : 811840 : cr2=trig(1,indx)
1182 : 811840 : ct2=trig(2,indx)
1183 : 811840 : cr3=trig(1,2*indx)
1184 : 811840 : ct3=trig(2,2*indx)
1185 : 811840 : cr4=trig(1,3*indx)
1186 : 811840 : ct4=trig(2,3*indx)
1187 : 811840 : cr5=trig(1,4*indx)
1188 : 811840 : ct5=trig(2,4*indx)
1189 [ + + ]: 37999684 : do ib=1,bef(i)
1190 [ + + ]: 23240848 : do j=ma,mb
1191 : 19316048 : r1=z(1,ia*ntb+ib,j,g3)
1192 : 19316048 : s1=z(2,ia*ntb+ib,j,g3)
1193 : : r2=cr2*(z(1,ia*ntb+bef(i)+ib,j,g3) - &
1194 : 19316048 : & z(2,ia*ntb+bef(i)+ib,j,g3)*ct2)
1195 : : s2=cr2*(z(1,ia*ntb+bef(i)+ib,j,g3)*ct2 + &
1196 : 19316048 : & z(2,ia*ntb+bef(i)+ib,j,g3))
1197 : : r3=cr3*(z(1,ia*ntb+2*bef(i)+ib,j,g3) - &
1198 : 19316048 : & z(2,ia*ntb+2*bef(i)+ib,j,g3)*ct3)
1199 : : s3=cr3*(z(1,ia*ntb+2*bef(i)+ib,j,g3)*ct3 + &
1200 : 19316048 : & z(2,ia*ntb+2*bef(i)+ib,j,g3))
1201 : : r4=z(1,ia*ntb+3*bef(i)+ib,j,g3) - &
1202 : 19316048 : & z(2,ia*ntb+3*bef(i)+ib,j,g3)*ct4
1203 : : s4=z(1,ia*ntb+3*bef(i)+ib,j,g3)*ct4 + &
1204 : 19316048 : & z(2,ia*ntb+3*bef(i)+ib,j,g3)
1205 : : r5=z(1,ia*ntb+4*bef(i)+ib,j,g3) - &
1206 : 19316048 : & z(2,ia*ntb+4*bef(i)+ib,j,g3)*ct5
1207 : : s5=z(1,ia*ntb+4*bef(i)+ib,j,g3)*ct5 + &
1208 : 19316048 : & z(2,ia*ntb+4*bef(i)+ib,j,g3)
1209 : 19316048 : r25 = r2 + r5*cr5
1210 : 19316048 : r34 = r3 + r4*cr4
1211 : 19316048 : s25 = s2 - s5*cr5
1212 : 19316048 : s34 = s3 - s4*cr4
1213 : 19316048 : z(1,ia*ntb+ib,j,g3) = r1 + r25 + r34
1214 : 19316048 : r = r1 + cos2*r25 + cos4*r34
1215 : 19316048 : s = s25 + sin42*s34
1216 : 19316048 : z(1,ia*ntb+bef(i)+ib,j,g3) = r - sin2*s
1217 : 19316048 : z(1,ia*ntb+4*bef(i)+ib,j,g3) = r + sin2*s
1218 : 19316048 : r = r1 + cos4*r25 + cos2*r34
1219 : 19316048 : s = sin42*s25 - s34
1220 : 19316048 : z(1,ia*ntb+2*bef(i)+ib,j,g3) = r - sin2*s
1221 : 19316048 : z(1,ia*ntb+3*bef(i)+ib,j,g3) = r + sin2*s
1222 : 19316048 : r25 = r2 - r5*cr5
1223 : 19316048 : r34 = r3 - r4*cr4
1224 : 19316048 : s25 = s2 + s5*cr5
1225 : 19316048 : s34 = s3 + s4*cr4
1226 : 19316048 : z(2,ia*ntb+ib,j,g3) = s1 + s25 + s34
1227 : 19316048 : r = s1 + cos2*s25 + cos4*s34
1228 : 19316048 : s = r25 + sin42*r34
1229 : 19316048 : z(2,ia*ntb+bef(i)+ib,j,g3) = r + sin2*s
1230 : 19316048 : z(2,ia*ntb+4*bef(i)+ib,j,g3) = r - sin2*s
1231 : 19316048 : r = s1 + cos4*s25 + cos2*s34
1232 : 19316048 : s = sin42*r25 - r34
1233 : 19316048 : z(2,ia*ntb+2*bef(i)+ib,j,g3) = r + sin2*s
1234 : 22429008 : z(2,ia*ntb+3*bef(i)+ib,j,g3) = r - sin2*s
1235 : : end do
1236 : : end do
1237 : : end do
1238 : :
1239 : : else
1240 : : ! All radices treated
1241 : 0 : ABI_BUG('called with factors other than 2, 3, and 5')
1242 : : end if
1243 : :
1244 : : end do ! End of direct transformation (loop over ic)
1245 : :
1246 : : ! -----------------------------------------------------------------
1247 : :
1248 : : ! Bitreversal
1249 : : ! Perform bit reversal on last factor of transformation
1250 : :
1251 : : ! Treat radix 4
1252 [ + + ]: 132226182 : if (now(ic)==4) then
1253 : 46815864 : ia=0
1254 : :
1255 : : ! First step of radix 4
1256 [ + + ]: 46815864 : do j=ma,mb
1257 : 37294432 : r4=z(1,ia*4+4,j,g3)
1258 : 37294432 : s4=z(2,ia*4+4,j,g3)
1259 : 37294432 : r3=z(1,ia*4+3,j,g3)
1260 : 37294432 : s3=z(2,ia*4+3,j,g3)
1261 : 37294432 : r2=z(1,ia*4+2,j,g3)
1262 : 37294432 : s2=z(2,ia*4+2,j,g3)
1263 : 37294432 : r1=z(1,ia*4+1,j,g3)
1264 : 37294432 : s1=z(2,ia*4+1,j,g3)
1265 : :
1266 : 37294432 : r=r1 + r3
1267 : 37294432 : s=r2 + r4
1268 : 37294432 : zbr(1,ind(ia*4+1),j,g3) = r + s
1269 : 37294432 : zbr(1,ind(ia*4+3),j,g3) = r - s
1270 : 37294432 : r=r1 - r3
1271 : 37294432 : s=s2 - s4
1272 : 37294432 : zbr(1,ind(ia*4+2),j,g3) = r - s*ris
1273 : 37294432 : zbr(1,ind(ia*4+4),j,g3) = r + s*ris
1274 : 37294432 : r=s1 + s3
1275 : 37294432 : s=s2 + s4
1276 : 37294432 : zbr(2,ind(ia*4+1),j,g3) = r + s
1277 : 37294432 : zbr(2,ind(ia*4+3),j,g3) = r - s
1278 : 37294432 : r=s1 - s3
1279 : 37294432 : s=r2 - r4
1280 : 37294432 : zbr(2,ind(ia*4+2),j,g3) = r + s*ris
1281 : 46815864 : zbr(2,ind(ia*4+4),j,g3) = r - s*ris
1282 : : end do
1283 : :
1284 : : ! Second step of radix 4
1285 [ + + ]: 44075808 : do ia=1,aft(ic)-1
1286 : 34554376 : indx=ind(ia*4+1)-1
1287 : 34554376 : cr2=trig(1,indx)
1288 : 34554376 : ct2=trig(2,indx)
1289 : 34554376 : cr3=trig(1,2*indx)
1290 : 34554376 : ct3=trig(2,2*indx)
1291 : 34554376 : cr4=trig(1,3*indx)
1292 : 34554376 : ct4=trig(2,3*indx)
1293 : 34554376 : cr4=cr4/cr2
1294 : 34554376 : cr2s=cr2*ris
1295 [ + + ]: 188750796 : do j=ma,mb
1296 : 144674988 : r4=z(1,ia*4+4,j,g3) - z(2,ia*4+4,j,g3)*ct4
1297 : 144674988 : s4=z(1,ia*4+4,j,g3)*ct4 + z(2,ia*4+4,j,g3)
1298 : 144674988 : r3=z(1,ia*4+3,j,g3) - z(2,ia*4+3,j,g3)*ct3
1299 : 144674988 : s3=z(1,ia*4+3,j,g3)*ct3 + z(2,ia*4+3,j,g3)
1300 : 144674988 : r2=z(1,ia*4+2,j,g3) - z(2,ia*4+2,j,g3)*ct2
1301 : 144674988 : s2=z(1,ia*4+2,j,g3)*ct2 + z(2,ia*4+2,j,g3)
1302 : 144674988 : r1=z(1,ia*4+1,j,g3)
1303 : 144674988 : s1=z(2,ia*4+1,j,g3)
1304 : :
1305 : 144674988 : r=r1 + r3*cr3
1306 : 144674988 : s=r2 + r4*cr4
1307 : 144674988 : zbr(1,ind(ia*4+1),j,g3) = r + s*cr2
1308 : 144674988 : zbr(1,ind(ia*4+3),j,g3) = r - s*cr2
1309 : 144674988 : r=r1 - r3*cr3
1310 : 144674988 : s=s2 - s4*cr4
1311 : 144674988 : zbr(1,ind(ia*4+2),j,g3) = r - s*cr2s
1312 : 144674988 : zbr(1,ind(ia*4+4),j,g3) = r + s*cr2s
1313 : 144674988 : r=s1 + s3*cr3
1314 : 144674988 : s=s2 + s4*cr4
1315 : 144674988 : zbr(2,ind(ia*4+1),j,g3) = r + s*cr2
1316 : 144674988 : zbr(2,ind(ia*4+3),j,g3) = r - s*cr2
1317 : 144674988 : r=s1 - s3*cr3
1318 : 144674988 : s=r2 - r4*cr4
1319 : 144674988 : zbr(2,ind(ia*4+2),j,g3) = r + s*cr2s
1320 : 179229364 : zbr(2,ind(ia*4+4),j,g3) = r - s*cr2s
1321 : : end do
1322 : : end do
1323 : :
1324 : : ! Treat radix 2
1325 [ + + ]: 56661696 : else if (now(ic)==2) then
1326 : :
1327 : 114741019 : ia=0
1328 : :
1329 : : ! First step of radix 2
1330 [ + + ]: 114741019 : do j=ma,mb
1331 : 93288575 : r1=z(1,ia*2+1,j,g3)
1332 : 93288575 : s1=z(2,ia*2+1,j,g3)
1333 : 93288575 : r2=z(1,ia*2+2,j,g3)
1334 : 93288575 : s2=z(2,ia*2+2,j,g3)
1335 : 93288575 : zbr(1,ind(ia*2+1),j,g3) = r2 + r1
1336 : 93288575 : zbr(2,ind(ia*2+1),j,g3) = s2 + s1
1337 : 93288575 : zbr(1,ind(ia*2+2),j,g3) = -r2 + r1
1338 : 114741019 : zbr(2,ind(ia*2+2),j,g3) = -s2 + s1
1339 : : end do
1340 : :
1341 : : ! Second step of radix 2
1342 [ + + ]: 208375284 : do ia=1,aft(ic)-1
1343 : 186922840 : indx=ind(ia*2+1)-1
1344 : 186922840 : cr2=trig(1,indx)
1345 : 186922840 : ct2=trig(2,indx)
1346 [ + + ]: 1035282544 : do j=ma,mb
1347 : 826907260 : r1=z(1,ia*2+1,j,g3)
1348 : 826907260 : s1=z(2,ia*2+1,j,g3)
1349 : 826907260 : r2=z(1,ia*2+2,j,g3) - z(2,ia*2+2,j,g3)*ct2
1350 : 826907260 : s2=z(1,ia*2+2,j,g3)*ct2 + z(2,ia*2+2,j,g3)
1351 : 826907260 : zbr(1,ind(ia*2+1),j,g3) = r2*cr2 + r1
1352 : 826907260 : zbr(2,ind(ia*2+1),j,g3) = s2*cr2 + s1
1353 : 826907260 : zbr(1,ind(ia*2+2),j,g3) = -r2*cr2 + r1
1354 : 1013830100 : zbr(2,ind(ia*2+2),j,g3) = -s2*cr2 + s1
1355 : : end do
1356 : : end do
1357 : :
1358 : : ! Treat radix 3
1359 [ + - ]: 35209252 : else if (now(ic)==3) then
1360 : : ! radix 3
1361 : : ! .5d0*sqrt(3.d0)=0.8660254037844387d0
1362 : 35209252 : ia=0
1363 : 35209252 : bb=ris*0.8660254037844387d0
1364 : :
1365 : : ! First step of radix 3
1366 [ + + ]: 137620102 : do j=ma,mb
1367 : 102410850 : r1=z(1,ia*3+1,j,g3)
1368 : 102410850 : s1=z(2,ia*3+1,j,g3)
1369 : 102410850 : r2=z(1,ia*3+2,j,g3)
1370 : 102410850 : s2=z(2,ia*3+2,j,g3)
1371 : 102410850 : r3=z(1,ia*3+3,j,g3)
1372 : 102410850 : s3=z(2,ia*3+3,j,g3)
1373 : 102410850 : r=r2 + r3
1374 : 102410850 : s=s2 + s3
1375 : 102410850 : zbr(1,ind(ia*3+1),j,g3) = r + r1
1376 : 102410850 : zbr(2,ind(ia*3+1),j,g3) = s + s1
1377 : 102410850 : r1=r1 - r*.5d0
1378 : 102410850 : s1=s1 - s*.5d0
1379 : 102410850 : r2=r2-r3
1380 : 102410850 : s2=s2-s3
1381 : 102410850 : zbr(1,ind(ia*3+2),j,g3) = r1 - s2*bb
1382 : 102410850 : zbr(2,ind(ia*3+2),j,g3) = s1 + r2*bb
1383 : 102410850 : zbr(1,ind(ia*3+3),j,g3) = r1 + s2*bb
1384 : 137620102 : zbr(2,ind(ia*3+3),j,g3) = s1 - r2*bb
1385 : : end do
1386 : :
1387 [ + + ]: 172682624 : do ia=1,aft(ic)-1
1388 : 137473372 : indx=ind(ia*3+1)-1
1389 : 137473372 : cr2=trig(1,indx)
1390 : 137473372 : ct2=trig(2,indx)
1391 : 137473372 : cr3=trig(1,2*indx)
1392 : 137473372 : ct3=trig(2,2*indx)
1393 : 137473372 : cr2=cr2/cr3
1394 : 137473372 : cr3p=.5d0*cr3
1395 : 137473372 : bb=ris*cr3*0.8660254037844387d0
1396 [ + + ]: 575510116 : do j=ma,mb
1397 : 402827492 : r1=z(1,ia*3+1,j,g3)
1398 : 402827492 : s1=z(2,ia*3+1,j,g3)
1399 : 402827492 : r2=z(1,ia*3+2,j,g3) - z(2,ia*3+2,j,g3)*ct2
1400 : 402827492 : s2=z(1,ia*3+2,j,g3)*ct2 + z(2,ia*3+2,j,g3)
1401 : 402827492 : r3=z(1,ia*3+3,j,g3) - z(2,ia*3+3,j,g3)*ct3
1402 : 402827492 : s3=z(1,ia*3+3,j,g3)*ct3 + z(2,ia*3+3,j,g3)
1403 : 402827492 : r=cr2*r2 + r3
1404 : 402827492 : s=cr2*s2 + s3
1405 : 402827492 : zbr(1,ind(ia*3+1),j,g3) = r*cr3 + r1
1406 : 402827492 : zbr(2,ind(ia*3+1),j,g3) = s*cr3 + s1
1407 : 402827492 : r1=r1 - r*cr3p
1408 : 402827492 : s1=s1 - s*cr3p
1409 : 402827492 : r2=cr2*r2-r3
1410 : 402827492 : s2=cr2*s2-s3
1411 : 402827492 : zbr(1,ind(ia*3+2),j,g3) = r1 - s2*bb
1412 : 402827492 : zbr(2,ind(ia*3+2),j,g3) = s1 + r2*bb
1413 : 402827492 : zbr(1,ind(ia*3+3),j,g3) = r1 + s2*bb
1414 : 540300864 : zbr(2,ind(ia*3+3),j,g3) = s1 - r2*bb
1415 : : end do
1416 : : end do
1417 : :
1418 : : ! Treat radix 5
1419 [ # # ]: 0 : else if (now(ic)==5) then
1420 : : ! radix 5
1421 : : ! sin(2.d0*pi/5.d0)
1422 : 0 : sin2=ris*0.9510565162951536d0
1423 : 0 : ia=0
1424 : :
1425 : : ! First step of radix 5
1426 [ # # ]: 0 : do j=ma,mb
1427 : 0 : r1=z(1,ia*5+1,j,g3)
1428 : 0 : s1=z(2,ia*5+1,j,g3)
1429 : 0 : r2=z(1,ia*5+2,j,g3)
1430 : 0 : s2=z(2,ia*5+2,j,g3)
1431 : 0 : r3=z(1,ia*5+3,j,g3)
1432 : 0 : s3=z(2,ia*5+3,j,g3)
1433 : 0 : r4=z(1,ia*5+4,j,g3)
1434 : 0 : s4=z(2,ia*5+4,j,g3)
1435 : 0 : r5=z(1,ia*5+5,j,g3)
1436 : 0 : s5=z(2,ia*5+5,j,g3)
1437 : 0 : r25 = r2 + r5
1438 : 0 : r34 = r3 + r4
1439 : 0 : s25 = s2 - s5
1440 : 0 : s34 = s3 - s4
1441 : 0 : zbr(1,ind(ia*5+1),j,g3) = r1 + r25 + r34
1442 : 0 : r = r1 + cos2*r25 + cos4*r34
1443 : 0 : s = s25 + sin42*s34
1444 : 0 : zbr(1,ind(ia*5+2),j,g3) = r - sin2*s
1445 : 0 : zbr(1,ind(ia*5+5),j,g3) = r + sin2*s
1446 : 0 : r = r1 + cos4*r25 + cos2*r34
1447 : 0 : s = sin42*s25 - s34
1448 : 0 : zbr(1,ind(ia*5+3),j,g3) = r - sin2*s
1449 : 0 : zbr(1,ind(ia*5+4),j,g3) = r + sin2*s
1450 : 0 : r25 = r2 - r5
1451 : 0 : r34 = r3 - r4
1452 : 0 : s25 = s2 + s5
1453 : 0 : s34 = s3 + s4
1454 : 0 : zbr(2,ind(ia*5+1),j,g3) = s1 + s25 + s34
1455 : 0 : r = s1 + cos2*s25 + cos4*s34
1456 : 0 : s = r25 + sin42*r34
1457 : 0 : zbr(2,ind(ia*5+2),j,g3) = r + sin2*s
1458 : 0 : zbr(2,ind(ia*5+5),j,g3) = r - sin2*s
1459 : 0 : r = s1 + cos4*s25 + cos2*s34
1460 : 0 : s = sin42*r25 - r34
1461 : 0 : zbr(2,ind(ia*5+3),j,g3) = r + sin2*s
1462 : 0 : zbr(2,ind(ia*5+4),j,g3) = r - sin2*s
1463 : : end do
1464 : :
1465 : : ! Second step of radix 5
1466 [ # # ]: 0 : do ia=1,aft(ic)-1
1467 : 0 : indx=ind(ia*5+1)-1
1468 : 0 : cr2=trig(1,indx)
1469 : 0 : ct2=trig(2,indx)
1470 : 0 : cr3=trig(1,2*indx)
1471 : 0 : ct3=trig(2,2*indx)
1472 : 0 : cr4=trig(1,3*indx)
1473 : 0 : ct4=trig(2,3*indx)
1474 : 0 : cr5=trig(1,4*indx)
1475 : 0 : ct5=trig(2,4*indx)
1476 [ # # ]: 0 : do j=ma,mb
1477 : 0 : r1=z(1,ia*5+1,j,g3)
1478 : 0 : s1=z(2,ia*5+1,j,g3)
1479 : 0 : r2=cr2*(z(1,ia*5+2,j,g3) - z(2,ia*5+2,j,g3)*ct2)
1480 : 0 : s2=cr2*(z(1,ia*5+2,j,g3)*ct2 + z(2,ia*5+2,j,g3))
1481 : 0 : r3=cr3*(z(1,ia*5+3,j,g3) - z(2,ia*5+3,j,g3)*ct3)
1482 : 0 : s3=cr3*(z(1,ia*5+3,j,g3)*ct3 + z(2,ia*5+3,j,g3))
1483 : 0 : r4=z(1,ia*5+4,j,g3) - z(2,ia*5+4,j,g3)*ct4
1484 : 0 : s4=z(1,ia*5+4,j,g3)*ct4 + z(2,ia*5+4,j,g3)
1485 : 0 : r5=z(1,ia*5+5,j,g3) - z(2,ia*5+5,j,g3)*ct5
1486 : 0 : s5=z(1,ia*5+5,j,g3)*ct5 + z(2,ia*5+5,j,g3)
1487 : 0 : r25 = r2 + r5*cr5
1488 : 0 : r34 = r3 + r4*cr4
1489 : 0 : s25 = s2 - s5*cr5
1490 : 0 : s34 = s3 - s4*cr4
1491 : 0 : zbr(1,ind(ia*5+1),j,g3) = r1 + r25 + r34
1492 : 0 : r = r1 + cos2*r25 + cos4*r34
1493 : 0 : s = s25 + sin42*s34
1494 : 0 : zbr(1,ind(ia*5+2),j,g3) = r - sin2*s
1495 : 0 : zbr(1,ind(ia*5+5),j,g3) = r + sin2*s
1496 : 0 : r = r1 + cos4*r25 + cos2*r34
1497 : 0 : s = sin42*s25 - s34
1498 : 0 : zbr(1,ind(ia*5+3),j,g3) = r - sin2*s
1499 : 0 : zbr(1,ind(ia*5+4),j,g3) = r + sin2*s
1500 : 0 : r25 = r2 - r5*cr5
1501 : 0 : r34 = r3 - r4*cr4
1502 : 0 : s25 = s2 + s5*cr5
1503 : 0 : s34 = s3 + s4*cr4
1504 : 0 : zbr(2,ind(ia*5+1),j,g3) = s1 + s25 + s34
1505 : 0 : r = s1 + cos2*s25 + cos4*s34
1506 : 0 : s = r25 + sin42*r34
1507 : 0 : zbr(2,ind(ia*5+2),j,g3) = r + sin2*s
1508 : 0 : zbr(2,ind(ia*5+5),j,g3) = r - sin2*s
1509 : 0 : r = s1 + cos4*s25 + cos2*s34
1510 : 0 : s = sin42*r25 - r34
1511 : 0 : zbr(2,ind(ia*5+3),j,g3) = r + sin2*s
1512 : 0 : zbr(2,ind(ia*5+4),j,g3) = r - sin2*s
1513 : : end do
1514 : : end do
1515 : :
1516 : : else
1517 : : ! All radices are treated
1518 : 0 : ABI_BUG('called with factors other than 2, 3, and 5')
1519 : : end if
1520 : :
1521 : : ! End of bit reversal
1522 : :
1523 : : ! -------------------------------------------------------------------
1524 : : end do
1525 : : end do
1526 : : end do
1527 : : !$OMP END PARALLEL DO
1528 : :
1529 : 32997005 : end subroutine sg_fftpx
1530 : : !!***
1531 : :
1532 : : !----------------------------------------------------------------------
1533 : :
1534 : : !!****f* m_sgfft/sg_fftx
1535 : : !! NAME
1536 : : !! sg_fftx
1537 : : !!
1538 : : !! FUNCTION
1539 : : !! This subroutine is called by the 3-dimensional fft to conduct the
1540 : : !! "x" transforms for all y and z.
1541 : : !!
1542 : : !! INPUTS
1543 : : !! fftcache=size of the cache (kB)
1544 : : !! mfac = maximum number of factors in 1D FFTs
1545 : : !! mg = maximum length of 1D FFTs
1546 : : !! nd1=first dimension of (complex) arrays z and zbr (treated as real within
1547 : : !! this subroutine)
1548 : : !! nd2=second dimension of (complex) arrays z and zbr (treated as real within
1549 : : !! this subroutine)
1550 : : !! nd3=third dimension of (complex) arrays z and zbr (treated as real within
1551 : : !! this subroutine)
1552 : : !! n2,n3=actual length of y and z transforms
1553 : : !! z(2,nd1,nd2,nd3)=INPUT array; destroyed by transformation
1554 : : !! trig, aft, now, bef, ind=provided by previous call to ctrig
1555 : : !! Note that in this routine (and in ctrig) the values in array trig are
1556 : : !! actually cos and tan, not cos and sin. Use of tan allows advantageous
1557 : : !! use of FMA on the ibm rs6000.
1558 : : !! ris=sign of exponential in transform (should be 1 or -1; real)
1559 : : !! ic=number of (radix) factors of x transform length (from ctrig)
1560 : : !!
1561 : : !! OUTPUT
1562 : : !! zbr(2,nd1,nd2,nd3)=OUTPUT transformed array; no scaling applied
1563 : : !!
1564 : : !! SIDE EFFECTS
1565 : : !!
1566 : : !! NOTES
1567 : : !! This routine blocks the x transforms
1568 : : !! so that all transforms under consideration at one step fit within
1569 : : !! the cache memory, which is crucial for optimal performance.
1570 : : !! The blocking factor is set by parameter "fftcache" below, which should
1571 : : !! be adjusted to be somewhat smaller (say 3/4) than the actual cache size
1572 : : !! of the machine.
1573 : : !!
1574 : : !! TODO
1575 : : !! Use latex for the equation above
1576 : : !!
1577 : : !! SOURCE
1578 : :
1579 : 281529 : subroutine sg_fftx(fftcache,mfac,mg,nd1,nd2,nd3,n2,n3,z,zbr,&
1580 : 281529 : & trig,aft,now,bef,ris,ind,ic)
1581 : :
1582 : : !Arguments ------------------------------------
1583 : : !Dimensions of aft, now, bef, ind, and trig should agree with
1584 : : !those in subroutine ctrig.
1585 : : !scalars
1586 : : integer,intent(in) :: fftcache,ic,mfac,mg,n2,n3,nd1,nd2,nd3
1587 : : real(dp),intent(in) :: ris
1588 : : !arrays
1589 : : integer,intent(in) :: aft(mfac),bef(mfac),ind(mg),now(mfac)
1590 : : real(dp),intent(in) :: trig(2,mg)
1591 : : real(dp),intent(inout) :: z(2,nd1,nd2,nd3),zbr(2,nd1,nd2,nd3)
1592 : :
1593 : : !Local variables-------------------------------
1594 : : !scalars
1595 : : integer :: i,i3,ia,ib,indx,j,jj,lot,ma,mb,ntb
1596 : : real(dp),parameter :: cos2=0.3090169943749474d0 !cos(2.d0*pi/5.d0)
1597 : : real(dp),parameter :: cos4=-0.8090169943749474d0 !cos(4.d0*pi/5.d0)
1598 : : real(dp),parameter :: sin42=0.6180339887498948d0 !sin(4.d0*pi/5.d0)/sin(2.d0*pi/5.d0)
1599 : : real(dp) :: bb,cr2,cr2s,cr3,cr3p,cr4,cr5,ct2,ct3,ct4,ct5
1600 : : real(dp) :: factor,r,r1,r2,r25,r3,r34,r4,r5,s,sin2,s1,s2,s25,s3,s34,s4,s5
1601 : :
1602 : : ! *************************************************************************
1603 : :
1604 : : !print *, "now", now(1:ic)
1605 : :
1606 : : !Do x transforms in blocks of size "lot" which is set by how
1607 : : !many x transform arrays (of size nd1 each) fit into the nominal
1608 : : !cache size "fftcache".
1609 : 281529 : factor=0.75d0
1610 : 281529 : lot=(fftcache*factor*1000d0)/(nd1*8*2)
1611 : :
1612 : : !XG : due to the dimension problems on the P6, I have slightly
1613 : : !modified this part of the code, with an external loop
1614 : : !on n3 ...
1615 : : !Modifications are indicated explicitely, or
1616 : : !are related to the increase of the number of dimensions of z and
1617 : : !zbr ...
1618 : :
1619 : 281529 : factor=0.75d0
1620 : 281529 : lot=(fftcache*factor*1000d0)/(nd1*8*2)
1621 : 281529 : if(lot.lt.1) lot=1 ! this may happen for very large cells
1622 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(aft,bef,ic,ind,lot,n2,n3,now,ris,trig,z,zbr)
1623 [ + + ]: 1876763 : do i3=1,n3
1624 [ + - + + ]: 4010203 : do jj=1,n2,lot
1625 : : ! end of modification
1626 : :
1627 : : ! For each jj, ma and mb give starting and ending addresses for fft
1628 : : ! ma starts where we left off after last block
1629 : 2133440 : ma=jj
1630 : : ! mb runs to the end of the block or else to the end of the data
1631 : : ! modified XG 980107
1632 : : ! mb=min(jj+(lot-1),n23)
1633 : 2133440 : mb=min(jj+(lot-1),n2)
1634 : :
1635 : : ! Run over all factors except the last (to ic-1), performing
1636 : : ! x transform
1637 : :
1638 : : ! Note: fortran should skip this loop if ic=1; beware "onetrip"
1639 : : ! compiler option which forces each loop at least once
1640 : :
1641 : : ! ------------------------------------------------------------------------
1642 : :
1643 : : ! Direct transformation (to be followed by bit reversal)
1644 : :
1645 [ + + ]: 5346800 : do i=1,ic-1
1646 : 3213360 : ntb=now(i)*bef(i)
1647 : : ! radix 4
1648 : :
1649 : : ! Treat radix 4
1650 [ + + ]: 5346800 : if (now(i)==4) then
1651 : 3897985 : ia=0
1652 : :
1653 : : ! First step of factor 4
1654 [ + + ]: 3897985 : do ib=1,bef(i)
1655 [ + + ]: 33781849 : do j=ma,mb
1656 : 29883864 : r4=z(1,ia*ntb+3*bef(i)+ib,j,i3)
1657 : 29883864 : s4=z(2,ia*ntb+3*bef(i)+ib,j,i3)
1658 : 29883864 : r3=z(1,ia*ntb+2*bef(i)+ib,j,i3)
1659 : 29883864 : s3=z(2,ia*ntb+2*bef(i)+ib,j,i3)
1660 : 29883864 : r2=z(1,ia*ntb+bef(i)+ib,j,i3)
1661 : 29883864 : s2=z(2,ia*ntb+bef(i)+ib,j,i3)
1662 : 29883864 : r1=z(1,ia*ntb+ib,j,i3)
1663 : 29883864 : s1=z(2,ia*ntb+ib,j,i3)
1664 : :
1665 : 29883864 : r=r1 + r3
1666 : 29883864 : s=r2 + r4
1667 : 29883864 : z(1,ia*ntb+ib,j,i3) = r + s
1668 : 29883864 : z(1,ia*ntb+2*bef(i)+ib,j,i3) = r - s
1669 : 29883864 : r=r1 - r3
1670 : 29883864 : s=s2 - s4
1671 : 29883864 : z(1,ia*ntb+bef(i)+ib,j,i3) = r - s*ris
1672 : 29883864 : z(1,ia*ntb+3*bef(i)+ib,j,i3) = r + s*ris
1673 : 29883864 : r=s1 + s3
1674 : 29883864 : s=s2 + s4
1675 : 29883864 : z(2,ia*ntb+ib,j,i3) = r + s
1676 : 29883864 : z(2,ia*ntb+2*bef(i)+ib,j,i3) = r - s
1677 : 29883864 : r=s1 - s3
1678 : 29883864 : s=r2 - r4
1679 : 29883864 : z(2,ia*ntb+bef(i)+ib,j,i3) = r + s*ris
1680 : 32682262 : z(2,ia*ntb+3*bef(i)+ib,j,i3) = r - s*ris
1681 : : end do
1682 : : end do
1683 : :
1684 : : ! Second step of factor 4
1685 [ + + ]: 1374787 : do ia=1,aft(i)-1
1686 : 275200 : indx=ind(ia*4*bef(i)+1)-1
1687 : 275200 : indx=indx*bef(i)
1688 : 275200 : cr2=trig(1,indx)
1689 : 275200 : ct2=trig(2,indx)
1690 : 275200 : cr3=trig(1,2*indx)
1691 : 275200 : ct3=trig(2,2*indx)
1692 : 275200 : cr4=trig(1,3*indx)
1693 : 275200 : ct4=trig(2,3*indx)
1694 : 275200 : cr4=cr4/cr2
1695 : 275200 : cr2s=cr2*ris
1696 [ + + ]: 1925187 : do ib=1,bef(i)
1697 [ + + ]: 6748416 : do j=ma,mb
1698 : : r4=z(1,ia*ntb+3*bef(i)+ib,j,i3) - &
1699 : 5922816 : & z(2,ia*ntb+3*bef(i)+ib,j,i3)*ct4
1700 : : s4=z(1,ia*ntb+3*bef(i)+ib,j,i3)*ct4 + &
1701 : 5922816 : & z(2,ia*ntb+3*bef(i)+ib,j,i3)
1702 : : r3=z(1,ia*ntb+2*bef(i)+ib,j,i3) - &
1703 : 5922816 : & z(2,ia*ntb+2*bef(i)+ib,j,i3)*ct3
1704 : : s3=z(1,ia*ntb+2*bef(i)+ib,j,i3)*ct3 + &
1705 : 5922816 : & z(2,ia*ntb+2*bef(i)+ib,j,i3)
1706 : : r2=z(1,ia*ntb+bef(i)+ib,j,i3) - &
1707 : 5922816 : & z(2,ia*ntb+bef(i)+ib,j,i3)*ct2
1708 : : s2=z(1,ia*ntb+bef(i)+ib,j,i3)*ct2 + &
1709 : 5922816 : & z(2,ia*ntb+bef(i)+ib,j,i3)
1710 : 5922816 : r1=z(1,ia*ntb+ib,j,i3)
1711 : 5922816 : s1=z(2,ia*ntb+ib,j,i3)
1712 : :
1713 : 5922816 : r=r1 + r3*cr3
1714 : 5922816 : s=r2 + r4*cr4
1715 : 5922816 : z(1,ia*ntb+ib,j,i3) = r + s*cr2
1716 : 5922816 : z(1,ia*ntb+2*bef(i)+ib,j,i3) = r - s*cr2
1717 : 5922816 : r=r1 - r3*cr3
1718 : 5922816 : s=s2 - s4*cr4
1719 : 5922816 : z(1,ia*ntb+bef(i)+ib,j,i3) = r - s*cr2s
1720 : 5922816 : z(1,ia*ntb+3*bef(i)+ib,j,i3) = r + s*cr2s
1721 : 5922816 : r=s1 + s3*cr3
1722 : 5922816 : s=s2 + s4*cr4
1723 : 5922816 : z(2,ia*ntb+ib,j,i3) = r + s*cr2
1724 : 5922816 : z(2,ia*ntb+2*bef(i)+ib,j,i3) = r - s*cr2
1725 : 5922816 : r=s1 - s3*cr3
1726 : 5922816 : s=r2 - r4*cr4
1727 : 5922816 : z(2,ia*ntb+bef(i)+ib,j,i3) = r + s*cr2s
1728 : 6473216 : z(2,ia*ntb+3*bef(i)+ib,j,i3) = r - s*cr2s
1729 : : end do
1730 : : end do
1731 : : end do
1732 : :
1733 : : ! Treat radix 2
1734 [ - + ]: 2113773 : else if (now(i)==2) then
1735 : 0 : ia=0
1736 : :
1737 : : ! First step of factor 2
1738 [ # # ]: 0 : do ib=1,bef(i)
1739 [ # # ]: 0 : do j=ma,mb
1740 : 0 : r1=z(1,ia*ntb+ib,j,i3)
1741 : 0 : s1=z(2,ia*ntb+ib,j,i3)
1742 : 0 : r2=z(1,ia*ntb+bef(i)+ib,j,i3)
1743 : 0 : s2=z(2,ia*ntb+bef(i)+ib,j,i3)
1744 : 0 : z(1,ia*ntb+ib,j,i3) = r2 + r1
1745 : 0 : z(2,ia*ntb+ib,j,i3) = s2 + s1
1746 : 0 : z(1,ia*ntb+bef(i)+ib,j,i3) = -r2 + r1
1747 : 0 : z(2,ia*ntb+bef(i)+ib,j,i3) = -s2 + s1
1748 : : end do
1749 : : end do
1750 : :
1751 : : ! Second step of factor 2
1752 [ # # ]: 0 : do ia=1,aft(i)-1
1753 : 0 : indx=ind(ia*2*bef(i)+1)-1
1754 : 0 : indx=indx*bef(i)
1755 : 0 : cr2=trig(1,indx)
1756 : 0 : ct2=trig(2,indx)
1757 [ # # ]: 0 : do ib=1,bef(i)
1758 [ # # ]: 0 : do j=ma,mb
1759 : 0 : r1=z(1,ia*ntb+ib,j,i3)
1760 : 0 : s1=z(2,ia*ntb+ib,j,i3)
1761 : : r2=z(1,ia*ntb+bef(i)+ib,j,i3) - &
1762 : 0 : & z(2,ia*ntb+bef(i)+ib,j,i3)*ct2
1763 : : s2=z(1,ia*ntb+bef(i)+ib,j,i3)*ct2 + &
1764 : 0 : & z(2,ia*ntb+bef(i)+ib,j,i3)
1765 : 0 : z(1,ia*ntb+ib,j,i3) = r2*cr2 + r1
1766 : 0 : z(2,ia*ntb+ib,j,i3) = s2*cr2 + s1
1767 : 0 : z(1,ia*ntb+bef(i)+ib,j,i3) = -r2*cr2 + r1
1768 : 0 : z(2,ia*ntb+bef(i)+ib,j,i3) = -s2*cr2 + s1
1769 : : end do
1770 : : end do
1771 : : end do
1772 : :
1773 : : ! Treat radix 3
1774 [ + + ]: 2113773 : else if (now(i)==3) then
1775 : : ! .5d0*sqrt(3.d0)=0.8660254037844387d0
1776 : 818116 : ia=0
1777 : 818116 : bb=ris*0.8660254037844387d0
1778 : :
1779 : : ! First step of factor 3
1780 [ + + ]: 5822012 : do ib=1,bef(i)
1781 [ + + ]: 61050432 : do j=ma,mb
1782 : 55228420 : r1=z(1,ia*ntb+ib,j,i3)
1783 : 55228420 : s1=z(2,ia*ntb+ib,j,i3)
1784 : 55228420 : r2=z(1,ia*ntb+bef(i)+ib,j,i3)
1785 : 55228420 : s2=z(2,ia*ntb+bef(i)+ib,j,i3)
1786 : 55228420 : r3=z(1,ia*ntb+2*bef(i)+ib,j,i3)
1787 : 55228420 : s3=z(2,ia*ntb+2*bef(i)+ib,j,i3)
1788 : 55228420 : r=r2 + r3
1789 : 55228420 : s=s2 + s3
1790 : 55228420 : z(1,ia*ntb+ib,j,i3) = r + r1
1791 : 55228420 : z(2,ia*ntb+ib,j,i3) = s + s1
1792 : 55228420 : r1=r1 - r*.5d0
1793 : 55228420 : s1=s1 - s*.5d0
1794 : 55228420 : r2=r2-r3
1795 : 55228420 : s2=s2-s3
1796 : 55228420 : z(1,ia*ntb+bef(i)+ib,j,i3) = r1 - s2*bb
1797 : 55228420 : z(2,ia*ntb+bef(i)+ib,j,i3) = s1 + r2*bb
1798 : 55228420 : z(1,ia*ntb+2*bef(i)+ib,j,i3) = r1 + s2*bb
1799 : 60232316 : z(2,ia*ntb+2*bef(i)+ib,j,i3) = s1 - r2*bb
1800 : : end do
1801 : : end do
1802 : :
1803 : : ! Second step of factor 3
1804 [ + + ]: 4516820 : do ia=1,aft(i)-1
1805 : 3698704 : indx=ind(ia*3*bef(i)+1)-1
1806 : 3698704 : indx=indx*bef(i)
1807 : 3698704 : cr2=trig(1,indx)
1808 : 3698704 : ct2=trig(2,indx)
1809 : 3698704 : cr3=trig(1,2*indx)
1810 : 3698704 : ct3=trig(2,2*indx)
1811 : 3698704 : cr2=cr2/cr3
1812 : 3698704 : cr3p=.5d0*cr3
1813 : 3698704 : bb=ris*cr3*0.8660254037844387d0
1814 [ + + ]: 14615668 : do ib=1,bef(i)
1815 [ + + ]: 115401272 : do j=ma,mb
1816 : 101603720 : r1=z(1,ia*ntb+ib,j,i3)
1817 : 101603720 : s1=z(2,ia*ntb+ib,j,i3)
1818 : : r2=z(1,ia*ntb+bef(i)+ib,j,i3) - &
1819 : 101603720 : & z(2,ia*ntb+bef(i)+ib,j,i3)*ct2
1820 : : s2=z(1,ia*ntb+bef(i)+ib,j,i3)*ct2 + &
1821 : 101603720 : & z(2,ia*ntb+bef(i)+ib,j,i3)
1822 : : r3=z(1,ia*ntb+2*bef(i)+ib,j,i3) - &
1823 : 101603720 : & z(2,ia*ntb+2*bef(i)+ib,j,i3)*ct3
1824 : : s3=z(1,ia*ntb+2*bef(i)+ib,j,i3)*ct3 + &
1825 : 101603720 : & z(2,ia*ntb+2*bef(i)+ib,j,i3)
1826 : 101603720 : r=cr2*r2 + r3
1827 : 101603720 : s=cr2*s2 + s3
1828 : 101603720 : z(1,ia*ntb+ib,j,i3) = r*cr3 + r1
1829 : 101603720 : z(2,ia*ntb+ib,j,i3) = s*cr3 + s1
1830 : 101603720 : r1=r1 - r*cr3p
1831 : 101603720 : s1=s1 - s*cr3p
1832 : 101603720 : r2=cr2*r2-r3
1833 : 101603720 : s2=cr2*s2-s3
1834 : 101603720 : z(1,ia*ntb+bef(i)+ib,j,i3) = r1 - s2*bb
1835 : 101603720 : z(2,ia*ntb+bef(i)+ib,j,i3) = s1 + r2*bb
1836 : 101603720 : z(1,ia*ntb+2*bef(i)+ib,j,i3) = r1 + s2*bb
1837 : 111702568 : z(2,ia*ntb+2*bef(i)+ib,j,i3) = s1 - r2*bb
1838 : : end do
1839 : : end do
1840 : : end do
1841 : :
1842 : : ! Treat radix 5
1843 [ + - ]: 1295657 : else if (now(i)==5) then
1844 : : ! sin(2.d0*pi/5.d0)
1845 : 1295657 : sin2=ris*0.9510565162951536d0
1846 : 1295657 : ia=0
1847 : :
1848 : : ! First step of factor 5
1849 [ + + ]: 11958176 : do ib=1,bef(i)
1850 [ + + ]: 99118513 : do j=ma,mb
1851 : 87160337 : r1=z(1,ia*ntb+ib,j,i3)
1852 : 87160337 : s1=z(2,ia*ntb+ib,j,i3)
1853 : 87160337 : r2=z(1,ia*ntb+bef(i)+ib,j,i3)
1854 : 87160337 : s2=z(2,ia*ntb+bef(i)+ib,j,i3)
1855 : 87160337 : r3=z(1,ia*ntb+2*bef(i)+ib,j,i3)
1856 : 87160337 : s3=z(2,ia*ntb+2*bef(i)+ib,j,i3)
1857 : 87160337 : r4=z(1,ia*ntb+3*bef(i)+ib,j,i3)
1858 : 87160337 : s4=z(2,ia*ntb+3*bef(i)+ib,j,i3)
1859 : 87160337 : r5=z(1,ia*ntb+4*bef(i)+ib,j,i3)
1860 : 87160337 : s5=z(2,ia*ntb+4*bef(i)+ib,j,i3)
1861 : 87160337 : r25 = r2 + r5
1862 : 87160337 : r34 = r3 + r4
1863 : 87160337 : s25 = s2 - s5
1864 : 87160337 : s34 = s3 - s4
1865 : 87160337 : z(1,ia*ntb+ib,j,i3) = r1 + r25 + r34
1866 : 87160337 : r = r1 + cos2*r25 + cos4*r34
1867 : 87160337 : s = s25 + sin42*s34
1868 : 87160337 : z(1,ia*ntb+bef(i)+ib,j,i3) = r - sin2*s
1869 : 87160337 : z(1,ia*ntb+4*bef(i)+ib,j,i3) = r + sin2*s
1870 : 87160337 : r = r1 + cos4*r25 + cos2*r34
1871 : 87160337 : s = sin42*s25 - s34
1872 : 87160337 : z(1,ia*ntb+2*bef(i)+ib,j,i3) = r - sin2*s
1873 : 87160337 : z(1,ia*ntb+3*bef(i)+ib,j,i3) = r + sin2*s
1874 : 87160337 : r25 = r2 - r5
1875 : 87160337 : r34 = r3 - r4
1876 : 87160337 : s25 = s2 + s5
1877 : 87160337 : s34 = s3 + s4
1878 : 87160337 : z(2,ia*ntb+ib,j,i3) = s1 + s25 + s34
1879 : 87160337 : r = s1 + cos2*s25 + cos4*s34
1880 : 87160337 : s = r25 + sin42*r34
1881 : 87160337 : z(2,ia*ntb+bef(i)+ib,j,i3) = r + sin2*s
1882 : 87160337 : z(2,ia*ntb+4*bef(i)+ib,j,i3) = r - sin2*s
1883 : 87160337 : r = s1 + cos4*s25 + cos2*s34
1884 : 87160337 : s = sin42*r25 - r34
1885 : 87160337 : z(2,ia*ntb+2*bef(i)+ib,j,i3) = r + sin2*s
1886 : 97822856 : z(2,ia*ntb+3*bef(i)+ib,j,i3) = r - sin2*s
1887 : : end do
1888 : : end do
1889 : :
1890 : : ! Second step of factor 5
1891 [ + + ]: 2704457 : do ia=1,aft(i)-1
1892 : 1408800 : indx=ind(ia*5*bef(i)+1)-1
1893 : 1408800 : indx=indx*bef(i)
1894 : 1408800 : cr2=trig(1,indx)
1895 : 1408800 : ct2=trig(2,indx)
1896 : 1408800 : cr3=trig(1,2*indx)
1897 : 1408800 : ct3=trig(2,2*indx)
1898 : 1408800 : cr4=trig(1,3*indx)
1899 : 1408800 : ct4=trig(2,3*indx)
1900 : 1408800 : cr5=trig(1,4*indx)
1901 : 1408800 : ct5=trig(2,4*indx)
1902 [ + + ]: 7602057 : do ib=1,bef(i)
1903 [ + + ]: 43823200 : do j=ma,mb
1904 : 37516800 : r1=z(1,ia*ntb+ib,j,i3)
1905 : 37516800 : s1=z(2,ia*ntb+ib,j,i3)
1906 : : r2=cr2*(z(1,ia*ntb+bef(i)+ib,j,i3) - &
1907 : 37516800 : & z(2,ia*ntb+bef(i)+ib,j,i3)*ct2)
1908 : : s2=cr2*(z(1,ia*ntb+bef(i)+ib,j,i3)*ct2 + &
1909 : 37516800 : & z(2,ia*ntb+bef(i)+ib,j,i3))
1910 : : r3=cr3*(z(1,ia*ntb+2*bef(i)+ib,j,i3) - &
1911 : 37516800 : & z(2,ia*ntb+2*bef(i)+ib,j,i3)*ct3)
1912 : : s3=cr3*(z(1,ia*ntb+2*bef(i)+ib,j,i3)*ct3 + &
1913 : 37516800 : & z(2,ia*ntb+2*bef(i)+ib,j,i3))
1914 : : r4=z(1,ia*ntb+3*bef(i)+ib,j,i3) - &
1915 : 37516800 : & z(2,ia*ntb+3*bef(i)+ib,j,i3)*ct4
1916 : : s4=z(1,ia*ntb+3*bef(i)+ib,j,i3)*ct4 + &
1917 : 37516800 : & z(2,ia*ntb+3*bef(i)+ib,j,i3)
1918 : : r5=z(1,ia*ntb+4*bef(i)+ib,j,i3) - &
1919 : 37516800 : & z(2,ia*ntb+4*bef(i)+ib,j,i3)*ct5
1920 : : s5=z(1,ia*ntb+4*bef(i)+ib,j,i3)*ct5 + &
1921 : 37516800 : & z(2,ia*ntb+4*bef(i)+ib,j,i3)
1922 : 37516800 : r25 = r2 + r5*cr5
1923 : 37516800 : r34 = r3 + r4*cr4
1924 : 37516800 : s25 = s2 - s5*cr5
1925 : 37516800 : s34 = s3 - s4*cr4
1926 : 37516800 : z(1,ia*ntb+ib,j,i3) = r1 + r25 + r34
1927 : 37516800 : r = r1 + cos2*r25 + cos4*r34
1928 : 37516800 : s = s25 + sin42*s34
1929 : 37516800 : z(1,ia*ntb+bef(i)+ib,j,i3) = r - sin2*s
1930 : 37516800 : z(1,ia*ntb+4*bef(i)+ib,j,i3) = r + sin2*s
1931 : 37516800 : r = r1 + cos4*r25 + cos2*r34
1932 : 37516800 : s = sin42*s25 - s34
1933 : 37516800 : z(1,ia*ntb+2*bef(i)+ib,j,i3) = r - sin2*s
1934 : 37516800 : z(1,ia*ntb+3*bef(i)+ib,j,i3) = r + sin2*s
1935 : 37516800 : r25 = r2 - r5*cr5
1936 : 37516800 : r34 = r3 - r4*cr4
1937 : 37516800 : s25 = s2 + s5*cr5
1938 : 37516800 : s34 = s3 + s4*cr4
1939 : 37516800 : z(2,ia*ntb+ib,j,i3) = s1 + s25 + s34
1940 : 37516800 : r = s1 + cos2*s25 + cos4*s34
1941 : 37516800 : s = r25 + sin42*r34
1942 : 37516800 : z(2,ia*ntb+bef(i)+ib,j,i3) = r + sin2*s
1943 : 37516800 : z(2,ia*ntb+4*bef(i)+ib,j,i3) = r - sin2*s
1944 : 37516800 : r = s1 + cos4*s25 + cos2*s34
1945 : 37516800 : s = sin42*r25 - r34
1946 : 37516800 : z(2,ia*ntb+2*bef(i)+ib,j,i3) = r + sin2*s
1947 : 42414400 : z(2,ia*ntb+3*bef(i)+ib,j,i3) = r - sin2*s
1948 : : end do
1949 : : end do
1950 : : end do
1951 : :
1952 : : else
1953 : : ! All factors have been treated
1954 : 0 : ABI_BUG('called with factors other than 2, 3, and 5')
1955 : : end if
1956 : :
1957 : : end do
1958 : :
1959 : : ! ---------------------------------------------------------------
1960 : :
1961 : : ! bitreversal
1962 : :
1963 : : ! Perform bit reversal on last factor of transformation
1964 : :
1965 : : ! Treat factor 4
1966 [ + + ]: 3728674 : if (now(ic)==4) then
1967 : : ! radix 4
1968 : 1737640 : ia=0
1969 : :
1970 : : ! First step of factor 4
1971 [ + + ]: 1737640 : do j=ma,mb
1972 : 1521592 : r4=z(1,ia*4+4,j,i3)
1973 : 1521592 : s4=z(2,ia*4+4,j,i3)
1974 : 1521592 : r3=z(1,ia*4+3,j,i3)
1975 : 1521592 : s3=z(2,ia*4+3,j,i3)
1976 : 1521592 : r2=z(1,ia*4+2,j,i3)
1977 : 1521592 : s2=z(2,ia*4+2,j,i3)
1978 : 1521592 : r1=z(1,ia*4+1,j,i3)
1979 : 1521592 : s1=z(2,ia*4+1,j,i3)
1980 : :
1981 : 1521592 : r=r1 + r3
1982 : 1521592 : s=r2 + r4
1983 : 1521592 : zbr(1,ind(ia*4+1),j,i3) = r + s
1984 : 1521592 : zbr(1,ind(ia*4+3),j,i3) = r - s
1985 : 1521592 : r=r1 - r3
1986 : 1521592 : s=s2 - s4
1987 : 1521592 : zbr(1,ind(ia*4+2),j,i3) = r - s*ris
1988 : 1521592 : zbr(1,ind(ia*4+4),j,i3) = r + s*ris
1989 : 1521592 : r=s1 + s3
1990 : 1521592 : s=s2 + s4
1991 : 1521592 : zbr(2,ind(ia*4+1),j,i3) = r + s
1992 : 1521592 : zbr(2,ind(ia*4+3),j,i3) = r - s
1993 : 1521592 : r=s1 - s3
1994 : 1521592 : s=r2 - r4
1995 : 1521592 : zbr(2,ind(ia*4+2),j,i3) = r + s*ris
1996 : 1737640 : zbr(2,ind(ia*4+4),j,i3) = r - s*ris
1997 : : end do
1998 : :
1999 : : ! Second step of factor 4
2000 [ + + ]: 4778272 : do ia=1,aft(ic)-1
2001 : 4562224 : indx=ind(ia*4+1)-1
2002 : 4562224 : cr2=trig(1,indx)
2003 : 4562224 : ct2=trig(2,indx)
2004 : 4562224 : cr3=trig(1,2*indx)
2005 : 4562224 : ct3=trig(2,2*indx)
2006 : 4562224 : cr4=trig(1,3*indx)
2007 : 4562224 : ct4=trig(2,3*indx)
2008 : 4562224 : cr4=cr4/cr2
2009 : 4562224 : cr2s=cr2*ris
2010 [ + + ]: 35366928 : do j=ma,mb
2011 : 30588656 : r4=z(1,ia*4+4,j,i3) - z(2,ia*4+4,j,i3)*ct4
2012 : 30588656 : s4=z(1,ia*4+4,j,i3)*ct4 + z(2,ia*4+4,j,i3)
2013 : 30588656 : r3=z(1,ia*4+3,j,i3) - z(2,ia*4+3,j,i3)*ct3
2014 : 30588656 : s3=z(1,ia*4+3,j,i3)*ct3 + z(2,ia*4+3,j,i3)
2015 : 30588656 : r2=z(1,ia*4+2,j,i3) - z(2,ia*4+2,j,i3)*ct2
2016 : 30588656 : s2=z(1,ia*4+2,j,i3)*ct2 + z(2,ia*4+2,j,i3)
2017 : 30588656 : r1=z(1,ia*4+1,j,i3)
2018 : 30588656 : s1=z(2,ia*4+1,j,i3)
2019 : :
2020 : 30588656 : r=r1 + r3*cr3
2021 : 30588656 : s=r2 + r4*cr4
2022 : 30588656 : zbr(1,ind(ia*4+1),j,i3) = r + s*cr2
2023 : 30588656 : zbr(1,ind(ia*4+3),j,i3) = r - s*cr2
2024 : 30588656 : r=r1 - r3*cr3
2025 : 30588656 : s=s2 - s4*cr4
2026 : 30588656 : zbr(1,ind(ia*4+2),j,i3) = r - s*cr2s
2027 : 30588656 : zbr(1,ind(ia*4+4),j,i3) = r + s*cr2s
2028 : 30588656 : r=s1 + s3*cr3
2029 : 30588656 : s=s2 + s4*cr4
2030 : 30588656 : zbr(2,ind(ia*4+1),j,i3) = r + s*cr2
2031 : 30588656 : zbr(2,ind(ia*4+3),j,i3) = r - s*cr2
2032 : 30588656 : r=s1 - s3*cr3
2033 : 30588656 : s=r2 - r4*cr4
2034 : 30588656 : zbr(2,ind(ia*4+2),j,i3) = r + s*cr2s
2035 : 35150880 : zbr(2,ind(ia*4+4),j,i3) = r - s*cr2s
2036 : : end do
2037 : : end do
2038 : :
2039 : : ! Treat factor 2
2040 [ + + ]: 1917392 : else if (now(ic)==2) then
2041 : : ! radix 2
2042 : 17935413 : ia=0
2043 : :
2044 : : ! First step of factor 2
2045 [ + + ]: 17935413 : do j=ma,mb
2046 : 16236578 : r1=z(1,ia*2+1,j,i3)
2047 : 16236578 : s1=z(2,ia*2+1,j,i3)
2048 : 16236578 : r2=z(1,ia*2+2,j,i3)
2049 : 16236578 : s2=z(2,ia*2+2,j,i3)
2050 : 16236578 : zbr(1,ind(ia*2+1),j,i3) = r2 + r1
2051 : 16236578 : zbr(2,ind(ia*2+1),j,i3) = s2 + s1
2052 : 16236578 : zbr(1,ind(ia*2+2),j,i3) = -r2 + r1
2053 : 17935413 : zbr(2,ind(ia*2+2),j,i3) = -s2 + s1
2054 : : end do
2055 : :
2056 : : ! Second step of factor 2
2057 [ + + ]: 17135484 : do ia=1,aft(ic)-1
2058 : 15436649 : indx=ind(ia*2+1)-1
2059 : 15436649 : cr2=trig(1,indx)
2060 : 15436649 : ct2=trig(2,indx)
2061 [ + + ]: 174426664 : do j=ma,mb
2062 : 157291180 : r1=z(1,ia*2+1,j,i3)
2063 : 157291180 : s1=z(2,ia*2+1,j,i3)
2064 : 157291180 : r2=z(1,ia*2+2,j,i3) - z(2,ia*2+2,j,i3)*ct2
2065 : 157291180 : s2=z(1,ia*2+2,j,i3)*ct2 + z(2,ia*2+2,j,i3)
2066 : 157291180 : zbr(1,ind(ia*2+1),j,i3) = r2*cr2 + r1
2067 : 157291180 : zbr(2,ind(ia*2+1),j,i3) = s2*cr2 + s1
2068 : 157291180 : zbr(1,ind(ia*2+2),j,i3) = -r2*cr2 + r1
2069 : 172727829 : zbr(2,ind(ia*2+2),j,i3) = -s2*cr2 + s1
2070 : : end do
2071 : : end do
2072 : :
2073 : : ! Treat factor 3
2074 [ + - ]: 218557 : else if (now(ic)==3) then
2075 : : ! radix 3
2076 : : ! .5d0*sqrt(3.d0)=0.8660254037844387d0
2077 : 218557 : ia=0
2078 : 218557 : bb=ris*0.8660254037844387d0
2079 : :
2080 : : ! First step of factor 3
2081 [ + + ]: 2339496 : do j=ma,mb
2082 : 2120939 : r1=z(1,ia*3+1,j,i3)
2083 : 2120939 : s1=z(2,ia*3+1,j,i3)
2084 : 2120939 : r2=z(1,ia*3+2,j,i3)
2085 : 2120939 : s2=z(2,ia*3+2,j,i3)
2086 : 2120939 : r3=z(1,ia*3+3,j,i3)
2087 : 2120939 : s3=z(2,ia*3+3,j,i3)
2088 : 2120939 : r=r2 + r3
2089 : 2120939 : s=s2 + s3
2090 : 2120939 : zbr(1,ind(ia*3+1),j,i3) = r + r1
2091 : 2120939 : zbr(2,ind(ia*3+1),j,i3) = s + s1
2092 : 2120939 : r1=r1 - r*.5d0
2093 : 2120939 : s1=s1 - s*.5d0
2094 : 2120939 : r2=r2-r3
2095 : 2120939 : s2=s2-s3
2096 : 2120939 : zbr(1,ind(ia*3+2),j,i3) = r1 - s2*bb
2097 : 2120939 : zbr(2,ind(ia*3+2),j,i3) = s1 + r2*bb
2098 : 2120939 : zbr(1,ind(ia*3+3),j,i3) = r1 + s2*bb
2099 : 2339496 : zbr(2,ind(ia*3+3),j,i3) = s1 - r2*bb
2100 : : end do
2101 : :
2102 : : ! Second step of factor 3
2103 [ + + ]: 4195513 : do ia=1,aft(ic)-1
2104 : 3976956 : indx=ind(ia*3+1)-1
2105 : 3976956 : cr2=trig(1,indx)
2106 : 3976956 : ct2=trig(2,indx)
2107 : 3976956 : cr3=trig(1,2*indx)
2108 : 3976956 : ct3=trig(2,2*indx)
2109 : 3976956 : cr2=cr2/cr3
2110 : 3976956 : cr3p=.5d0*cr3
2111 : 3976956 : bb=ris*cr3*0.8660254037844387d0
2112 [ + + ]: 41466445 : do j=ma,mb
2113 : 37270932 : r1=z(1,ia*3+1,j,i3)
2114 : 37270932 : s1=z(2,ia*3+1,j,i3)
2115 : 37270932 : r2=z(1,ia*3+2,j,i3) - z(2,ia*3+2,j,i3)*ct2
2116 : 37270932 : s2=z(1,ia*3+2,j,i3)*ct2 + z(2,ia*3+2,j,i3)
2117 : 37270932 : r3=z(1,ia*3+3,j,i3) - z(2,ia*3+3,j,i3)*ct3
2118 : 37270932 : s3=z(1,ia*3+3,j,i3)*ct3 + z(2,ia*3+3,j,i3)
2119 : 37270932 : r=cr2*r2 + r3
2120 : 37270932 : s=cr2*s2 + s3
2121 : 37270932 : zbr(1,ind(ia*3+1),j,i3) = r*cr3 + r1
2122 : 37270932 : zbr(2,ind(ia*3+1),j,i3) = s*cr3 + s1
2123 : 37270932 : r1=r1 - r*cr3p
2124 : 37270932 : s1=s1 - s*cr3p
2125 : 37270932 : r2=cr2*r2-r3
2126 : 37270932 : s2=cr2*s2-s3
2127 : 37270932 : zbr(1,ind(ia*3+2),j,i3) = r1 - s2*bb
2128 : 37270932 : zbr(2,ind(ia*3+2),j,i3) = s1 + r2*bb
2129 : 37270932 : zbr(1,ind(ia*3+3),j,i3) = r1 + s2*bb
2130 : 41247888 : zbr(2,ind(ia*3+3),j,i3) = s1 - r2*bb
2131 : : end do
2132 : : end do
2133 : :
2134 : : ! Treat factor 5
2135 [ # # ]: 0 : else if (now(ic)==5) then
2136 : : ! radix 5
2137 : : ! sin(2.d0*pi/5.d0)
2138 : 0 : sin2=ris*0.9510565162951536d0
2139 : 0 : ia=0
2140 : :
2141 : : ! First step of factor 5
2142 [ # # ]: 0 : do j=ma,mb
2143 : 0 : r1=z(1,ia*5+1,j,i3)
2144 : 0 : s1=z(2,ia*5+1,j,i3)
2145 : 0 : r2=z(1,ia*5+2,j,i3)
2146 : 0 : s2=z(2,ia*5+2,j,i3)
2147 : 0 : r3=z(1,ia*5+3,j,i3)
2148 : 0 : s3=z(2,ia*5+3,j,i3)
2149 : 0 : r4=z(1,ia*5+4,j,i3)
2150 : 0 : s4=z(2,ia*5+4,j,i3)
2151 : 0 : r5=z(1,ia*5+5,j,i3)
2152 : 0 : s5=z(2,ia*5+5,j,i3)
2153 : 0 : r25 = r2 + r5
2154 : 0 : r34 = r3 + r4
2155 : 0 : s25 = s2 - s5
2156 : 0 : s34 = s3 - s4
2157 : 0 : zbr(1,ind(ia*5+1),j,i3) = r1 + r25 + r34
2158 : 0 : r = r1 + cos2*r25 + cos4*r34
2159 : 0 : s = s25 + sin42*s34
2160 : 0 : zbr(1,ind(ia*5+2),j,i3) = r - sin2*s
2161 : 0 : zbr(1,ind(ia*5+5),j,i3) = r + sin2*s
2162 : 0 : r = r1 + cos4*r25 + cos2*r34
2163 : 0 : s = sin42*s25 - s34
2164 : 0 : zbr(1,ind(ia*5+3),j,i3) = r - sin2*s
2165 : 0 : zbr(1,ind(ia*5+4),j,i3) = r + sin2*s
2166 : 0 : r25 = r2 - r5
2167 : 0 : r34 = r3 - r4
2168 : 0 : s25 = s2 + s5
2169 : 0 : s34 = s3 + s4
2170 : 0 : zbr(2,ind(ia*5+1),j,i3) = s1 + s25 + s34
2171 : 0 : r = s1 + cos2*s25 + cos4*s34
2172 : 0 : s = r25 + sin42*r34
2173 : 0 : zbr(2,ind(ia*5+2),j,i3) = r + sin2*s
2174 : 0 : zbr(2,ind(ia*5+5),j,i3) = r - sin2*s
2175 : 0 : r = s1 + cos4*s25 + cos2*s34
2176 : 0 : s = sin42*r25 - r34
2177 : 0 : zbr(2,ind(ia*5+3),j,i3) = r + sin2*s
2178 : 0 : zbr(2,ind(ia*5+4),j,i3) = r - sin2*s
2179 : : end do
2180 : :
2181 : : ! Second step of factor 5
2182 [ # # ]: 0 : do ia=1,aft(ic)-1
2183 : 0 : indx=ind(ia*5+1)-1
2184 : 0 : cr2=trig(1,indx)
2185 : 0 : ct2=trig(2,indx)
2186 : 0 : cr3=trig(1,2*indx)
2187 : 0 : ct3=trig(2,2*indx)
2188 : 0 : cr4=trig(1,3*indx)
2189 : 0 : ct4=trig(2,3*indx)
2190 : 0 : cr5=trig(1,4*indx)
2191 : 0 : ct5=trig(2,4*indx)
2192 [ # # ]: 0 : do j=ma,mb
2193 : 0 : r1=z(1,ia*5+1,j,i3)
2194 : 0 : s1=z(2,ia*5+1,j,i3)
2195 : 0 : r2=cr2*(z(1,ia*5+2,j,i3) - z(2,ia*5+2,j,i3)*ct2)
2196 : 0 : s2=cr2*(z(1,ia*5+2,j,i3)*ct2 + z(2,ia*5+2,j,i3))
2197 : 0 : r3=cr3*(z(1,ia*5+3,j,i3) - z(2,ia*5+3,j,i3)*ct3)
2198 : 0 : s3=cr3*(z(1,ia*5+3,j,i3)*ct3 + z(2,ia*5+3,j,i3))
2199 : 0 : r4=z(1,ia*5+4,j,i3) - z(2,ia*5+4,j,i3)*ct4
2200 : 0 : s4=z(1,ia*5+4,j,i3)*ct4 + z(2,ia*5+4,j,i3)
2201 : 0 : r5=z(1,ia*5+5,j,i3) - z(2,ia*5+5,j,i3)*ct5
2202 : 0 : s5=z(1,ia*5+5,j,i3)*ct5 + z(2,ia*5+5,j,i3)
2203 : 0 : r25 = r2 + r5*cr5
2204 : 0 : r34 = r3 + r4*cr4
2205 : 0 : s25 = s2 - s5*cr5
2206 : 0 : s34 = s3 - s4*cr4
2207 : 0 : zbr(1,ind(ia*5+1),j,i3) = r1 + r25 + r34
2208 : 0 : r = r1 + cos2*r25 + cos4*r34
2209 : 0 : s = s25 + sin42*s34
2210 : 0 : zbr(1,ind(ia*5+2),j,i3) = r - sin2*s
2211 : 0 : zbr(1,ind(ia*5+5),j,i3) = r + sin2*s
2212 : 0 : r = r1 + cos4*r25 + cos2*r34
2213 : 0 : s = sin42*s25 - s34
2214 : 0 : zbr(1,ind(ia*5+3),j,i3) = r - sin2*s
2215 : 0 : zbr(1,ind(ia*5+4),j,i3) = r + sin2*s
2216 : 0 : r25 = r2 - r5*cr5
2217 : 0 : r34 = r3 - r4*cr4
2218 : 0 : s25 = s2 + s5*cr5
2219 : 0 : s34 = s3 + s4*cr4
2220 : 0 : zbr(2,ind(ia*5+1),j,i3) = s1 + s25 + s34
2221 : 0 : r = s1 + cos2*s25 + cos4*s34
2222 : 0 : s = r25 + sin42*r34
2223 : 0 : zbr(2,ind(ia*5+2),j,i3) = r + sin2*s
2224 : 0 : zbr(2,ind(ia*5+5),j,i3) = r - sin2*s
2225 : 0 : r = s1 + cos4*s25 + cos2*s34
2226 : 0 : s = sin42*r25 - r34
2227 : 0 : zbr(2,ind(ia*5+3),j,i3) = r + sin2*s
2228 : 0 : zbr(2,ind(ia*5+4),j,i3) = r - sin2*s
2229 : : end do
2230 : : end do
2231 : :
2232 : : else
2233 : : ! All factors treated
2234 : 0 : ABI_BUG('called with factors other than 2, 3, and 5')
2235 : : end if
2236 : :
2237 : : ! ---------------------------------------------------------------
2238 : :
2239 : : end do ! do i3=1,n3
2240 : : end do ! do jj=1,n2,lot
2241 : : !$OMP END PARALLEL DO
2242 : :
2243 : 281529 : end subroutine sg_fftx
2244 : : !!***
2245 : :
2246 : : !----------------------------------------------------------------------
2247 : :
2248 : : !!****f* m_sgfft/sg_ffty
2249 : : !! NAME
2250 : : !! sg_ffty
2251 : : !!
2252 : : !! FUNCTION
2253 : : !! This subroutine is called by the 3-dimensional fft to conduct the
2254 : : !! "y" transforms for all x and z.
2255 : : !!
2256 : : !! INPUTS
2257 : : !! fftcache=size of the cache (kB)
2258 : : !! mfac = maximum number of factors in 1D FFTs
2259 : : !! mg = maximum length of 1D FFTs
2260 : : !! nd1=first dimension of (complex) arrays z and zbr (treated as real within
2261 : : !! this subroutine)
2262 : : !! nd2=second dimension of (complex) arrays z and zbr (treated as real within
2263 : : !! this subroutine)
2264 : : !! nd3=third dimension of (complex) arrays z and zbr (treated as real within
2265 : : !! this subroutine)
2266 : : !! n1i=lower i1 index, used for blocking : the do-loop will be i1=n1i,n1
2267 : : !! put to 1 for usual ffty
2268 : : !! n1=upper i1 index, used for blocking, put usual n1 for usual ffty
2269 : : !! n3i=lower i3 index, used for blocking : the do-loop will be i3=n3i,n3
2270 : : !! put to 1 for usual ffty
2271 : : !! n3=upper i3 index, used for blocking, put usual n3 for usual ffty
2272 : : !! z(2,nd1,nd2,nd3)=INPUT array; destroyed by transformation
2273 : : !! trig, aft, now, bef, ind=provided by previous call to ctrig
2274 : : !! Note that in this routine (and in ctrig) the values in array trig are
2275 : : !! actually cos and tan, not cos and sin. Use of tan allows advantageous
2276 : : !! use of FMA on the ibm rs6000.
2277 : : !! ris=sign of exponential in transform (should be 1 or -1; real)
2278 : : !! ic=number of (radix) factors of x transform length (from ctrig)
2279 : : !!
2280 : : !! OUTPUT
2281 : : !! zbr(2,nd1,nd2,nd3)=OUTPUT transformed array; no scaling applied
2282 : : !!
2283 : : !! TODO
2284 : : !! Use latex for the equation above
2285 : : !!
2286 : : !! SOURCE
2287 : :
2288 : 39264765 : subroutine sg_ffty(fftcache,mfac,mg,nd1,nd2,nd3,n1i,n1,n3i,n3,&
2289 : 39264765 : & z,zbr,trig,aft,now,bef,ris,ind,ic)
2290 : :
2291 : : !Arguments ------------------------------------
2292 : : !Dimensions of aft, now, bef, ind, and trig should agree with
2293 : : !those in subroutine ctrig.
2294 : : !scalars
2295 : : integer,intent(in) :: fftcache,ic,mfac,mg,n1,n1i,n3,n3i,nd1,nd2,nd3
2296 : : real(dp),intent(in) :: ris
2297 : : !arrays
2298 : : integer,intent(in) :: aft(mfac),bef(mfac),ind(mg),now(mfac)
2299 : : real(dp),intent(in) :: trig(2,mg)
2300 : : real(dp),intent(inout) :: z(2,nd1,nd2,nd3),zbr(2,nd1,nd2,nd3)
2301 : :
2302 : : !Local variables-------------------------------
2303 : : !scalars
2304 : : integer :: i,ia,ib,indx,j1,j2,ntb
2305 : : real(dp),parameter :: cos2=0.3090169943749474d0 !cos(2.d0*pi/5.d0)
2306 : : real(dp),parameter :: cos4=-0.8090169943749474d0 !cos(4.d0*pi/5.d0)
2307 : : real(dp),parameter :: sin42=0.6180339887498948d0 !sin(4.d0*pi/5.d0)/sin(2.d0*pi/5.d0)
2308 : : real(dp) :: bb,cr2,cr2s,cr3,cr3p,cr4,cr5,ct2,ct3,ct4,ct5
2309 : : real(dp) :: r,r1,r2,r25,r3,r34,r4,r5,s,sin2,s1,s2,s25,s3,s34,s4,s5
2310 : :
2311 : : ! *************************************************************************
2312 : :
2313 [ - + ]: 39264765 : if (fftcache<0) then
2314 : 0 : ABI_ERROR('fftcache must be positive')
2315 : : end if
2316 : :
2317 : : !Outer loop over z planes (j2)--note range from n3i to n3
2318 : :
2319 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(aft,bef,ic,ind,n1,n1i,n3,n3i,now,ris,trig,z,zbr)
2320 [ + + ]: 79867040 : do j2=n3i,n3
2321 : :
2322 : : ! Direct transformation
2323 [ + + ]: 95595904 : do i=1,ic-1
2324 : 54993629 : ntb=now(i)*bef(i)
2325 : :
2326 : : ! Treat radix 4
2327 [ + + ]: 95595904 : if (now(i)==4) then
2328 : 60072359 : ia=0
2329 : :
2330 : : ! First step of radix 4
2331 [ + + ]: 60072359 : do ib=1,bef(i)
2332 : : ! Inner loop over all x values (j1) -- note range from n1i to n1
2333 : : ! y transform is performed for this range of x values repeatedly
2334 : : ! below
2335 : :
2336 [ + + ]: 873771999 : do j1=n1i,n1
2337 : 813699640 : r4=z(1,j1,ia*ntb+3*bef(i)+ib,j2)
2338 : 813699640 : s4=z(2,j1,ia*ntb+3*bef(i)+ib,j2)
2339 : 813699640 : r3=z(1,j1,ia*ntb+2*bef(i)+ib,j2)
2340 : 813699640 : s3=z(2,j1,ia*ntb+2*bef(i)+ib,j2)
2341 : 813699640 : r2=z(1,j1,ia*ntb+bef(i)+ib,j2)
2342 : 813699640 : s2=z(2,j1,ia*ntb+bef(i)+ib,j2)
2343 : 813699640 : r1=z(1,j1,ia*ntb+ib,j2)
2344 : 813699640 : s1=z(2,j1,ia*ntb+ib,j2)
2345 : :
2346 : 813699640 : r=r1 + r3
2347 : 813699640 : s=r2 + r4
2348 : 813699640 : z(1,j1,ia*ntb+ib,j2) = r + s
2349 : 813699640 : z(1,j1,ia*ntb+2*bef(i)+ib,j2) = r - s
2350 : 813699640 : r=r1 - r3
2351 : 813699640 : s=s2 - s4
2352 : 813699640 : z(1,j1,ia*ntb+bef(i)+ib,j2) = r - s*ris
2353 : 813699640 : z(1,j1,ia*ntb+3*bef(i)+ib,j2) = r + s*ris
2354 : 813699640 : r=s1 + s3
2355 : 813699640 : s=s2 + s4
2356 : 813699640 : z(2,j1,ia*ntb+ib,j2) = r + s
2357 : 813699640 : z(2,j1,ia*ntb+2*bef(i)+ib,j2) = r - s
2358 : 813699640 : r=s1 - s3
2359 : 813699640 : s=r2 - r4
2360 : 813699640 : z(2,j1,ia*ntb+bef(i)+ib,j2) = r + s*ris
2361 : 862573978 : z(2,j1,ia*ntb+3*bef(i)+ib,j2) = r - s*ris
2362 : : end do ! j1
2363 : : end do ! ib
2364 : :
2365 : : ! Second step of radix 4
2366 [ + + ]: 13015147 : do ia=1,aft(i)-1
2367 : 1817126 : indx=ind(ia*4*bef(i)+1)-1
2368 : 1817126 : indx=indx*bef(i)
2369 : 1817126 : cr2=trig(1,indx)
2370 : 1817126 : ct2=trig(2,indx)
2371 : 1817126 : cr3=trig(1,2*indx)
2372 : 1817126 : ct3=trig(2,2*indx)
2373 : 1817126 : cr4=trig(1,3*indx)
2374 : 1817126 : ct4=trig(2,3*indx)
2375 : 1817126 : cr4=cr4/cr2
2376 : 1817126 : cr2s=cr2*ris
2377 [ + + ]: 16770479 : do ib=1,bef(i)
2378 : : ! Range of x array again (also appears many times below)
2379 [ + + ]: 35244860 : do j1=n1i,n1
2380 : : r4=z(1,j1,ia*ntb+3*bef(i)+ib,j2) - &
2381 : 29672402 : & z(2,j1,ia*ntb+3*bef(i)+ib,j2)*ct4
2382 : : s4=z(1,j1,ia*ntb+3*bef(i)+ib,j2)*ct4 + &
2383 : 29672402 : & z(2,j1,ia*ntb+3*bef(i)+ib,j2)
2384 : : r3=z(1,j1,ia*ntb+2*bef(i)+ib,j2) - &
2385 : 29672402 : & z(2,j1,ia*ntb+2*bef(i)+ib,j2)*ct3
2386 : : s3=z(1,j1,ia*ntb+2*bef(i)+ib,j2)*ct3 + &
2387 : 29672402 : & z(2,j1,ia*ntb+2*bef(i)+ib,j2)
2388 : : r2=z(1,j1,ia*ntb+bef(i)+ib,j2) - &
2389 : 29672402 : & z(2,j1,ia*ntb+bef(i)+ib,j2)*ct2
2390 : : s2=z(1,j1,ia*ntb+bef(i)+ib,j2)*ct2 + &
2391 : 29672402 : & z(2,j1,ia*ntb+bef(i)+ib,j2)
2392 : 29672402 : r1=z(1,j1,ia*ntb+ib,j2)
2393 : 29672402 : s1=z(2,j1,ia*ntb+ib,j2)
2394 : :
2395 : 29672402 : r=r1 + r3*cr3
2396 : 29672402 : s=r2 + r4*cr4
2397 : 29672402 : z(1,j1,ia*ntb+ib,j2) = r + s*cr2
2398 : 29672402 : z(1,j1,ia*ntb+2*bef(i)+ib,j2) = r - s*cr2
2399 : 29672402 : r=r1 - r3*cr3
2400 : 29672402 : s=s2 - s4*cr4
2401 : 29672402 : z(1,j1,ia*ntb+bef(i)+ib,j2) = r - s*cr2s
2402 : 29672402 : z(1,j1,ia*ntb+3*bef(i)+ib,j2) = r + s*cr2s
2403 : 29672402 : r=s1 + s3*cr3
2404 : 29672402 : s=s2 + s4*cr4
2405 : 29672402 : z(2,j1,ia*ntb+ib,j2) = r + s*cr2
2406 : 29672402 : z(2,j1,ia*ntb+2*bef(i)+ib,j2) = r - s*cr2
2407 : 29672402 : r=s1 - s3*cr3
2408 : 29672402 : s=r2 - r4*cr4
2409 : 29672402 : z(2,j1,ia*ntb+bef(i)+ib,j2) = r + s*cr2s
2410 : 33427734 : z(2,j1,ia*ntb+3*bef(i)+ib,j2) = r - s*cr2s
2411 : : end do ! j1
2412 : : end do ! ib
2413 : : end do ! ia
2414 : :
2415 : : ! Treat radix 2
2416 [ - + ]: 43795608 : else if (now(i)==2) then
2417 : 0 : ia=0
2418 : :
2419 : : ! First step of radix 2
2420 [ # # ]: 0 : do ib=1,bef(i)
2421 [ # # ]: 0 : do j1=n1i,n1
2422 : 0 : r1=z(1,j1,ia*ntb+ib,j2)
2423 : 0 : s1=z(2,j1,ia*ntb+ib,j2)
2424 : 0 : r2=z(1,j1,ia*ntb+bef(i)+ib,j2)
2425 : 0 : s2=z(2,j1,ia*ntb+bef(i)+ib,j2)
2426 : 0 : z(1,j1,ia*ntb+ib,j2) = r2 + r1
2427 : 0 : z(2,j1,ia*ntb+ib,j2) = s2 + s1
2428 : 0 : z(1,j1,ia*ntb+bef(i)+ib,j2) = -r2 + r1
2429 : 0 : z(2,j1,ia*ntb+bef(i)+ib,j2) = -s2 + s1
2430 : : end do
2431 : : end do
2432 : :
2433 : : ! Second step of radix 2
2434 [ # # ]: 0 : do ia=1,aft(i)-1
2435 : 0 : indx=ind(ia*2*bef(i)+1)-1
2436 : 0 : indx=indx*bef(i)
2437 : 0 : cr2=trig(1,indx)
2438 : 0 : ct2=trig(2,indx)
2439 [ # # ]: 0 : do ib=1,bef(i)
2440 [ # # ]: 0 : do j1=n1i,n1
2441 : 0 : r1=z(1,j1,ia*ntb+ib,j2)
2442 : 0 : s1=z(2,j1,ia*ntb+ib,j2)
2443 : : r2=z(1,j1,ia*ntb+bef(i)+ib,j2) - &
2444 : 0 : & z(2,j1,ia*ntb+bef(i)+ib,j2)*ct2
2445 : : s2=z(1,j1,ia*ntb+bef(i)+ib,j2)*ct2 + &
2446 : 0 : & z(2,j1,ia*ntb+bef(i)+ib,j2)
2447 : 0 : z(1,j1,ia*ntb+ib,j2) = r2*cr2 + r1
2448 : 0 : z(2,j1,ia*ntb+ib,j2) = s2*cr2 + s1
2449 : 0 : z(1,j1,ia*ntb+bef(i)+ib,j2) = -r2*cr2 + r1
2450 : 0 : z(2,j1,ia*ntb+bef(i)+ib,j2) = -s2*cr2 + s1
2451 : : end do
2452 : : end do
2453 : : end do
2454 : :
2455 : : ! Treat radix 3
2456 [ + + ]: 43795608 : else if (now(i)==3) then
2457 : : ! .5d0*sqrt(3.d0)=0.8660254037844387d0
2458 : 23786181 : ia=0
2459 : 23786181 : bb=ris*0.8660254037844387d0
2460 : :
2461 : : ! First step of radix 3
2462 [ + + ]: 112029921 : do ib=1,bef(i)
2463 [ + + ]: 1644685107 : do j1=n1i,n1
2464 : 1532655186 : r1=z(1,j1,ia*ntb+ib,j2)
2465 : 1532655186 : s1=z(2,j1,ia*ntb+ib,j2)
2466 : 1532655186 : r2=z(1,j1,ia*ntb+bef(i)+ib,j2)
2467 : 1532655186 : s2=z(2,j1,ia*ntb+bef(i)+ib,j2)
2468 : 1532655186 : r3=z(1,j1,ia*ntb+2*bef(i)+ib,j2)
2469 : 1532655186 : s3=z(2,j1,ia*ntb+2*bef(i)+ib,j2)
2470 : 1532655186 : r=r2 + r3
2471 : 1532655186 : s=s2 + s3
2472 : 1532655186 : z(1,j1,ia*ntb+ib,j2) = r + r1
2473 : 1532655186 : z(2,j1,ia*ntb+ib,j2) = s + s1
2474 : 1532655186 : r1=r1 - r*.5d0
2475 : 1532655186 : s1=s1 - s*.5d0
2476 : 1532655186 : r2=r2-r3
2477 : 1532655186 : s2=s2-s3
2478 : 1532655186 : z(1,j1,ia*ntb+bef(i)+ib,j2) = r1 - s2*bb
2479 : 1532655186 : z(2,j1,ia*ntb+bef(i)+ib,j2) = s1 + r2*bb
2480 : 1532655186 : z(1,j1,ia*ntb+2*bef(i)+ib,j2) = r1 + s2*bb
2481 : 1620898926 : z(2,j1,ia*ntb+2*bef(i)+ib,j2) = s1 - r2*bb
2482 : : end do
2483 : : end do
2484 : :
2485 : : ! Second step of radix 3
2486 [ + + ]: 55333284 : do ia=1,aft(i)-1
2487 : 31547103 : indx=ind(ia*3*bef(i)+1)-1
2488 : 31547103 : indx=indx*bef(i)
2489 : 31547103 : cr2=trig(1,indx)
2490 : 31547103 : ct2=trig(2,indx)
2491 : 31547103 : cr3=trig(1,2*indx)
2492 : 31547103 : ct3=trig(2,2*indx)
2493 : 31547103 : cr2=cr2/cr3
2494 : 31547103 : cr3p=.5d0*cr3
2495 : 31547103 : bb=ris*cr3*0.8660254037844387d0
2496 [ + + ]: 119288394 : do ib=1,bef(i)
2497 [ + + ]: 1362709011 : do j1=n1i,n1
2498 : 1267206798 : r1=z(1,j1,ia*ntb+ib,j2)
2499 : 1267206798 : s1=z(2,j1,ia*ntb+ib,j2)
2500 : : r2=z(1,j1,ia*ntb+bef(i)+ib,j2) - &
2501 : 1267206798 : & z(2,j1,ia*ntb+bef(i)+ib,j2)*ct2
2502 : : s2=z(1,j1,ia*ntb+bef(i)+ib,j2)*ct2 + &
2503 : 1267206798 : & z(2,j1,ia*ntb+bef(i)+ib,j2)
2504 : : r3=z(1,j1,ia*ntb+2*bef(i)+ib,j2) - &
2505 : 1267206798 : & z(2,j1,ia*ntb+2*bef(i)+ib,j2)*ct3
2506 : : s3=z(1,j1,ia*ntb+2*bef(i)+ib,j2)*ct3 + &
2507 : 1267206798 : & z(2,j1,ia*ntb+2*bef(i)+ib,j2)
2508 : 1267206798 : r=cr2*r2 + r3
2509 : 1267206798 : s=cr2*s2 + s3
2510 : 1267206798 : z(1,j1,ia*ntb+ib,j2) = r*cr3 + r1
2511 : 1267206798 : z(2,j1,ia*ntb+ib,j2) = s*cr3 + s1
2512 : 1267206798 : r1=r1 - r*cr3p
2513 : 1267206798 : s1=s1 - s*cr3p
2514 : 1267206798 : r2=cr2*r2-r3
2515 : 1267206798 : s2=cr2*s2-s3
2516 : 1267206798 : z(1,j1,ia*ntb+bef(i)+ib,j2) = r1 - s2*bb
2517 : 1267206798 : z(2,j1,ia*ntb+bef(i)+ib,j2) = s1 + r2*bb
2518 : 1267206798 : z(1,j1,ia*ntb+2*bef(i)+ib,j2) = r1 + s2*bb
2519 : 1331161908 : z(2,j1,ia*ntb+2*bef(i)+ib,j2) = s1 - r2*bb
2520 : : end do
2521 : : end do
2522 : : end do
2523 : :
2524 : : ! Treat radix 5
2525 [ + - ]: 20009427 : else if (now(i)==5) then
2526 : : ! sin(2.d0*pi/5.d0)
2527 : 20009427 : sin2=ris*0.9510565162951536d0
2528 : 20009427 : ia=0
2529 : :
2530 : : ! First step of radix 5
2531 [ + + ]: 84458420 : do ib=1,bef(i)
2532 [ + + ]: 1127923158 : do j1=n1i,n1
2533 : 1043464738 : r1=z(1,j1,ia*ntb+ib,j2)
2534 : 1043464738 : s1=z(2,j1,ia*ntb+ib,j2)
2535 : 1043464738 : r2=z(1,j1,ia*ntb+bef(i)+ib,j2)
2536 : 1043464738 : s2=z(2,j1,ia*ntb+bef(i)+ib,j2)
2537 : 1043464738 : r3=z(1,j1,ia*ntb+2*bef(i)+ib,j2)
2538 : 1043464738 : s3=z(2,j1,ia*ntb+2*bef(i)+ib,j2)
2539 : 1043464738 : r4=z(1,j1,ia*ntb+3*bef(i)+ib,j2)
2540 : 1043464738 : s4=z(2,j1,ia*ntb+3*bef(i)+ib,j2)
2541 : 1043464738 : r5=z(1,j1,ia*ntb+4*bef(i)+ib,j2)
2542 : 1043464738 : s5=z(2,j1,ia*ntb+4*bef(i)+ib,j2)
2543 : 1043464738 : r25 = r2 + r5
2544 : 1043464738 : r34 = r3 + r4
2545 : 1043464738 : s25 = s2 - s5
2546 : 1043464738 : s34 = s3 - s4
2547 : 1043464738 : z(1,j1,ia*ntb+ib,j2) = r1 + r25 + r34
2548 : 1043464738 : r = r1 + cos2*r25 + cos4*r34
2549 : 1043464738 : s = s25 + sin42*s34
2550 : 1043464738 : z(1,j1,ia*ntb+bef(i)+ib,j2) = r - sin2*s
2551 : 1043464738 : z(1,j1,ia*ntb+4*bef(i)+ib,j2) = r + sin2*s
2552 : 1043464738 : r = r1 + cos4*r25 + cos2*r34
2553 : 1043464738 : s = sin42*s25 - s34
2554 : 1043464738 : z(1,j1,ia*ntb+2*bef(i)+ib,j2) = r - sin2*s
2555 : 1043464738 : z(1,j1,ia*ntb+3*bef(i)+ib,j2) = r + sin2*s
2556 : 1043464738 : r25 = r2 - r5
2557 : 1043464738 : r34 = r3 - r4
2558 : 1043464738 : s25 = s2 + s5
2559 : 1043464738 : s34 = s3 + s4
2560 : 1043464738 : z(2,j1,ia*ntb+ib,j2) = s1 + s25 + s34
2561 : 1043464738 : r = s1 + cos2*s25 + cos4*s34
2562 : 1043464738 : s = r25 + sin42*r34
2563 : 1043464738 : z(2,j1,ia*ntb+bef(i)+ib,j2) = r + sin2*s
2564 : 1043464738 : z(2,j1,ia*ntb+4*bef(i)+ib,j2) = r - sin2*s
2565 : 1043464738 : r = s1 + cos4*s25 + cos2*s34
2566 : 1043464738 : s = sin42*r25 - r34
2567 : 1043464738 : z(2,j1,ia*ntb+2*bef(i)+ib,j2) = r + sin2*s
2568 : 1107913731 : z(2,j1,ia*ntb+3*bef(i)+ib,j2) = r - sin2*s
2569 : : end do
2570 : : end do
2571 : :
2572 : : ! Second step of radix 5
2573 [ + + ]: 20487723 : do ia=1,aft(i)-1
2574 : 478296 : indx=ind(ia*5*bef(i)+1)-1
2575 : 478296 : indx=indx*bef(i)
2576 : 478296 : cr2=trig(1,indx)
2577 : 478296 : ct2=trig(2,indx)
2578 : 478296 : cr3=trig(1,2*indx)
2579 : 478296 : ct3=trig(2,2*indx)
2580 : 478296 : cr4=trig(1,3*indx)
2581 : 478296 : ct4=trig(2,3*indx)
2582 : 478296 : cr5=trig(1,4*indx)
2583 : 478296 : ct5=trig(2,4*indx)
2584 [ + + ]: 22328107 : do ib=1,bef(i)
2585 [ + + ]: 66632024 : do j1=n1i,n1
2586 : 64313344 : r1=z(1,j1,ia*ntb+ib,j2)
2587 : 64313344 : s1=z(2,j1,ia*ntb+ib,j2)
2588 : : r2=cr2*(z(1,j1,ia*ntb+bef(i)+ib,j2) - &
2589 : 64313344 : & z(2,j1,ia*ntb+bef(i)+ib,j2)*ct2)
2590 : : s2=cr2*(z(1,j1,ia*ntb+bef(i)+ib,j2)*ct2 + &
2591 : 64313344 : & z(2,j1,ia*ntb+bef(i)+ib,j2))
2592 : : r3=cr3*(z(1,j1,ia*ntb+2*bef(i)+ib,j2) - &
2593 : 64313344 : & z(2,j1,ia*ntb+2*bef(i)+ib,j2)*ct3)
2594 : : s3=cr3*(z(1,j1,ia*ntb+2*bef(i)+ib,j2)*ct3 + &
2595 : 64313344 : & z(2,j1,ia*ntb+2*bef(i)+ib,j2))
2596 : : r4=z(1,j1,ia*ntb+3*bef(i)+ib,j2) - &
2597 : 64313344 : & z(2,j1,ia*ntb+3*bef(i)+ib,j2)*ct4
2598 : : s4=z(1,j1,ia*ntb+3*bef(i)+ib,j2)*ct4 + &
2599 : 64313344 : & z(2,j1,ia*ntb+3*bef(i)+ib,j2)
2600 : : r5=z(1,j1,ia*ntb+4*bef(i)+ib,j2) - &
2601 : 64313344 : & z(2,j1,ia*ntb+4*bef(i)+ib,j2)*ct5
2602 : : s5=z(1,j1,ia*ntb+4*bef(i)+ib,j2)*ct5 + &
2603 : 64313344 : & z(2,j1,ia*ntb+4*bef(i)+ib,j2)
2604 : 64313344 : r25 = r2 + r5*cr5
2605 : 64313344 : r34 = r3 + r4*cr4
2606 : 64313344 : s25 = s2 - s5*cr5
2607 : 64313344 : s34 = s3 - s4*cr4
2608 : 64313344 : z(1,j1,ia*ntb+ib,j2) = r1 + r25 + r34
2609 : 64313344 : r = r1 + cos2*r25 + cos4*r34
2610 : 64313344 : s = s25 + sin42*s34
2611 : 64313344 : z(1,j1,ia*ntb+bef(i)+ib,j2) = r - sin2*s
2612 : 64313344 : z(1,j1,ia*ntb+4*bef(i)+ib,j2) = r + sin2*s
2613 : 64313344 : r = r1 + cos4*r25 + cos2*r34
2614 : 64313344 : s = sin42*s25 - s34
2615 : 64313344 : z(1,j1,ia*ntb+2*bef(i)+ib,j2) = r - sin2*s
2616 : 64313344 : z(1,j1,ia*ntb+3*bef(i)+ib,j2) = r + sin2*s
2617 : 64313344 : r25 = r2 - r5*cr5
2618 : 64313344 : r34 = r3 - r4*cr4
2619 : 64313344 : s25 = s2 + s5*cr5
2620 : 64313344 : s34 = s3 + s4*cr4
2621 : 64313344 : z(2,j1,ia*ntb+ib,j2) = s1 + s25 + s34
2622 : 64313344 : r = s1 + cos2*s25 + cos4*s34
2623 : 64313344 : s = r25 + sin42*r34
2624 : 64313344 : z(2,j1,ia*ntb+bef(i)+ib,j2) = r + sin2*s
2625 : 64313344 : z(2,j1,ia*ntb+4*bef(i)+ib,j2) = r - sin2*s
2626 : 64313344 : r = s1 + cos4*s25 + cos2*s34
2627 : 64313344 : s = sin42*r25 - r34
2628 : 64313344 : z(2,j1,ia*ntb+2*bef(i)+ib,j2) = r + sin2*s
2629 : 66153728 : z(2,j1,ia*ntb+3*bef(i)+ib,j2) = r - sin2*s
2630 : : end do
2631 : : end do
2632 : : end do
2633 : :
2634 : : else
2635 : : ! All radices treated
2636 : 0 : ABI_BUG('called with factors other than 2, 3, and 5')
2637 : : end if
2638 : :
2639 : : end do
2640 : :
2641 : : ! ---------------------------------------------------------------
2642 : :
2643 : : ! bitreversal
2644 : :
2645 : : ! Treat radix 4
2646 [ + + ]: 79867040 : if (now(ic)==4) then
2647 : 5138399 : ia=0
2648 : :
2649 : : ! First step of radix 4
2650 [ + + ]: 92640533 : do j1=n1i,n1
2651 : 87502134 : r4=z(1,j1,ia*4+4,j2)
2652 : 87502134 : s4=z(2,j1,ia*4+4,j2)
2653 : 87502134 : r3=z(1,j1,ia*4+3,j2)
2654 : 87502134 : s3=z(2,j1,ia*4+3,j2)
2655 : 87502134 : r2=z(1,j1,ia*4+2,j2)
2656 : 87502134 : s2=z(2,j1,ia*4+2,j2)
2657 : 87502134 : r1=z(1,j1,ia*4+1,j2)
2658 : 87502134 : s1=z(2,j1,ia*4+1,j2)
2659 : :
2660 : 87502134 : r=r1 + r3
2661 : 87502134 : s=r2 + r4
2662 : 87502134 : zbr(1,j1,ind(ia*4+1),j2) = r + s
2663 : 87502134 : zbr(1,j1,ind(ia*4+3),j2) = r - s
2664 : 87502134 : r=r1 - r3
2665 : 87502134 : s=s2 - s4
2666 : 87502134 : zbr(1,j1,ind(ia*4+2),j2) = r - s*ris
2667 : 87502134 : zbr(1,j1,ind(ia*4+4),j2) = r + s*ris
2668 : 87502134 : r=s1 + s3
2669 : 87502134 : s=s2 + s4
2670 : 87502134 : zbr(2,j1,ind(ia*4+1),j2) = r + s
2671 : 87502134 : zbr(2,j1,ind(ia*4+3),j2) = r - s
2672 : 87502134 : r=s1 - s3
2673 : 87502134 : s=r2 - r4
2674 : 87502134 : zbr(2,j1,ind(ia*4+2),j2) = r + s*ris
2675 : 92640533 : zbr(2,j1,ind(ia*4+4),j2) = r - s*ris
2676 : : end do
2677 : :
2678 : : ! Second step of radix 4
2679 [ + + ]: 24644714 : do ia=1,aft(ic)-1
2680 : 19506315 : indx=ind(ia*4+1)-1
2681 : 19506315 : cr2=trig(1,indx)
2682 : 19506315 : ct2=trig(2,indx)
2683 : 19506315 : cr3=trig(1,2*indx)
2684 : 19506315 : ct3=trig(2,2*indx)
2685 : 19506315 : cr4=trig(1,3*indx)
2686 : 19506315 : ct4=trig(2,3*indx)
2687 : 19506315 : cr4=cr4/cr2
2688 : 19506315 : cr2s=cr2*ris
2689 [ + + ]: 398121091 : do j1=n1i,n1
2690 : 373476377 : r4=z(1,j1,ia*4+4,j2) - z(2,j1,ia*4+4,j2)*ct4
2691 : 373476377 : s4=z(1,j1,ia*4+4,j2)*ct4 + z(2,j1,ia*4+4,j2)
2692 : 373476377 : r3=z(1,j1,ia*4+3,j2) - z(2,j1,ia*4+3,j2)*ct3
2693 : 373476377 : s3=z(1,j1,ia*4+3,j2)*ct3 + z(2,j1,ia*4+3,j2)
2694 : 373476377 : r2=z(1,j1,ia*4+2,j2) - z(2,j1,ia*4+2,j2)*ct2
2695 : 373476377 : s2=z(1,j1,ia*4+2,j2)*ct2 + z(2,j1,ia*4+2,j2)
2696 : 373476377 : r1=z(1,j1,ia*4+1,j2)
2697 : 373476377 : s1=z(2,j1,ia*4+1,j2)
2698 : :
2699 : 373476377 : r=r1 + r3*cr3
2700 : 373476377 : s=r2 + r4*cr4
2701 : 373476377 : zbr(1,j1,ind(ia*4+1),j2) = r + s*cr2
2702 : 373476377 : zbr(1,j1,ind(ia*4+3),j2) = r - s*cr2
2703 : 373476377 : r=r1 - r3*cr3
2704 : 373476377 : s=s2 - s4*cr4
2705 : 373476377 : zbr(1,j1,ind(ia*4+2),j2) = r - s*cr2s
2706 : 373476377 : zbr(1,j1,ind(ia*4+4),j2) = r + s*cr2s
2707 : 373476377 : r=s1 + s3*cr3
2708 : 373476377 : s=s2 + s4*cr4
2709 : 373476377 : zbr(2,j1,ind(ia*4+1),j2) = r + s*cr2
2710 : 373476377 : zbr(2,j1,ind(ia*4+3),j2) = r - s*cr2
2711 : 373476377 : r=s1 - s3*cr3
2712 : 373476377 : s=r2 - r4*cr4
2713 : 373476377 : zbr(2,j1,ind(ia*4+2),j2) = r + s*cr2s
2714 : 392982692 : zbr(2,j1,ind(ia*4+4),j2) = r - s*cr2s
2715 : : end do
2716 : : end do
2717 : :
2718 : : ! Treat radix 2
2719 [ + + ]: 35463876 : else if (now(ic)==2) then
2720 : 15371745 : ia=0
2721 : :
2722 : : ! First step of radix 2
2723 [ + + ]: 273885279 : do j1=n1i,n1
2724 : 258513534 : r1=z(1,j1,ia*2+1,j2)
2725 : 258513534 : s1=z(2,j1,ia*2+1,j2)
2726 : 258513534 : r2=z(1,j1,ia*2+2,j2)
2727 : 258513534 : s2=z(2,j1,ia*2+2,j2)
2728 : 258513534 : zbr(1,j1,ind(ia*2+1),j2) = r2 + r1
2729 : 258513534 : zbr(2,j1,ind(ia*2+1),j2) = s2 + s1
2730 : 258513534 : zbr(1,j1,ind(ia*2+2),j2) = -r2 + r1
2731 : 273885279 : zbr(2,j1,ind(ia*2+2),j2) = -s2 + s1
2732 : : end do
2733 : :
2734 : : ! Second step of radix 2
2735 [ + + ]: 148960297 : do ia=1,aft(ic)-1
2736 : 133588552 : indx=ind(ia*2+1)-1
2737 : 133588552 : cr2=trig(1,indx)
2738 : 133588552 : ct2=trig(2,indx)
2739 [ + + ]: 2514859337 : do j1=n1i,n1
2740 : 2365899040 : r1=z(1,j1,ia*2+1,j2)
2741 : 2365899040 : s1=z(2,j1,ia*2+1,j2)
2742 : 2365899040 : r2=z(1,j1,ia*2+2,j2) - z(2,j1,ia*2+2,j2)*ct2
2743 : 2365899040 : s2=z(1,j1,ia*2+2,j2)*ct2 + z(2,j1,ia*2+2,j2)
2744 : 2365899040 : zbr(1,j1,ind(ia*2+1),j2) = r2*cr2 + r1
2745 : 2365899040 : zbr(2,j1,ind(ia*2+1),j2) = s2*cr2 + s1
2746 : 2365899040 : zbr(1,j1,ind(ia*2+2),j2) = -r2*cr2 + r1
2747 : 2499487592 : zbr(2,j1,ind(ia*2+2),j2) = -s2*cr2 + s1
2748 : : end do
2749 : : end do
2750 : :
2751 : : ! Treat radix 3
2752 [ + - ]: 20092131 : else if (now(ic)==3) then
2753 : : ! .5d0*sqrt(3.d0)=0.8660254037844387d0
2754 : 20092131 : ia=0
2755 : 20092131 : bb=ris*0.8660254037844387d0
2756 : :
2757 : : ! First step of radix 3
2758 [ + + ]: 309231633 : do j1=n1i,n1
2759 : 289139502 : r1=z(1,j1,ia*3+1,j2)
2760 : 289139502 : s1=z(2,j1,ia*3+1,j2)
2761 : 289139502 : r2=z(1,j1,ia*3+2,j2)
2762 : 289139502 : s2=z(2,j1,ia*3+2,j2)
2763 : 289139502 : r3=z(1,j1,ia*3+3,j2)
2764 : 289139502 : s3=z(2,j1,ia*3+3,j2)
2765 : 289139502 : r=r2 + r3
2766 : 289139502 : s=s2 + s3
2767 : 289139502 : zbr(1,j1,ind(ia*3+1),j2) = r + r1
2768 : 289139502 : zbr(2,j1,ind(ia*3+1),j2) = s + s1
2769 : 289139502 : r1=r1 - r*.5d0
2770 : 289139502 : s1=s1 - s*.5d0
2771 : 289139502 : r2=r2-r3
2772 : 289139502 : s2=s2-s3
2773 : 289139502 : zbr(1,j1,ind(ia*3+2),j2) = r1 - s2*bb
2774 : 289139502 : zbr(2,j1,ind(ia*3+2),j2) = s1 + r2*bb
2775 : 289139502 : zbr(1,j1,ind(ia*3+3),j2) = r1 + s2*bb
2776 : 309231633 : zbr(2,j1,ind(ia*3+3),j2) = s1 - r2*bb
2777 : : end do
2778 : :
2779 : : ! Second step of radix 3
2780 [ + + ]: 98660165 : do ia=1,aft(ic)-1
2781 : 78568034 : indx=ind(ia*3+1)-1
2782 : 78568034 : cr2=trig(1,indx)
2783 : 78568034 : ct2=trig(2,indx)
2784 : 78568034 : cr3=trig(1,2*indx)
2785 : 78568034 : ct3=trig(2,2*indx)
2786 : 78568034 : cr2=cr2/cr3
2787 : 78568034 : cr3p=.5d0*cr3
2788 : 78568034 : bb=ris*cr3*0.8660254037844387d0
2789 [ + + ]: 1250181717 : do j1=n1i,n1
2790 : 1151521552 : r1=z(1,j1,ia*3+1,j2)
2791 : 1151521552 : s1=z(2,j1,ia*3+1,j2)
2792 : 1151521552 : r2=z(1,j1,ia*3+2,j2) - z(2,j1,ia*3+2,j2)*ct2
2793 : 1151521552 : s2=z(1,j1,ia*3+2,j2)*ct2 + z(2,j1,ia*3+2,j2)
2794 : 1151521552 : r3=z(1,j1,ia*3+3,j2) - z(2,j1,ia*3+3,j2)*ct3
2795 : 1151521552 : s3=z(1,j1,ia*3+3,j2)*ct3 + z(2,j1,ia*3+3,j2)
2796 : 1151521552 : r=cr2*r2 + r3
2797 : 1151521552 : s=cr2*s2 + s3
2798 : 1151521552 : zbr(1,j1,ind(ia*3+1),j2) = r*cr3 + r1
2799 : 1151521552 : zbr(2,j1,ind(ia*3+1),j2) = s*cr3 + s1
2800 : 1151521552 : r1=r1 - r*cr3p
2801 : 1151521552 : s1=s1 - s*cr3p
2802 : 1151521552 : r2=cr2*r2-r3
2803 : 1151521552 : s2=cr2*s2-s3
2804 : 1151521552 : zbr(1,j1,ind(ia*3+2),j2) = r1 - s2*bb
2805 : 1151521552 : zbr(2,j1,ind(ia*3+2),j2) = s1 + r2*bb
2806 : 1151521552 : zbr(1,j1,ind(ia*3+3),j2) = r1 + s2*bb
2807 : 1230089586 : zbr(2,j1,ind(ia*3+3),j2) = s1 - r2*bb
2808 : : end do
2809 : : end do
2810 : :
2811 : : ! Treat radix 5
2812 [ # # ]: 0 : else if (now(ic)==5) then
2813 : : ! sin(2.d0*pi/5.d0)
2814 : 0 : sin2=ris*0.9510565162951536d0
2815 : 0 : ia=0
2816 : :
2817 : : ! First step of radix 5
2818 [ # # ]: 0 : do j1=n1i,n1
2819 : 0 : r1=z(1,j1,ia*5+1,j2)
2820 : 0 : s1=z(2,j1,ia*5+1,j2)
2821 : 0 : r2=z(1,j1,ia*5+2,j2)
2822 : 0 : s2=z(2,j1,ia*5+2,j2)
2823 : 0 : r3=z(1,j1,ia*5+3,j2)
2824 : 0 : s3=z(2,j1,ia*5+3,j2)
2825 : 0 : r4=z(1,j1,ia*5+4,j2)
2826 : 0 : s4=z(2,j1,ia*5+4,j2)
2827 : 0 : r5=z(1,j1,ia*5+5,j2)
2828 : 0 : s5=z(2,j1,ia*5+5,j2)
2829 : 0 : r25 = r2 + r5
2830 : 0 : r34 = r3 + r4
2831 : 0 : s25 = s2 - s5
2832 : 0 : s34 = s3 - s4
2833 : 0 : zbr(1,j1,ind(ia*5+1),j2) = r1 + r25 + r34
2834 : 0 : r = r1 + cos2*r25 + cos4*r34
2835 : 0 : s = s25 + sin42*s34
2836 : 0 : zbr(1,j1,ind(ia*5+2),j2) = r - sin2*s
2837 : 0 : zbr(1,j1,ind(ia*5+5),j2) = r + sin2*s
2838 : 0 : r = r1 + cos4*r25 + cos2*r34
2839 : 0 : s = sin42*s25 - s34
2840 : 0 : zbr(1,j1,ind(ia*5+3),j2) = r - sin2*s
2841 : 0 : zbr(1,j1,ind(ia*5+4),j2) = r + sin2*s
2842 : 0 : r25 = r2 - r5
2843 : 0 : r34 = r3 - r4
2844 : 0 : s25 = s2 + s5
2845 : 0 : s34 = s3 + s4
2846 : 0 : zbr(2,j1,ind(ia*5+1),j2) = s1 + s25 + s34
2847 : 0 : r = s1 + cos2*s25 + cos4*s34
2848 : 0 : s = r25 + sin42*r34
2849 : 0 : zbr(2,j1,ind(ia*5+2),j2) = r + sin2*s
2850 : 0 : zbr(2,j1,ind(ia*5+5),j2) = r - sin2*s
2851 : 0 : r = s1 + cos4*s25 + cos2*s34
2852 : 0 : s = sin42*r25 - r34
2853 : 0 : zbr(2,j1,ind(ia*5+3),j2) = r + sin2*s
2854 : 0 : zbr(2,j1,ind(ia*5+4),j2) = r - sin2*s
2855 : : end do
2856 : :
2857 : : ! Second step of radix 5
2858 [ # # ]: 0 : do ia=1,aft(ic)-1
2859 : 0 : indx=ind(ia*5+1)-1
2860 : 0 : cr2=trig(1,indx)
2861 : 0 : ct2=trig(2,indx)
2862 : 0 : cr3=trig(1,2*indx)
2863 : 0 : ct3=trig(2,2*indx)
2864 : 0 : cr4=trig(1,3*indx)
2865 : 0 : ct4=trig(2,3*indx)
2866 : 0 : cr5=trig(1,4*indx)
2867 : 0 : ct5=trig(2,4*indx)
2868 [ # # ]: 0 : do j1=n1i,n1
2869 : 0 : r1=z(1,j1,ia*5+1,j2)
2870 : 0 : s1=z(2,j1,ia*5+1,j2)
2871 : 0 : r2=cr2*(z(1,j1,ia*5+2,j2) - z(2,j1,ia*5+2,j2)*ct2)
2872 : 0 : s2=cr2*(z(1,j1,ia*5+2,j2)*ct2 + z(2,j1,ia*5+2,j2))
2873 : 0 : r3=cr3*(z(1,j1,ia*5+3,j2) - z(2,j1,ia*5+3,j2)*ct3)
2874 : 0 : s3=cr3*(z(1,j1,ia*5+3,j2)*ct3 + z(2,j1,ia*5+3,j2))
2875 : 0 : r4=z(1,j1,ia*5+4,j2) - z(2,j1,ia*5+4,j2)*ct4
2876 : 0 : s4=z(1,j1,ia*5+4,j2)*ct4 + z(2,j1,ia*5+4,j2)
2877 : 0 : r5=z(1,j1,ia*5+5,j2) - z(2,j1,ia*5+5,j2)*ct5
2878 : 0 : s5=z(1,j1,ia*5+5,j2)*ct5 + z(2,j1,ia*5+5,j2)
2879 : 0 : r25 = r2 + r5*cr5
2880 : 0 : r34 = r3 + r4*cr4
2881 : 0 : s25 = s2 - s5*cr5
2882 : 0 : s34 = s3 - s4*cr4
2883 : 0 : zbr(1,j1,ind(ia*5+1),j2) = r1 + r25 + r34
2884 : 0 : r = r1 + cos2*r25 + cos4*r34
2885 : 0 : s = s25 + sin42*s34
2886 : 0 : zbr(1,j1,ind(ia*5+2),j2) = r - sin2*s
2887 : 0 : zbr(1,j1,ind(ia*5+5),j2) = r + sin2*s
2888 : 0 : r = r1 + cos4*r25 + cos2*r34
2889 : 0 : s = sin42*s25 - s34
2890 : 0 : zbr(1,j1,ind(ia*5+3),j2) = r - sin2*s
2891 : 0 : zbr(1,j1,ind(ia*5+4),j2) = r + sin2*s
2892 : 0 : r25 = r2 - r5*cr5
2893 : 0 : r34 = r3 - r4*cr4
2894 : 0 : s25 = s2 + s5*cr5
2895 : 0 : s34 = s3 + s4*cr4
2896 : 0 : zbr(2,j1,ind(ia*5+1),j2) = s1 + s25 + s34
2897 : 0 : r = s1 + cos2*s25 + cos4*s34
2898 : 0 : s = r25 + sin42*r34
2899 : 0 : zbr(2,j1,ind(ia*5+2),j2) = r + sin2*s
2900 : 0 : zbr(2,j1,ind(ia*5+5),j2) = r - sin2*s
2901 : 0 : r = s1 + cos4*s25 + cos2*s34
2902 : 0 : s = sin42*r25 - r34
2903 : 0 : zbr(2,j1,ind(ia*5+3),j2) = r + sin2*s
2904 : 0 : zbr(2,j1,ind(ia*5+4),j2) = r - sin2*s
2905 : : end do
2906 : : end do
2907 : :
2908 : : else
2909 : : ! All radices done
2910 : : !if (now(ic) /= 1) then
2911 : 0 : ABI_BUG(sjoin("Called with factors other than 2, 3, and 5. now(ic) = ", itoa(now(ic))))
2912 : : !end if
2913 : : end if
2914 : : end do
2915 : : !$OMP END PARALLEL DO
2916 : :
2917 : 39264765 : end subroutine sg_ffty
2918 : : !!***
2919 : :
2920 : : !----------------------------------------------------------------------
2921 : :
2922 : : !!****f* m_sgfft/sg_fftz
2923 : : !! NAME
2924 : : !! sg_fftz
2925 : : !!
2926 : : !! FUNCTION
2927 : : !! This subroutine is called by the 3-dimensional fft to conduct the
2928 : : !! "z" transforms for all x and y.
2929 : : !!
2930 : : !! INPUTS
2931 : : !! mfac = maximum number of factors in 1D FFTs
2932 : : !! mg = maximum length of 1D FFTs
2933 : : !! nd1=first dimension of (complex) arrays z and zbr (treated as real within
2934 : : !! this subroutine)
2935 : : !! nd2=second dimension of (complex) arrays z and zbr (treated as real within
2936 : : !! this subroutine)
2937 : : !! nd3=third dimension of (complex) arrays z and zbr (treated as real within
2938 : : !! this subroutine)
2939 : : !! n1=actual length of x and y transforms
2940 : : !! n2i=lower i2 index, used for blocking : the do-loop will be i2=n2i,n2
2941 : : !! put to 1 for usual ffty
2942 : : !! n2=upper i2 index, used for blocking, put usual n2 for usual ffty
2943 : : !! z(2,nd1,nd2,nd3)=INPUT array; destroyed by transformation
2944 : : !! trig, aft, now, bef, ind=provided by previous call to ctrig
2945 : : !! Note that in this routine (and in ctrig) the values in array trig are
2946 : : !! actually cos and tan, not cos and sin. Use of tan allows advantageous
2947 : : !! use of FMA on the ibm rs6000.
2948 : : !! ris=sign of exponential in transform (should be 1 or -1; real)
2949 : : !! ic=number of (radix) factors of x transform length (from ctrig)
2950 : : !!
2951 : : !! OUTPUT
2952 : : !! zbr(2,nd1,nd2,nd3)=OUTPUT transformed array; no scaling applied
2953 : : !!
2954 : : !! TODO
2955 : : !! Use latex for the equation above
2956 : : !!
2957 : : !! SOURCE
2958 : :
2959 : 568051 : subroutine sg_fftz(mfac,mg,nd1,nd2,nd3,n1,n2i,n2,z,zbr,trig,aft,now,bef,ris,ind,ic)
2960 : :
2961 : : !Arguments ------------------------------------
2962 : : !Dimensions of aft, now, bef, ind, and trig should agree with
2963 : : !those in subroutine ctrig.
2964 : : !scalars
2965 : : integer,intent(in) :: ic,mfac,mg,n1,n2,n2i,nd1,nd2,nd3
2966 : : real(dp),intent(in) :: ris
2967 : : !arrays
2968 : : integer,intent(in) :: aft(mfac),bef(mfac),ind(mg),now(mfac)
2969 : : real(dp),intent(in) :: trig(2,mg)
2970 : : real(dp),intent(inout) :: z(2,nd1,nd2,nd3),zbr(2,nd1,nd2,nd3)
2971 : :
2972 : : !Local variables-------------------------------
2973 : : !scalars
2974 : : integer :: b_i,i,i2,ia,ib,indx,j,ntb
2975 : : real(dp),parameter :: cos2=0.3090169943749474d0 !cos(2.d0*pi/5.d0)
2976 : : real(dp),parameter :: cos4=-0.8090169943749474d0 !cos(4.d0*pi/5.d0)
2977 : : real(dp),parameter :: sin42=0.6180339887498948d0 !sin(4.d0*pi/5.d0)/sin(2.d0*pi/5.d0)
2978 : : real(dp) :: bb,cr2,cr2s,cr3,cr3p,cr4,cr5,ct2,ct3,ct4,ct5
2979 : : real(dp) :: r,r1,r2,r25,r3,r34,r4,r5,s,sin2,s1,s2,s25,s3,s34,s4,s5
2980 : :
2981 : : ! *************************************************************************
2982 : :
2983 : : !n12 occurs as a loop index repeated below; do z transform while
2984 : : !looping over all n12 lines of data
2985 : :
2986 : : !Direct transformation (to ic-1), bitreversal will be in second part
2987 : : !of routine
2988 : :
2989 [ + + ]: 1661615 : do i=1,ic-1
2990 : 1093564 : ntb=now(i)*bef(i)
2991 : 1093564 : b_i=bef(i)
2992 : :
2993 : : ! Treat radix 4
2994 [ + + ]: 1661615 : if (now(i)==4) then
2995 : 2428804 : ia=0
2996 : :
2997 : : ! First step of radix 4
2998 [ + + ]: 2428804 : do ib=1,b_i
2999 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3000 : : !$OMP&SHARED(b_i,ia,ib,n1,n2i,n2,ntb,ris,z)
3001 [ + + ]: 4492374 : do i2=n2i,n2
3002 [ + + ]: 41891976 : do j=1,n1
3003 : 37764836 : r4=z(1,j,i2,ia*ntb+3*b_i+ib)
3004 : 37764836 : s4=z(2,j,i2,ia*ntb+3*b_i+ib)
3005 : 37764836 : r3=z(1,j,i2,ia*ntb+2*b_i+ib)
3006 : 37764836 : s3=z(2,j,i2,ia*ntb+2*b_i+ib)
3007 : 37764836 : r2=z(1,j,i2,ia*ntb+b_i+ib)
3008 : 37764836 : s2=z(2,j,i2,ia*ntb+b_i+ib)
3009 : 37764836 : r1=z(1,j,i2,ia*ntb+ib)
3010 : 37764836 : s1=z(2,j,i2,ia*ntb+ib)
3011 : :
3012 : 37764836 : r=r1 + r3
3013 : 37764836 : s=r2 + r4
3014 : 37764836 : z(1,j,i2,ia*ntb+ib) = r + s
3015 : 37764836 : z(1,j,i2,ia*ntb+2*b_i+ib) = r - s
3016 : 37764836 : r=r1 - r3
3017 : 37764836 : s=s2 - s4
3018 : 37764836 : z(1,j,i2,ia*ntb+b_i+ib) = r - s*ris
3019 : 37764836 : z(1,j,i2,ia*ntb+3*b_i+ib) = r + s*ris
3020 : 37764836 : r=s1 + s3
3021 : 37764836 : s=s2 + s4
3022 : 37764836 : z(2,j,i2,ia*ntb+ib) = r + s
3023 : 37764836 : z(2,j,i2,ia*ntb+2*b_i+ib) = r - s
3024 : 37764836 : r=s1 - s3
3025 : 37764836 : s=r2 - r4
3026 : 37764836 : z(2,j,i2,ia*ntb+b_i+ib) = r + s*ris
3027 : 39828406 : z(2,j,i2,ia*ntb+3*b_i+ib) = r - s*ris
3028 : : end do ! j
3029 : : end do ! i2
3030 : : !$OMP END PARALLEL DO
3031 : : end do ! ib
3032 : :
3033 : : ! Second step of radix 4
3034 [ + + ]: 1054530 : do ia=1,aft(i)-1
3035 : 689296 : indx=ind(ia*4*b_i+1)-1
3036 : 689296 : indx=indx*b_i
3037 : 689296 : cr2=trig(1,indx)
3038 : 689296 : ct2=trig(2,indx)
3039 : 689296 : cr3=trig(1,2*indx)
3040 : 689296 : ct3=trig(2,2*indx)
3041 : 689296 : cr4=trig(1,3*indx)
3042 : 689296 : ct4=trig(2,3*indx)
3043 : 689296 : cr4=cr4/cr2
3044 : 689296 : cr2s=cr2*ris
3045 [ + + ]: 2899832 : do ib=1,b_i
3046 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3047 : : !$OMP&SHARED(b_i,cr2,cr3,cr4,ct2,cr2s,ct3,ct4,i,ia,ib,n1,n2i,n2,ntb,ris,z)
3048 [ + + ]: 4379900 : do i2=n2i,n2
3049 [ + + ]: 59223476 : do j=1,n1
3050 : : r4=z(1,j,i2,ia*ntb+3*b_i+ib) - &
3051 : 55532872 : & z(2,j,i2,ia*ntb+3*b_i+ib)*ct4
3052 : : s4=z(1,j,i2,ia*ntb+3*b_i+ib)*ct4 + &
3053 : 55532872 : & z(2,j,i2,ia*ntb+3*b_i+ib)
3054 : : r3=z(1,j,i2,ia*ntb+2*b_i+ib) - &
3055 : 55532872 : & z(2,j,i2,ia*ntb+2*b_i+ib)*ct3
3056 : : s3=z(1,j,i2,ia*ntb+2*b_i+ib)*ct3 + &
3057 : 55532872 : & z(2,j,i2,ia*ntb+2*b_i+ib)
3058 : : r2=z(1,j,i2,ia*ntb+b_i+ib) - &
3059 : 55532872 : & z(2,j,i2,ia*ntb+b_i+ib)*ct2
3060 : : s2=z(1,j,i2,ia*ntb+b_i+ib)*ct2 + &
3061 : 55532872 : & z(2,j,i2,ia*ntb+b_i+ib)
3062 : 55532872 : r1=z(1,j,i2,ia*ntb+ib)
3063 : 55532872 : s1=z(2,j,i2,ia*ntb+ib)
3064 : :
3065 : 55532872 : r=r1 + r3*cr3
3066 : 55532872 : s=r2 + r4*cr4
3067 : 55532872 : z(1,j,i2,ia*ntb+ib) = r + s*cr2
3068 : 55532872 : z(1,j,i2,ia*ntb+2*b_i+ib) = r - s*cr2
3069 : 55532872 : r=r1 - r3*cr3
3070 : 55532872 : s=s2 - s4*cr4
3071 : 55532872 : z(1,j,i2,ia*ntb+b_i+ib) = r - s*cr2s
3072 : 55532872 : z(1,j,i2,ia*ntb+3*b_i+ib) = r + s*cr2s
3073 : 55532872 : r=s1 + s3*cr3
3074 : 55532872 : s=s2 + s4*cr4
3075 : 55532872 : z(2,j,i2,ia*ntb+ib) = r + s*cr2
3076 : 55532872 : z(2,j,i2,ia*ntb+2*b_i+ib) = r - s*cr2
3077 : 55532872 : r=s1 - s3*cr3
3078 : 55532872 : s=r2 - r4*cr4
3079 : 55532872 : z(2,j,i2,ia*ntb+b_i+ib) = r + s*cr2s
3080 : 57378174 : z(2,j,i2,ia*ntb+3*b_i+ib) = r - s*cr2s
3081 : : end do ! j
3082 : : end do ! i2
3083 : : !$OMP END PARALLEL DO
3084 : : end do ! ib
3085 : :
3086 : : end do ! ia
3087 : :
3088 : : ! Treat radix 2
3089 [ - + ]: 728330 : else if (now(i)==2) then
3090 : 0 : ia=0
3091 : :
3092 : : ! First step of radix 2
3093 [ # # ]: 0 : do ib=1,b_i
3094 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3095 : : !$OMP&SHARED(b_i,ia,ib,n1,n2,n2i,ntb,z)
3096 [ # # ]: 0 : do i2=n2i,n2
3097 [ # # ]: 0 : do j=1,n1
3098 : 0 : r1=z(1,j,i2,ia*ntb+ib)
3099 : 0 : s1=z(2,j,i2,ia*ntb+ib)
3100 : 0 : r2=z(1,j,i2,ia*ntb+b_i+ib)
3101 : 0 : s2=z(2,j,i2,ia*ntb+b_i+ib)
3102 : 0 : z(1,j,i2,ia*ntb+ib) = r2 + r1
3103 : 0 : z(2,j,i2,ia*ntb+ib) = s2 + s1
3104 : 0 : z(1,j,i2,ia*ntb+b_i+ib) = -r2 + r1
3105 : 0 : z(2,j,i2,ia*ntb+b_i+ib) = -s2 + s1
3106 : : end do ! j
3107 : : end do ! i2
3108 : : !$OMP END PARALLEL DO
3109 : : end do ! ib
3110 : :
3111 : : ! Second step of radix 2
3112 [ # # ]: 0 : do ia=1,aft(i)-1
3113 : 0 : indx=ind(ia*2*b_i+1)-1
3114 : 0 : indx=indx*b_i
3115 : 0 : cr2=trig(1,indx)
3116 : 0 : ct2=trig(2,indx)
3117 [ # # ]: 0 : do ib=1,b_i
3118 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3119 : : !$OMP&SHARED(b_i,cr2,ct2,ia,ib,n1,n2,n2i,ntb,z)
3120 [ # # ]: 0 : do i2=n2i,n2
3121 [ # # ]: 0 : do j=1,n1
3122 : 0 : r1=z(1,j,i2,ia*ntb+ib)
3123 : 0 : s1=z(2,j,i2,ia*ntb+ib)
3124 : : r2=z(1,j,i2,ia*ntb+b_i+ib) - &
3125 : 0 : & z(2,j,i2,ia*ntb+b_i+ib)*ct2
3126 : : s2=z(1,j,i2,ia*ntb+b_i+ib)*ct2 + &
3127 : 0 : & z(2,j,i2,ia*ntb+b_i+ib)
3128 : 0 : z(1,j,i2,ia*ntb+ib) = r2*cr2 + r1
3129 : 0 : z(2,j,i2,ia*ntb+ib) = s2*cr2 + s1
3130 : 0 : z(1,j,i2,ia*ntb+b_i+ib) = -r2*cr2 + r1
3131 : 0 : z(2,j,i2,ia*ntb+b_i+ib) = -s2*cr2 + s1
3132 : : end do ! j
3133 : : end do ! i2
3134 : : !$OMP END PARALLEL DO
3135 : : end do ! ib
3136 : :
3137 : : end do ! ia
3138 : :
3139 : : ! Treat radix 3
3140 [ + + ]: 728330 : else if (now(i)==3) then
3141 : : ! .5d0*sqrt(3.d0)=0.8660254037844387d0
3142 : 341419 : ia=0
3143 : 341419 : bb=ris*0.8660254037844387d0
3144 : :
3145 : : ! First step of radix 3
3146 [ + + ]: 1633851 : do ib=1,b_i
3147 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3148 : : !$OMP&SHARED(bb,b_i,ia,ib,n1,n2,n2i,ntb,z)
3149 [ + + ]: 2926283 : do i2=n2i,n2
3150 [ + + ]: 27359760 : do j=1,n1
3151 : 24774896 : r1=z(1,j,i2,ia*ntb+ib)
3152 : 24774896 : s1=z(2,j,i2,ia*ntb+ib)
3153 : 24774896 : r2=z(1,j,i2,ia*ntb+b_i+ib)
3154 : 24774896 : s2=z(2,j,i2,ia*ntb+b_i+ib)
3155 : 24774896 : r3=z(1,j,i2,ia*ntb+2*b_i+ib)
3156 : 24774896 : s3=z(2,j,i2,ia*ntb+2*b_i+ib)
3157 : 24774896 : r=r2 + r3
3158 : 24774896 : s=s2 + s3
3159 : 24774896 : z(1,j,i2,ia*ntb+ib) = r + r1
3160 : 24774896 : z(2,j,i2,ia*ntb+ib) = s + s1
3161 : 24774896 : r1=r1 - r*.5d0
3162 : 24774896 : s1=s1 - s*.5d0
3163 : 24774896 : r2=r2-r3
3164 : 24774896 : s2=s2-s3
3165 : 24774896 : z(1,j,i2,ia*ntb+b_i+ib) = r1 - s2*bb
3166 : 24774896 : z(2,j,i2,ia*ntb+b_i+ib) = s1 + r2*bb
3167 : 24774896 : z(1,j,i2,ia*ntb+2*b_i+ib) = r1 + s2*bb
3168 : 26067328 : z(2,j,i2,ia*ntb+2*b_i+ib) = s1 - r2*bb
3169 : : end do ! j
3170 : : end do ! i2
3171 : : !$OMP END PARALLEL DO
3172 : : end do ! ib
3173 : :
3174 : : ! Second step of radix 3
3175 [ + + ]: 1304172 : do ia=1,aft(i)-1
3176 : 962753 : indx=ind(ia*3*b_i+1)-1
3177 : 962753 : indx=indx*b_i
3178 : 962753 : cr2=trig(1,indx)
3179 : 962753 : ct2=trig(2,indx)
3180 : 962753 : cr3=trig(1,2*indx)
3181 : 962753 : ct3=trig(2,2*indx)
3182 : 962753 : cr2=cr2/cr3
3183 : 962753 : cr3p=.5d0*cr3
3184 : 962753 : bb=ris*cr3*0.8660254037844387d0
3185 [ + + ]: 3741094 : do ib=1,b_i
3186 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3187 : : !$OMP&SHARED(bb,b_i,cr2,cr3,cr3p,ct2,ct3,ia,ib,n1,n2,n2i,ntb,z)
3188 [ + + ]: 5836597 : do i2=n2i,n2
3189 [ + + ]: 91060992 : do j=1,n1
3190 : 86187148 : r1=z(1,j,i2,ia*ntb+ib)
3191 : 86187148 : s1=z(2,j,i2,ia*ntb+ib)
3192 : : r2=z(1,j,i2,ia*ntb+b_i+ib) - &
3193 : 86187148 : & z(2,j,i2,ia*ntb+b_i+ib)*ct2
3194 : : s2=z(1,j,i2,ia*ntb+b_i+ib)*ct2 + &
3195 : 86187148 : & z(2,j,i2,ia*ntb+b_i+ib)
3196 : : r3=z(1,j,i2,ia*ntb+2*b_i+ib) - &
3197 : 86187148 : & z(2,j,i2,ia*ntb+2*b_i+ib)*ct3
3198 : : s3=z(1,j,i2,ia*ntb+2*b_i+ib)*ct3 + &
3199 : 86187148 : & z(2,j,i2,ia*ntb+2*b_i+ib)
3200 : 86187148 : r=cr2*r2 + r3
3201 : 86187148 : s=cr2*s2 + s3
3202 : 86187148 : z(1,j,i2,ia*ntb+ib) = r*cr3 + r1
3203 : 86187148 : z(2,j,i2,ia*ntb+ib) = s*cr3 + s1
3204 : 86187148 : r1=r1 - r*cr3p
3205 : 86187148 : s1=s1 - s*cr3p
3206 : 86187148 : r2=cr2*r2-r3
3207 : 86187148 : s2=cr2*s2-s3
3208 : 86187148 : z(1,j,i2,ia*ntb+b_i+ib) = r1 - s2*bb
3209 : 86187148 : z(2,j,i2,ia*ntb+b_i+ib) = s1 + r2*bb
3210 : 86187148 : z(1,j,i2,ia*ntb+2*b_i+ib) = r1 + s2*bb
3211 : 88624070 : z(2,j,i2,ia*ntb+2*b_i+ib) = s1 - r2*bb
3212 : : end do ! j
3213 : : end do ! i2
3214 : : !$OMP END PARALLEL DO
3215 : : end do ! ib
3216 : :
3217 : : end do ! ia
3218 : :
3219 : : ! Treat radix 5
3220 [ + - ]: 386911 : else if (now(i)==5) then
3221 : 386911 : sin2=ris*0.9510565162951536d0
3222 : 386911 : ia=0
3223 : :
3224 : : ! First step of radix 5
3225 [ + + ]: 3759098 : do ib=1,b_i
3226 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3227 : : !$OMP&SHARED(b_i,ia,ib,n1,n2,n2i,ntb,sin2,z)
3228 [ + + ]: 7131285 : do i2=n2i,n2
3229 [ + + ]: 193795733 : do j=1,n1
3230 : 187051359 : r1=z(1,j,i2,ia*ntb+ib)
3231 : 187051359 : s1=z(2,j,i2,ia*ntb+ib)
3232 : 187051359 : r2=z(1,j,i2,ia*ntb+b_i+ib)
3233 : 187051359 : s2=z(2,j,i2,ia*ntb+b_i+ib)
3234 : 187051359 : r3=z(1,j,i2,ia*ntb+2*b_i+ib)
3235 : 187051359 : s3=z(2,j,i2,ia*ntb+2*b_i+ib)
3236 : 187051359 : r4=z(1,j,i2,ia*ntb+3*b_i+ib)
3237 : 187051359 : s4=z(2,j,i2,ia*ntb+3*b_i+ib)
3238 : 187051359 : r5=z(1,j,i2,ia*ntb+4*b_i+ib)
3239 : 187051359 : s5=z(2,j,i2,ia*ntb+4*b_i+ib)
3240 : 187051359 : r25 = r2 + r5
3241 : 187051359 : r34 = r3 + r4
3242 : 187051359 : s25 = s2 - s5
3243 : 187051359 : s34 = s3 - s4
3244 : 187051359 : z(1,j,i2,ia*ntb+ib) = r1 + r25 + r34
3245 : 187051359 : r = r1 + cos2*r25 + cos4*r34
3246 : 187051359 : s = s25 + sin42*s34
3247 : 187051359 : z(1,j,i2,ia*ntb+b_i+ib) = r - sin2*s
3248 : 187051359 : z(1,j,i2,ia*ntb+4*b_i+ib) = r + sin2*s
3249 : 187051359 : r = r1 + cos4*r25 + cos2*r34
3250 : 187051359 : s = sin42*s25 - s34
3251 : 187051359 : z(1,j,i2,ia*ntb+2*b_i+ib) = r - sin2*s
3252 : 187051359 : z(1,j,i2,ia*ntb+3*b_i+ib) = r + sin2*s
3253 : 187051359 : r25 = r2 - r5
3254 : 187051359 : r34 = r3 - r4
3255 : 187051359 : s25 = s2 + s5
3256 : 187051359 : s34 = s3 + s4
3257 : 187051359 : z(2,j,i2,ia*ntb+ib) = s1 + s25 + s34
3258 : 187051359 : r = s1 + cos2*s25 + cos4*s34
3259 : 187051359 : s = r25 + sin42*r34
3260 : 187051359 : z(2,j,i2,ia*ntb+b_i+ib) = r + sin2*s
3261 : 187051359 : z(2,j,i2,ia*ntb+4*b_i+ib) = r - sin2*s
3262 : 187051359 : r = s1 + cos4*s25 + cos2*s34
3263 : 187051359 : s = sin42*r25 - r34
3264 : 187051359 : z(2,j,i2,ia*ntb+2*b_i+ib) = r + sin2*s
3265 : 190423546 : z(2,j,i2,ia*ntb+3*b_i+ib) = r - sin2*s
3266 : : end do ! j
3267 : : end do ! i2
3268 : : !$OMP END PARALLEL DO
3269 : : end do ! ib
3270 : :
3271 : : ! Second step of radix 5
3272 [ + + ]: 619791 : do ia=1,aft(i)-1
3273 : 232880 : indx=ind(ia*5*b_i+1)-1
3274 : 232880 : indx=indx*b_i
3275 : 232880 : cr2=trig(1,indx)
3276 : 232880 : ct2=trig(2,indx)
3277 : 232880 : cr3=trig(1,2*indx)
3278 : 232880 : ct3=trig(2,2*indx)
3279 : 232880 : cr4=trig(1,3*indx)
3280 : 232880 : ct4=trig(2,3*indx)
3281 : 232880 : cr5=trig(1,4*indx)
3282 : 232880 : ct5=trig(2,4*indx)
3283 [ + + ]: 1405551 : do ib=1,b_i
3284 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3285 : : !$OMP&SHARED(b_i,cr2,cr3,cr4,cr5,ct2,ct3,ct4,ct5,ia,ib,n1,n2,n2i,ntb,sin2,z)
3286 [ + + ]: 1804400 : do i2=n2i,n2
3287 [ + + ]: 68327552 : do j=1,n1
3288 : 66756032 : r1=z(1,j,i2,ia*ntb+ib)
3289 : 66756032 : s1=z(2,j,i2,ia*ntb+ib)
3290 : : r2=cr2*(z(1,j,i2,ia*ntb+b_i+ib) - &
3291 : 66756032 : & z(2,j,i2,ia*ntb+b_i+ib)*ct2)
3292 : : s2=cr2*(z(1,j,i2,ia*ntb+b_i+ib)*ct2 + &
3293 : 66756032 : & z(2,j,i2,ia*ntb+b_i+ib))
3294 : : r3=cr3*(z(1,j,i2,ia*ntb+2*b_i+ib) - &
3295 : 66756032 : & z(2,j,i2,ia*ntb+2*b_i+ib)*ct3)
3296 : : s3=cr3*(z(1,j,i2,ia*ntb+2*b_i+ib)*ct3 + &
3297 : 66756032 : & z(2,j,i2,ia*ntb+2*b_i+ib))
3298 : : r4=z(1,j,i2,ia*ntb+3*b_i+ib) - &
3299 : 66756032 : & z(2,j,i2,ia*ntb+3*b_i+ib)*ct4
3300 : : s4=z(1,j,i2,ia*ntb+3*b_i+ib)*ct4 + &
3301 : 66756032 : & z(2,j,i2,ia*ntb+3*b_i+ib)
3302 : : r5=z(1,j,i2,ia*ntb+4*b_i+ib) - &
3303 : 66756032 : & z(2,j,i2,ia*ntb+4*b_i+ib)*ct5
3304 : : s5=z(1,j,i2,ia*ntb+4*b_i+ib)*ct5 + &
3305 : 66756032 : & z(2,j,i2,ia*ntb+4*b_i+ib)
3306 : 66756032 : r25 = r2 + r5*cr5
3307 : 66756032 : r34 = r3 + r4*cr4
3308 : 66756032 : s25 = s2 - s5*cr5
3309 : 66756032 : s34 = s3 - s4*cr4
3310 : 66756032 : z(1,j,i2,ia*ntb+ib) = r1 + r25 + r34
3311 : 66756032 : r = r1 + cos2*r25 + cos4*r34
3312 : 66756032 : s = s25 + sin42*s34
3313 : 66756032 : z(1,j,i2,ia*ntb+b_i+ib) = r - sin2*s
3314 : 66756032 : z(1,j,i2,ia*ntb+4*b_i+ib) = r + sin2*s
3315 : 66756032 : r = r1 + cos4*r25 + cos2*r34
3316 : 66756032 : s = sin42*s25 - s34
3317 : 66756032 : z(1,j,i2,ia*ntb+2*b_i+ib) = r - sin2*s
3318 : 66756032 : z(1,j,i2,ia*ntb+3*b_i+ib) = r + sin2*s
3319 : 66756032 : r25 = r2 - r5*cr5
3320 : 66756032 : r34 = r3 - r4*cr4
3321 : 66756032 : s25 = s2 + s5*cr5
3322 : 66756032 : s34 = s3 + s4*cr4
3323 : 66756032 : z(2,j,i2,ia*ntb+ib) = s1 + s25 + s34
3324 : 66756032 : r = s1 + cos2*s25 + cos4*s34
3325 : 66756032 : s = r25 + sin42*r34
3326 : 66756032 : z(2,j,i2,ia*ntb+b_i+ib) = r + sin2*s
3327 : 66756032 : z(2,j,i2,ia*ntb+4*b_i+ib) = r - sin2*s
3328 : 66756032 : r = s1 + cos4*s25 + cos2*s34
3329 : 66756032 : s = sin42*r25 - r34
3330 : 66756032 : z(2,j,i2,ia*ntb+2*b_i+ib) = r + sin2*s
3331 : 67541792 : z(2,j,i2,ia*ntb+3*b_i+ib) = r - sin2*s
3332 : : end do ! j
3333 : : end do ! i2
3334 : : !$OMP END PARALLEL DO
3335 : : end do ! ib
3336 : :
3337 : : end do ! ia
3338 : :
3339 : : ! All radices treated
3340 : : else
3341 : 0 : ABI_BUG('called with factors other than 2, 3, and 5')
3342 : : end if
3343 : :
3344 : : ! End of direct transformation
3345 : : end do
3346 : :
3347 : : !------------------------------------------------------------
3348 : : !bitreversal (zbr is for z"bit-reversed")
3349 : :
3350 : : !Treat radix 4
3351 [ + + ]: 568051 : if (now(ic)==4) then
3352 : 76645 : ia=0
3353 : :
3354 : : ! First step of radix 4
3355 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3356 : : !$OMP&SHARED(ia,ind,n1,n2,n2i,ntb,ris,z,zbr)
3357 [ + + ]: 153290 : do i2=n2i,n2
3358 [ + + ]: 6628426 : do j=1,n1
3359 : 6475136 : r4=z(1,j,i2,ia*4+4)
3360 : 6475136 : s4=z(2,j,i2,ia*4+4)
3361 : 6475136 : r3=z(1,j,i2,ia*4+3)
3362 : 6475136 : s3=z(2,j,i2,ia*4+3)
3363 : 6475136 : r2=z(1,j,i2,ia*4+2)
3364 : 6475136 : s2=z(2,j,i2,ia*4+2)
3365 : 6475136 : r1=z(1,j,i2,ia*4+1)
3366 : 6475136 : s1=z(2,j,i2,ia*4+1)
3367 : :
3368 : 6475136 : r=r1 + r3
3369 : 6475136 : s=r2 + r4
3370 : 6475136 : zbr(1,j,i2,ind(ia*4+1)) = r + s
3371 : 6475136 : zbr(1,j,i2,ind(ia*4+3)) = r - s
3372 : 6475136 : r=r1 - r3
3373 : 6475136 : s=s2 - s4
3374 : 6475136 : zbr(1,j,i2,ind(ia*4+2)) = r - s*ris
3375 : 6475136 : zbr(1,j,i2,ind(ia*4+4)) = r + s*ris
3376 : 6475136 : r=s1 + s3
3377 : 6475136 : s=s2 + s4
3378 : 6475136 : zbr(2,j,i2,ind(ia*4+1)) = r + s
3379 : 6475136 : zbr(2,j,i2,ind(ia*4+3)) = r - s
3380 : 6475136 : r=s1 - s3
3381 : 6475136 : s=r2 - r4
3382 : 6475136 : zbr(2,j,i2,ind(ia*4+2)) = r + s*ris
3383 : 6551781 : zbr(2,j,i2,ind(ia*4+4)) = r - s*ris
3384 : : end do ! j
3385 : : end do ! i2
3386 : : !$OMP END PARALLEL DO
3387 : :
3388 : : ! Second step of radix 4
3389 [ + + ]: 1658384 : do ia=1,aft(ic)-1
3390 : 1581739 : indx=ind(ia*4+1)-1
3391 : 1581739 : cr2=trig(1,indx)
3392 : 1581739 : ct2=trig(2,indx)
3393 : 1581739 : cr3=trig(1,2*indx)
3394 : 1581739 : ct3=trig(2,2*indx)
3395 : 1581739 : cr4=trig(1,3*indx)
3396 : 1581739 : ct4=trig(2,3*indx)
3397 : 1581739 : cr4=cr4/cr2
3398 : 1581739 : cr2s=cr2*ris
3399 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3400 : : !$OMP&SHARED(ia,cr2,cr2s,cr3,cr4,ct2,ct3,ct4,ind,n1,n2,n2i,z,zbr)
3401 [ + + ]: 3240123 : do i2=n2i,n2
3402 [ + + ]: 144703366 : do j=1,n1
3403 : 141539888 : r4=z(1,j,i2,ia*4+4) - z(2,j,i2,ia*4+4)*ct4
3404 : 141539888 : s4=z(1,j,i2,ia*4+4)*ct4 + z(2,j,i2,ia*4+4)
3405 : 141539888 : r3=z(1,j,i2,ia*4+3) - z(2,j,i2,ia*4+3)*ct3
3406 : 141539888 : s3=z(1,j,i2,ia*4+3)*ct3 + z(2,j,i2,ia*4+3)
3407 : 141539888 : r2=z(1,j,i2,ia*4+2) - z(2,j,i2,ia*4+2)*ct2
3408 : 141539888 : s2=z(1,j,i2,ia*4+2)*ct2 + z(2,j,i2,ia*4+2)
3409 : 141539888 : r1=z(1,j,i2,ia*4+1)
3410 : 141539888 : s1=z(2,j,i2,ia*4+1)
3411 : :
3412 : 141539888 : r=r1 + r3*cr3
3413 : 141539888 : s=r2 + r4*cr4
3414 : 141539888 : zbr(1,j,i2,ind(ia*4+1)) = r + s*cr2
3415 : 141539888 : zbr(1,j,i2,ind(ia*4+3)) = r - s*cr2
3416 : 141539888 : r=r1 - r3*cr3
3417 : 141539888 : s=s2 - s4*cr4
3418 : 141539888 : zbr(1,j,i2,ind(ia*4+2)) = r - s*cr2s
3419 : 141539888 : zbr(1,j,i2,ind(ia*4+4)) = r + s*cr2s
3420 : 141539888 : r=s1 + s3*cr3
3421 : 141539888 : s=s2 + s4*cr4
3422 : 141539888 : zbr(2,j,i2,ind(ia*4+1)) = r + s*cr2
3423 : 141539888 : zbr(2,j,i2,ind(ia*4+3)) = r - s*cr2
3424 : 141539888 : r=s1 - s3*cr3
3425 : 141539888 : s=r2 - r4*cr4
3426 : 141539888 : zbr(2,j,i2,ind(ia*4+2)) = r + s*cr2s
3427 : 143121627 : zbr(2,j,i2,ind(ia*4+4)) = r - s*cr2s
3428 : : end do ! j
3429 : : end do ! i2
3430 : : !$OMP END PARALLEL DO
3431 : :
3432 : : end do ! ia
3433 : :
3434 : : ! Treat radix 2
3435 [ + + ]: 491406 : else if (now(ic)==2) then
3436 : 255877 : ia=0
3437 : :
3438 : : ! First step of radix 2
3439 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3440 : : !$OMP&SHARED(ia,ind,n1,n2,n2i,z,zbr)
3441 [ + + ]: 511754 : do i2=n2i,n2
3442 [ + + ]: 5707820 : do j=1,n1
3443 : 5196066 : r1=z(1,j,i2,ia*2+1)
3444 : 5196066 : s1=z(2,j,i2,ia*2+1)
3445 : 5196066 : r2=z(1,j,i2,ia*2+2)
3446 : 5196066 : s2=z(2,j,i2,ia*2+2)
3447 : 5196066 : zbr(1,j,i2,ind(ia*2+1)) = r2 + r1
3448 : 5196066 : zbr(2,j,i2,ind(ia*2+1)) = s2 + s1
3449 : 5196066 : zbr(1,j,i2,ind(ia*2+2)) = -r2 + r1
3450 : 5451943 : zbr(2,j,i2,ind(ia*2+2)) = -s2 + s1
3451 : : end do ! j
3452 : : end do ! i2
3453 : : !$OMP END PARALLEL DO
3454 : :
3455 : : ! Second step of radix 2
3456 [ + + ]: 4326588 : do ia=1,aft(ic)-1
3457 : 4070711 : indx=ind(ia*2+1)-1
3458 : 4070711 : cr2=trig(1,indx)
3459 : 4070711 : ct2=trig(2,indx)
3460 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3461 : : !$OMP&SHARED(cr2,ct2,ia,ind,n1,n2,n2i,z,zbr)
3462 [ + + ]: 8397299 : do i2=n2i,n2
3463 [ + + ]: 106113284 : do j=1,n1
3464 : 97971862 : r1=z(1,j,i2,ia*2+1)
3465 : 97971862 : s1=z(2,j,i2,ia*2+1)
3466 : 97971862 : r2=z(1,j,i2,ia*2+2) - z(2,j,i2,ia*2+2)*ct2
3467 : 97971862 : s2=z(1,j,i2,ia*2+2)*ct2 + z(2,j,i2,ia*2+2)
3468 : 97971862 : zbr(1,j,i2,ind(ia*2+1)) = r2*cr2 + r1
3469 : 97971862 : zbr(2,j,i2,ind(ia*2+1)) = s2*cr2 + s1
3470 : 97971862 : zbr(1,j,i2,ind(ia*2+2)) = -r2*cr2 + r1
3471 : 102042573 : zbr(2,j,i2,ind(ia*2+2)) = -s2*cr2 + s1
3472 : : end do ! j
3473 : : end do ! i2
3474 : : !$OMP END PARALLEL DO
3475 : : end do ! ia
3476 : :
3477 : : ! Treat radix 3
3478 [ + - ]: 235529 : else if (now(ic)==3) then
3479 : : ! .5d0*sqrt(3.d0)=0.8660254037844387d0
3480 : 235529 : ia=0
3481 : 235529 : bb=ris*0.8660254037844387d0
3482 : :
3483 : : ! First step of radix 3
3484 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3485 : : !$OMP&SHARED(bb,ia,ind,n1,n2,n2i,z,zbr)
3486 [ + + ]: 471058 : do i2=n2i,n2
3487 [ + + ]: 4597599 : do j=1,n1
3488 : 4126541 : r1=z(1,j,i2,ia*3+1)
3489 : 4126541 : s1=z(2,j,i2,ia*3+1)
3490 : 4126541 : r2=z(1,j,i2,ia*3+2)
3491 : 4126541 : s2=z(2,j,i2,ia*3+2)
3492 : 4126541 : r3=z(1,j,i2,ia*3+3)
3493 : 4126541 : s3=z(2,j,i2,ia*3+3)
3494 : 4126541 : r=r2 + r3
3495 : 4126541 : s=s2 + s3
3496 : 4126541 : zbr(1,j,i2,ind(ia*3+1)) = r + r1
3497 : 4126541 : zbr(2,j,i2,ind(ia*3+1)) = s + s1
3498 : 4126541 : r1=r1 - r*.5d0
3499 : 4126541 : s1=s1 - s*.5d0
3500 : 4126541 : r2=r2-r3
3501 : 4126541 : s2=s2-s3
3502 : 4126541 : zbr(1,j,i2,ind(ia*3+2)) = r1 - s2*bb
3503 : 4126541 : zbr(2,j,i2,ind(ia*3+2)) = s1 + r2*bb
3504 : 4126541 : zbr(1,j,i2,ind(ia*3+3)) = r1 + s2*bb
3505 : 4362070 : zbr(2,j,i2,ind(ia*3+3)) = s1 - r2*bb
3506 : : end do ! j
3507 : : end do ! i2
3508 : : !$OMP END PARALLEL DO
3509 : :
3510 : : ! Second step of radix 3
3511 [ + + ]: 2834177 : do ia=1,aft(ic)-1
3512 : 2598648 : indx=ind(ia*3+1)-1
3513 : 2598648 : cr2=trig(1,indx)
3514 : 2598648 : ct2=trig(2,indx)
3515 : 2598648 : cr3=trig(1,2*indx)
3516 : 2598648 : ct3=trig(2,2*indx)
3517 : 2598648 : cr2=cr2/cr3
3518 : 2598648 : cr3p=.5d0*cr3
3519 : 2598648 : bb=ris*cr3*0.8660254037844387d0
3520 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3521 : : !$OMP&SHARED(bb,cr2,cr3,cr3p,ct2,ct3,ia,ind,n1,n2,n2i,z,zbr)
3522 [ + + ]: 5432825 : do i2=n2i,n2
3523 [ + + ]: 54846116 : do j=1,n1
3524 : 49648820 : r1=z(1,j,i2,ia*3+1)
3525 : 49648820 : s1=z(2,j,i2,ia*3+1)
3526 : 49648820 : r2=z(1,j,i2,ia*3+2) - z(2,j,i2,ia*3+2)*ct2
3527 : 49648820 : s2=z(1,j,i2,ia*3+2)*ct2 + z(2,j,i2,ia*3+2)
3528 : 49648820 : r3=z(1,j,i2,ia*3+3) - z(2,j,i2,ia*3+3)*ct3
3529 : 49648820 : s3=z(1,j,i2,ia*3+3)*ct3 + z(2,j,i2,ia*3+3)
3530 : 49648820 : r=cr2*r2 + r3
3531 : 49648820 : s=cr2*s2 + s3
3532 : 49648820 : zbr(1,j,i2,ind(ia*3+1)) = r*cr3 + r1
3533 : 49648820 : zbr(2,j,i2,ind(ia*3+1)) = s*cr3 + s1
3534 : 49648820 : r1=r1 - r*cr3p
3535 : 49648820 : s1=s1 - s*cr3p
3536 : 49648820 : r2=cr2*r2-r3
3537 : 49648820 : s2=cr2*s2-s3
3538 : 49648820 : zbr(1,j,i2,ind(ia*3+2)) = r1 - s2*bb
3539 : 49648820 : zbr(2,j,i2,ind(ia*3+2)) = s1 + r2*bb
3540 : 49648820 : zbr(1,j,i2,ind(ia*3+3)) = r1 + s2*bb
3541 : 52247468 : zbr(2,j,i2,ind(ia*3+3)) = s1 - r2*bb
3542 : : end do ! j
3543 : : end do ! i2
3544 : : !$OMP END PARALLEL DO
3545 : : end do ! ia
3546 : :
3547 : : ! Treat radix 5
3548 [ # # ]: 0 : else if (now(ic)==5) then
3549 : : ! sin(2.d0*pi/5.d0)
3550 : 0 : sin2=ris*0.9510565162951536d0
3551 : 0 : ia=0
3552 : :
3553 : : ! First step of radix 5
3554 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3555 : : !$OMP&SHARED(ia,ind,n1,n2,n2i,sin2,z,zbr)
3556 [ # # ]: 0 : do i2=n2i,n2
3557 [ # # ]: 0 : do j=1,n1
3558 : 0 : r1=z(1,j,i2,ia*5+1)
3559 : 0 : s1=z(2,j,i2,ia*5+1)
3560 : 0 : r2=z(1,j,i2,ia*5+2)
3561 : 0 : s2=z(2,j,i2,ia*5+2)
3562 : 0 : r3=z(1,j,i2,ia*5+3)
3563 : 0 : s3=z(2,j,i2,ia*5+3)
3564 : 0 : r4=z(1,j,i2,ia*5+4)
3565 : 0 : s4=z(2,j,i2,ia*5+4)
3566 : 0 : r5=z(1,j,i2,ia*5+5)
3567 : 0 : s5=z(2,j,i2,ia*5+5)
3568 : 0 : r25 = r2 + r5
3569 : 0 : r34 = r3 + r4
3570 : 0 : s25 = s2 - s5
3571 : 0 : s34 = s3 - s4
3572 : 0 : zbr(1,j,i2,ind(ia*5+1)) = r1 + r25 + r34
3573 : 0 : r = r1 + cos2*r25 + cos4*r34
3574 : 0 : s = s25 + sin42*s34
3575 : 0 : zbr(1,j,i2,ind(ia*5+2)) = r - sin2*s
3576 : 0 : zbr(1,j,i2,ind(ia*5+5)) = r + sin2*s
3577 : 0 : r = r1 + cos4*r25 + cos2*r34
3578 : 0 : s = sin42*s25 - s34
3579 : 0 : zbr(1,j,i2,ind(ia*5+3)) = r - sin2*s
3580 : 0 : zbr(1,j,i2,ind(ia*5+4)) = r + sin2*s
3581 : 0 : r25 = r2 - r5
3582 : 0 : r34 = r3 - r4
3583 : 0 : s25 = s2 + s5
3584 : 0 : s34 = s3 + s4
3585 : 0 : zbr(2,j,i2,ind(ia*5+1)) = s1 + s25 + s34
3586 : 0 : r = s1 + cos2*s25 + cos4*s34
3587 : 0 : s = r25 + sin42*r34
3588 : 0 : zbr(2,j,i2,ind(ia*5+2)) = r + sin2*s
3589 : 0 : zbr(2,j,i2,ind(ia*5+5)) = r - sin2*s
3590 : 0 : r = s1 + cos4*s25 + cos2*s34
3591 : 0 : s = sin42*r25 - r34
3592 : 0 : zbr(2,j,i2,ind(ia*5+3)) = r + sin2*s
3593 : 0 : zbr(2,j,i2,ind(ia*5+4)) = r - sin2*s
3594 : : end do ! j
3595 : : end do ! i2
3596 : : !$OMP END PARALLEL DO
3597 : :
3598 : : ! Second step of radix 5
3599 [ # # ]: 0 : do ia=1,aft(ic)-1
3600 : 0 : indx=ind(ia*5+1)-1
3601 : 0 : cr2=trig(1,indx)
3602 : 0 : ct2=trig(2,indx)
3603 : 0 : cr3=trig(1,2*indx)
3604 : 0 : ct3=trig(2,2*indx)
3605 : 0 : cr4=trig(1,3*indx)
3606 : 0 : ct4=trig(2,3*indx)
3607 : 0 : cr5=trig(1,4*indx)
3608 : 0 : ct5=trig(2,4*indx)
3609 : : !$OMP PARALLEL DO DEFAULT(PRIVATE)&
3610 : : !$OMP&SHARED(cr2,cr3,cr4,cr5,ct2,ct3,ct4,ct5,ia,ind,n1,n2,n2i,sin2,z,zbr)
3611 [ # # ]: 0 : do i2=n2i,n2
3612 [ # # ]: 0 : do j=1,n1
3613 : 0 : r1=z(1,j,i2,ia*5+1)
3614 : 0 : s1=z(2,j,i2,ia*5+1)
3615 : 0 : r2=cr2*(z(1,j,i2,ia*5+2) - z(2,j,i2,ia*5+2)*ct2)
3616 : 0 : s2=cr2*(z(1,j,i2,ia*5+2)*ct2 + z(2,j,i2,ia*5+2))
3617 : 0 : r3=cr3*(z(1,j,i2,ia*5+3) - z(2,j,i2,ia*5+3)*ct3)
3618 : 0 : s3=cr3*(z(1,j,i2,ia*5+3)*ct3 + z(2,j,i2,ia*5+3))
3619 : 0 : r4=z(1,j,i2,ia*5+4) - z(2,j,i2,ia*5+4)*ct4
3620 : 0 : s4=z(1,j,i2,ia*5+4)*ct4 + z(2,j,i2,ia*5+4)
3621 : 0 : r5=z(1,j,i2,ia*5+5) - z(2,j,i2,ia*5+5)*ct5
3622 : 0 : s5=z(1,j,i2,ia*5+5)*ct5 + z(2,j,i2,ia*5+5)
3623 : 0 : r25 = r2 + r5*cr5
3624 : 0 : r34 = r3 + r4*cr4
3625 : 0 : s25 = s2 - s5*cr5
3626 : 0 : s34 = s3 - s4*cr4
3627 : 0 : zbr(1,j,i2,ind(ia*5+1)) = r1 + r25 + r34
3628 : 0 : r = r1 + cos2*r25 + cos4*r34
3629 : 0 : s = s25 + sin42*s34
3630 : 0 : zbr(1,j,i2,ind(ia*5+2)) = r - sin2*s
3631 : 0 : zbr(1,j,i2,ind(ia*5+5)) = r + sin2*s
3632 : 0 : r = r1 + cos4*r25 + cos2*r34
3633 : 0 : s = sin42*s25 - s34
3634 : 0 : zbr(1,j,i2,ind(ia*5+3)) = r - sin2*s
3635 : 0 : zbr(1,j,i2,ind(ia*5+4)) = r + sin2*s
3636 : 0 : r25 = r2 - r5*cr5
3637 : 0 : r34 = r3 - r4*cr4
3638 : 0 : s25 = s2 + s5*cr5
3639 : 0 : s34 = s3 + s4*cr4
3640 : 0 : zbr(2,j,i2,ind(ia*5+1)) = s1 + s25 + s34
3641 : 0 : r = s1 + cos2*s25 + cos4*s34
3642 : 0 : s = r25 + sin42*r34
3643 : 0 : zbr(2,j,i2,ind(ia*5+2)) = r + sin2*s
3644 : 0 : zbr(2,j,i2,ind(ia*5+5)) = r - sin2*s
3645 : 0 : r = s1 + cos4*s25 + cos2*s34
3646 : 0 : s = sin42*r25 - r34
3647 : 0 : zbr(2,j,i2,ind(ia*5+3)) = r + sin2*s
3648 : 0 : zbr(2,j,i2,ind(ia*5+4)) = r - sin2*s
3649 : : end do ! j
3650 : : end do ! i2
3651 : : !$OMP END PARALLEL DO
3652 : : end do ! ia
3653 : :
3654 : : else ! All radices treated
3655 : : !if (now(ic) /= 1) then
3656 : 0 : ABI_BUG(sjoin("Called with factors other than 2, 3, and 5. now(ic) = ", itoa(now(ic))))
3657 : : !end if
3658 : : end if
3659 : :
3660 : 568051 : end subroutine sg_fftz
3661 : : !!***
3662 : :
3663 : : !----------------------------------------------------------------------
3664 : :
3665 : : !!****f* m_sgfft/sg_ctrig
3666 : : !! NAME
3667 : : !! sg_ctrig
3668 : : !!
3669 : : !! FUNCTION
3670 : : !! Precalculates trigonometric expressions and bitreversal key IND (Stefan Goedecker lib).
3671 : : !!
3672 : : !! INPUTS
3673 : : !! n=Number of FFT points for 1D FFT.
3674 : : !! ris = sign of exponential in transform (should be 1 or -1; real)
3675 : : !! mfac = maximum number of factors in 1D FFTs
3676 : : !! mg = maximum length of 1D FFTs
3677 : : !!
3678 : : !! OUTPUT
3679 : : !! trig(2,mg) TO BE DESCRIBED SB 090902
3680 : : !! aft(mfac) TO BE DESCRIBED SB 090902
3681 : : !! bef(mfac) TO BE DESCRIBED SB 090902
3682 : : !! now(mfac) TO BE DESCRIBED SB 090902
3683 : : !! ic = number of (radix) factors of x transform length (from ctrig)
3684 : : !! ind(mg) TO BE DESCRIBED SB 090902
3685 : : !!
3686 : : !! NOTES
3687 : : !! * This version of sg_ctrig produces cos and tan instead of sin and cos--
3688 : : !! this allows for much greater efficiency on the superscalar architecture
3689 : : !! of ibm rs6000 where floating point multiply and add (FMA) is used.
3690 : : !!
3691 : : !! * This routine is not thread-safe due to the presence of variables with the save attribute!
3692 : : !! DO NOT CALL THIS ROUTINE INSIDE A OPENMP PARALLEL REGION
3693 : : !!
3694 : : !! TODO
3695 : : !! Should describe arguments
3696 : : !! Should suppress one-letter variables
3697 : : !!
3698 : : !! SOURCE
3699 : :
3700 : 96285 : subroutine sg_ctrig(n,trig,aft,bef,now,ris,ic,ind,mfac,mg)
3701 : :
3702 : : !Arguments ------------------------------------
3703 : : !scalars
3704 : : integer,intent(in) :: mfac,mg,n
3705 : : integer,intent(out) :: ic
3706 : : real(dp),intent(in) :: ris
3707 : : !arrays
3708 : : integer,intent(out) :: aft(mfac),bef(mfac),ind(mg),now(mfac)
3709 : : real(dp),intent(out) :: trig(2,mg)
3710 : :
3711 : : !Local variables-------------------------------
3712 : : !scalars
3713 : : integer,save :: nextmx=4
3714 : : integer :: i,ii,inc,irep,j,k,l,next,nh
3715 : : integer,save :: prime(4)=(/5,4,3,2/) !"prime" is the set of radices coded elsewhere for fft
3716 : : real(dp) :: angle,trigc,trigs,twopi
3717 : : character(len=500) :: message
3718 : :
3719 : : ! *************************************************************************
3720 : :
3721 : : !**Note**
3722 : : !2*Pi must not be defined too accurately here or else
3723 : : !cos(twopi/2) will be exactly 0 and sin/cos below will be
3724 : : !infinite; if a small error is left in Pi, then sin/cos will
3725 : : !be about 10**14 and later cos * (sin/cos) will be 1 to within
3726 : : !about 10**(-14) and the fft routines will work
3727 : : !The precision on sgi causes the algorithm to fail if
3728 : : !twopi is defined as 8.d0*atan(1.0d0).
3729 : :
3730 : 96285 : twopi=6.2831853071795867d0
3731 : :
3732 : 96285 : angle=ris*twopi/n
3733 : : !trig(1,0)=1.d0
3734 : : !trig(2,0)=0.d0
3735 [ + + ]: 96285 : if (mod(n,2)==0) then
3736 : 81607 : nh=n/2
3737 : 81607 : trig(1,nh)=-1.d0
3738 : 81607 : trig(2,nh)=0.d0
3739 [ + + ]: 993734 : do i=1,nh-1
3740 : 912127 : trigc=cos(i*angle)
3741 : 912127 : trigs=sin(i*angle)
3742 : 912127 : trig(1,i)=trigc
3743 : 912127 : trig(2,i)=trigs/trigc
3744 : 912127 : trig(1,n-i)=trigc
3745 : 993734 : trig(2,n-i)=-trigs/trigc
3746 : : end do
3747 : : else
3748 : 14678 : nh=(n-1)/2
3749 [ + + ]: 204139 : do i=1,nh
3750 : 189461 : trigc=cos(i*angle)
3751 : 189461 : trigs=sin(i*angle)
3752 : 189461 : trig(1,i)=trigc
3753 : 189461 : trig(2,i)=trigs/trigc
3754 : 189461 : trig(1,n-i)=trigc
3755 : 204139 : trig(2,n-i)=-trigs/trigc
3756 : : end do
3757 : : end if
3758 : :
3759 : 96285 : ic=1
3760 : 96285 : aft(ic)=1
3761 : 96285 : bef(ic)=n
3762 : 96285 : next=1
3763 : :
3764 : : !An infinite loop, with exit or cycle instructions
3765 : : do
3766 [ + + ]: 502967 : if( (bef(ic)/prime(next))*prime(next)<bef(ic) ) then
3767 : 255365 : next=next+1
3768 [ + - ]: 255365 : if (next<=nextmx) then
3769 : : cycle
3770 : : else
3771 : 0 : now(ic)=bef(ic)
3772 : 0 : bef(ic)=1
3773 : : end if
3774 : : else
3775 : 247602 : now(ic)=prime(next)
3776 : 247602 : bef(ic)=bef(ic)/prime(next)
3777 : : end if
3778 : 247602 : aft(ic+1)=aft(ic)
3779 : 247602 : now(ic+1)=now(ic)
3780 : 247602 : bef(ic+1)=bef(ic)
3781 : 247602 : ic=ic+1
3782 [ - + ]: 247602 : if (ic>mfac) then
3783 : : write(message, '(a,i0,2a,i0)' )&
3784 : 0 : & 'number of factors ic=',ic,ch10,&
3785 : 0 : & 'exceeds dimensioned mfac=',mfac
3786 : 0 : ABI_BUG(message)
3787 : : end if
3788 [ + + ]: 247602 : if (bef(ic)/=1) then
3789 : 151317 : aft(ic)=aft(ic)*now(ic)
3790 : 151317 : cycle
3791 : : end if
3792 : : ! If not cycled, exit
3793 : 255365 : exit
3794 : : end do
3795 : :
3796 : 96285 : ic=ic-1
3797 : :
3798 : : !DEBUG
3799 : : !write(std_out,*) 'now',(now(i),i=1,ic)
3800 : : !write(std_out,*) 'aft',(aft(i),i=1,ic)
3801 : : !write(std_out,*) 'bef',(bef(i),i=1,ic)
3802 : : !ENDDEBUG
3803 : :
3804 [ + + ]: 2477353 : do i=1,n
3805 : 2477353 : ind(i)=1
3806 : : end do
3807 : :
3808 : 96285 : irep=1
3809 : 96285 : inc=n
3810 [ + + ]: 343887 : do l=ic,1,-1
3811 : 247602 : inc=inc/now(l)
3812 : 247602 : ii=0
3813 [ + + ]: 1602920 : do k=1,1+(n-1)/(now(l)*irep)
3814 [ + + ]: 5243021 : do j=0,now(l)-1
3815 [ + + ]: 11800574 : do i=1,irep
3816 : 6805155 : ii=ii+1
3817 : 10445256 : ind(ii)=ind(ii)+j*inc
3818 : : end do
3819 : : end do
3820 : : end do
3821 : 343887 : irep=irep*now(l)
3822 : : end do
3823 : :
3824 [ - + ]: 96285 : if (irep/=n) then
3825 : 0 : write(message,'(a,i0,a,i0)')' irep should equal n ; irep=',irep,' n=',n
3826 : 0 : ABI_BUG(message)
3827 : : end if
3828 : :
3829 [ - + ]: 96285 : if (inc/=1) then
3830 : 0 : write(message, '(a,i0)' )' inc should equal 1 in sg_ctrig; inc=',inc
3831 : 0 : ABI_BUG(message)
3832 : : end if
3833 : :
3834 : 96285 : end subroutine sg_ctrig
3835 : : !!***
3836 : :
3837 : : !----------------------------------------------------------------------
3838 : :
3839 : : !!****f* m_sgfft/sg_fftrisc
3840 : : !! NAME
3841 : : !! sg_fftrisc
3842 : : !!
3843 : : !! FUNCTION
3844 : : !! Wrapper around fftrisc_one_nothreadsafe that supports ndat transforms.
3845 : : !!
3846 : : !! * This routine is not thread-safe due to the presence of variables with the save attribute!
3847 : : !! DO NOT CALL THIS ROUTINE INSIDE A OPENMP PARALLEL REGION
3848 : : !!
3849 : : !! SOURCE
3850 : :
3851 : 1094182 : subroutine sg_fftrisc(cplex,denpot,fofgin,fofgout,fofr,gboundin,gboundout,istwf_k,&
3852 : 1094182 : & kg_kin,kg_kout,mgfft,ndat,ngfft,npwin,npwout,n4,n5,n6,option,weight_r, weight_i)
3853 : :
3854 : : !Arguments ------------------------------------
3855 : : !scalars
3856 : : integer,intent(in) :: cplex,istwf_k,mgfft,n4,n5,n6,ndat,npwin,npwout,option
3857 : : real(dp),intent(in) :: weight_i,weight_r
3858 : : !arrays
3859 : : integer,intent(in) :: gboundin(2*mgfft+8,2),gboundout(2*mgfft+8,2)
3860 : : integer,intent(in) :: kg_kin(3,npwin),kg_kout(3,npwout),ngfft(18)
3861 : : real(dp),intent(in) :: fofgin(2,npwin*ndat)
3862 : : real(dp),intent(inout) :: denpot(cplex*n4*n5*n6),fofr(2,n4*n5*n6*ndat)
3863 : : real(dp),intent(out) :: fofgout(2,npwout*ndat)
3864 : :
3865 : : !Local variables-------------------------------
3866 : : !scalars
3867 : : integer :: idat,fofgin_p,fofr_p,fofgout_p
3868 : : !arrays
3869 : : real(dp) :: dum_fofgin(0,0),dum_fofr(0,0),dum_fofgout(0,0)
3870 : :
3871 : : ! *************************************************************************
3872 : :
3873 [ + + ]: 2188388 : do idat=1,ndat
3874 : 1094206 : fofgin_p = 1 + (idat-1) * npwin
3875 : 1094206 : fofr_p = 1 + (idat - 1) * n4*n5*n6
3876 : 1094206 : fofgout_p = 1 + (idat-1) * npwout
3877 : :
3878 : 1094182 : select case (option)
3879 : : case (0)
3880 : : call fftrisc_one_nothreadsafe(&
3881 : : & cplex,denpot,fofgin(1,fofgin_p),dum_fofgout,fofr(1,fofr_p),&
3882 : : & gboundin,gboundout,istwf_k,&
3883 : 279232 : & kg_kin,kg_kout,mgfft,ngfft,npwin,npwout,n4,n5,n6,option,weight_r,weight_i)
3884 : :
3885 : : case (1)
3886 : : ! Don't know why but fofr is not touched by this option.
3887 : : call fftrisc_one_nothreadsafe(&
3888 : : & cplex,denpot,fofgin(1,fofgin_p),dum_fofgout,dum_fofr,&
3889 : : & gboundin,gboundout,istwf_k,&
3890 : 37245 : & kg_kin,kg_kout,mgfft,ngfft,npwin,npwout,n4,n5,n6,option,weight_r,weight_i)
3891 : :
3892 : : case (2)
3893 : : call fftrisc_one_nothreadsafe(&
3894 : : & cplex,denpot,fofgin(1,fofgin_p),fofgout(1,fofgout_p),dum_fofr,&
3895 : : & gboundin,gboundout,istwf_k,&
3896 : 777714 : & kg_kin,kg_kout,mgfft,ngfft,npwin,npwout,n4,n5,n6,option,weight_r,weight_i)
3897 : :
3898 : : case (3)
3899 : : call fftrisc_one_nothreadsafe(&
3900 : : & cplex,denpot,dum_fofgin,fofgout(1,fofgout_p),fofr(1,fofr_p),&
3901 : : & gboundin,gboundout,istwf_k,&
3902 : 15 : & kg_kin,kg_kout,mgfft,ngfft,npwin,npwout,n4,n5,n6,option,weight_r,weight_i)
3903 : :
3904 : : case default
3905 [ + + + + : 1094206 : ABI_ERROR("Wrong option")
- ]
3906 : : end select
3907 : : end do
3908 : :
3909 : 1094182 : end subroutine sg_fftrisc
3910 : : !!***
3911 : :
3912 : : !----------------------------------------------------------------------
3913 : :
3914 : : !!****f* m_sgfft/fftrisc_one_nothreadsafe
3915 : : !! NAME
3916 : : !! fftrisc_one_nothreadsafe
3917 : : !!
3918 : : !! FUNCTION
3919 : : !! Carry out Fourier transforms between real and reciprocal (G) space,
3920 : : !! for wavefunctions, contained in a sphere in reciprocal space,
3921 : : !! in both directions. Also accomplish some post-processing.
3922 : : !!
3923 : : !! NOTES
3924 : : !! Specifically uses rather sophisticated algorithms, based on S Goedecker
3925 : : !! routines, specialized for superscalar RISC architecture.
3926 : : !! Zero padding : saves 7/12 execution time
3927 : : !! Bi-dimensional data locality in most of the routine : cache reuse
3928 : : !! For k-point (0 0 0) : takes advantage of symmetry of data.
3929 : : !! Note however that no blocking is used, in both 1D z-transform
3930 : : !! or subsequent 2D transform. This should be improved.
3931 : : !!
3932 : : !! * This routine is not thread-safe due to the presence of variables with the save attribute!
3933 : : !! DO NOT CALL THIS ROUTINE INSIDE A OPENMP PARALLEL REGION
3934 : : !!
3935 : : !! INPUTS
3936 : : !! cplex= if 1 , denpot is real, if 2 , denpot is complex
3937 : : !! (cplex=2 only allowed for option=2 when istwf_k=1)
3938 : : !! one can also use cplex=0 if option=0 or option=3
3939 : : !! fofgin(2,npwin)=holds input wavefunction in G vector basis sphere.
3940 : : !! gboundin(2*mgfft+8,2)=sphere boundary info for reciprocal to real space
3941 : : !! gboundout(2*mgfft+8,2)=sphere boundary info for real to reciprocal space
3942 : : !! istwf_k=option parameter that describes the storage of wfs
3943 : : !! kg_kin(3,npwin)=reduced planewave coordinates, input
3944 : : !! kg_kout(3,npwout)=reduced planewave coordinates, output
3945 : : !! mgfft=maximum size of 1D FFTs
3946 : : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
3947 : : !! npwin=number of elements in fofgin array (for option 0, 1 and 2)
3948 : : !! npwout=number of elements in fofgout array (for option 2 and 3)
3949 : : !! n4,n5,n6=ngfft(4),ngfft(5),ngfft(6), dimensions of fofr.
3950 : : !! option= if 0: do direct FFT
3951 : : !! if 1: do direct FFT, then sum the density
3952 : : !! if 2: do direct FFT, multiply by the potential, then do reverse FFT
3953 : : !! if 3: do reverse FFT only
3954 : : !! weight=weight to be used for the accumulation of the density in real space
3955 : : !! (needed only when option=1)
3956 : : !!
3957 : : !! OUTPUT
3958 : : !! (see side effects)
3959 : : !!
3960 : : !! OPTIONS
3961 : : !! The different options are:
3962 : : !! - reciprocal to real space and output the result (when option=0),
3963 : : !! - reciprocal to real space and accumulate the density (when option=1) or
3964 : : !! - reciprocal to real space, apply the local potential to the wavefunction
3965 : : !! in real space and produce the result in reciprocal space (when option=2)
3966 : : !! - real space to reciprocal space (when option=3).
3967 : : !! option=0 IS NOT ALLOWED when istwf_k>2
3968 : : !! option=3 IS NOT ALLOWED when istwf_k>=2
3969 : : !!
3970 : : !! SIDE EFFECTS
3971 : : !! for option==0, fofgin(2,npwin)=holds input wavefunction in G sphere;
3972 : : !! fofr(2,n4,n5,n6) contains the Fourier Transform of fofgin;
3973 : : !! no use of denpot, fofgout and npwout.
3974 : : !! for option==1, fofgin(2,npwin)=holds input wavefunction in G sphere;
3975 : : !! denpot(cplex*n4,n5,n6) contains the input density at input,
3976 : : !! and the updated density at output;
3977 : : !! no use of fofgout and npwout.
3978 : : !! for option==2, fofgin(2,npwin)=holds input wavefunction in G sphere;
3979 : : !! denpot(cplex*n4,n5,n6) contains the input local potential;
3980 : : !! fofgout(2,npwout) contains the output function;
3981 : : !! for option==3, fofr(2,n4,n5,n6) contains the real space wavefunction;
3982 : : !! fofgout(2,npwout) contains its Fourier transform;
3983 : : !! no use of fofgin and npwin.
3984 : : !!
3985 : : !! SOURCE
3986 : :
3987 : 1094206 : subroutine fftrisc_one_nothreadsafe(cplex,denpot,fofgin,fofgout,fofr,gboundin,gboundout,istwf_k,&
3988 : 1094206 : & kg_kin,kg_kout,mgfft,ngfft,npwin,npwout,n4,n5,n6,option,weight_r,weight_i)
3989 : :
3990 : : !Arguments ------------------------------------
3991 : : !scalars
3992 : : integer,intent(in) :: cplex,istwf_k,mgfft,n4,n5,n6,npwin,npwout,option
3993 : : real(dp),intent(in) :: weight_i,weight_r
3994 : : !arrays
3995 : : integer,intent(in) :: gboundin(2*mgfft+8,2),gboundout(2*mgfft+8,2)
3996 : : integer,intent(in) :: kg_kin(3,npwin),kg_kout(3,npwout),ngfft(18)
3997 : : real(dp),intent(in) :: fofgin(2,npwin)
3998 : : real(dp),intent(inout) :: denpot(cplex*n4,n5,n6),fofr(2,n4,n5,n6)
3999 : : real(dp),intent(out) :: fofgout(2,npwout)
4000 : :
4001 : : !Local variables-------------------------------
4002 : : !scalars
4003 : : integer,parameter :: mfac=11
4004 : : integer,save :: ic1,ic2,ic3,ic4,ic5,ic6,n1_save=0,n2_save=0,n3_save=0
4005 : : integer :: fftcache,g2max,g2min,i1,i1max,i2,i3,i3inv,ig,igb
4006 : : integer :: igb_inv,igbmax,ii2,lot,lotin,lotout,mgb,n1
4007 : : integer :: n1half1,n1halfm,n1i,n2,n2half1,n3,n4half1,n5half1,nfftot,ngbin
4008 : : integer :: ngbout,nlot,nproc_omp
4009 : : real(dp) :: ai,ar,fraction,norm,phai,phar,wkim,wkre
4010 : : character(len=500) :: message
4011 : : !arrays
4012 : : integer,save :: aft1(mfac),aft2(mfac),aft3(mfac),aft4(mfac),aft5(mfac)
4013 : : integer,save :: aft6(mfac),bef1(mfac),bef2(mfac),bef3(mfac),bef4(mfac)
4014 : : integer,save :: bef5(mfac),bef6(mfac),ind1(mg),ind2(mg),ind3(mg),ind4(mg)
4015 : : integer,save :: ind5(mg),ind6(mg),now1(mfac),now2(mfac),now3(mfac),now4(mfac)
4016 : : integer,save :: now5(mfac),now6(mfac)
4017 : : integer :: gbound_dum(4)
4018 : 1094206 : integer,allocatable :: indpw_kin(:,:),indpw_kout(:,:)
4019 : : real(dp),save :: trig1(2,mg),trig2(2,mg),trig3(2,mg),trig4(2,mg),trig5(2,mg)
4020 : : real(dp),save :: trig6(2,mg)
4021 : 1094206 : real(dp),allocatable :: pha1(:,:),pha2(:,:),pha3(:,:),wk1d_a(:,:,:,:)
4022 : 1094206 : real(dp),allocatable :: wk1d_b(:,:,:,:),wk2d_a(:,:,:,:),wk2d_b(:,:,:,:)
4023 : 1094206 : real(dp),allocatable :: wk2d_c(:,:,:,:),wk2d_d(:,:,:,:)
4024 : : #if defined HAVE_OPENMP
4025 : : integer,external :: OMP_GET_NUM_THREADS
4026 : : #endif
4027 : :
4028 : : ! *************************************************************************
4029 : :
4030 [ + + - + ]: 1094206 : if(istwf_k>2 .and. option==0)then
4031 : 0 : write(message,'(a,i0)')' option=0 is not allowed with istwf_k=',istwf_k
4032 : 0 : ABI_BUG(message)
4033 : : end if
4034 : :
4035 [ + + - + ]: 1094206 : if(istwf_k>=2 .and. option==3)then
4036 : 0 : write(message,'(a,i0)')' option=3 is not allowed with istwf_k=',istwf_k
4037 : 0 : ABI_BUG(message)
4038 : : end if
4039 : :
4040 : : !For all other tests of validity of inputs, assume that they
4041 : : !have been done in the calling routine
4042 : :
4043 : 1094206 : n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3) ; nfftot=n1*n2*n3
4044 : 1094206 : fftcache=ngfft(8)
4045 : :
4046 [ + + ]: 1094206 : if(option/=3)then
4047 [ - + + - : 3282573 : ABI_MALLOC(indpw_kin,(4,npwin))
+ - + - -
+ - + ]
4048 : 1094191 : call indfftrisc(gboundin(3:3+2*mgfft+4,1),indpw_kin,kg_kin,mgfft,ngbin,ngfft,npwin)
4049 : : end if
4050 [ + + ]: 1094206 : if(option==2 .or. option==3)then
4051 [ - + + - : 2333187 : ABI_MALLOC(indpw_kout,(4,npwout))
+ - + - -
+ - + ]
4052 : 777729 : call indfftrisc(gboundout(3:3+2*mgfft+4,1),indpw_kout,kg_kout,mgfft,ngbout,ngfft,npwout)
4053 : : end if
4054 : :
4055 : : !Define the dimension of the first work arrays, for 1D transforms along z ,
4056 : : !taking into account the need to avoid the cache trashing
4057 [ + + ]: 1094206 : if(option==2)then
4058 : 777714 : mgb=max(ngbin,ngbout)
4059 [ + + ]: 316492 : else if(option==0 .or. option==1)then
4060 : 316477 : mgb=ngbin ; ngbout=1
4061 [ + - ]: 15 : else if(option==3)then
4062 : 15 : mgb=ngbout ; ngbin=1
4063 : : end if
4064 : :
4065 [ + + ]: 1094206 : if(mod(mgb,2)/=1)mgb=mgb+1
4066 : :
4067 : : !Initialise openmp, if needed
4068 : : !$OMP PARALLEL
4069 : : !$OMP SINGLE
4070 : 1094206 : nproc_omp=1
4071 : : #if defined HAVE_OPENMP
4072 : : nproc_omp=OMP_GET_NUM_THREADS()
4073 : : #endif
4074 : : !$OMP END SINGLE
4075 : : !$OMP END PARALLEL
4076 : :
4077 : : !For the treatment of the z transform,
4078 : : !one tries to use only a fraction of the cache, since the
4079 : : !treatment of the array wk1d_a will not involve contiguous segments
4080 : 1094206 : fraction=0.25
4081 : : !First estimation of lot and nlot
4082 : 1094206 : lot=(fftcache*fraction*1000)/(n3*8*2)+1
4083 : : !Select the smallest integer multiple of nproc_omp, larger
4084 : : !or equal to nlot. In this way, the cache size is not exhausted,
4085 : : !and one takes care correctly of the number of processors.
4086 : : !Treat separately the in and out cases
4087 : 1094206 : nlot=(ngbin-1)/lot+1
4088 : 1094206 : nlot=nproc_omp*((nlot-1)/nproc_omp+1)
4089 : 1094206 : lotin=(ngbin-1)/nlot+1
4090 : 1094206 : nlot=(ngbout-1)/lot+1
4091 : 1094206 : nlot=nproc_omp*((nlot-1)/nproc_omp+1)
4092 : 1094206 : lotout=(ngbout-1)/nlot+1
4093 : : !The next line impose only one lot. Usually, comment it.
4094 : : !lotin=mgb ; lotout=mgb
4095 : :
4096 : : !Compute auxiliary arrays needed for FFTs
4097 [ + + ]: 1094206 : if(n1/=n1_save)then
4098 : 49 : call sg_ctrig(n1,trig1,aft1,bef1,now1,one,ic1,ind1,mfac,mg)
4099 : 49 : call sg_ctrig(n1,trig4,aft4,bef4,now4,-one,ic4,ind4,mfac,mg)
4100 : 49 : n1_save=n1
4101 : : end if
4102 [ + + ]: 1094206 : if(n2/=n2_save)then
4103 : 49 : call sg_ctrig(n2,trig2,aft2,bef2,now2,one,ic2,ind2,mfac,mg)
4104 : 49 : call sg_ctrig(n2,trig5,aft5,bef5,now5,-one,ic5,ind5,mfac,mg)
4105 : 49 : n2_save=n2
4106 : : end if
4107 [ + + ]: 1094206 : if(n3/=n3_save)then
4108 : 49 : call sg_ctrig(n3,trig3,aft3,bef3,now3,one,ic3,ind3,mfac,mg)
4109 : 49 : call sg_ctrig(n3,trig6,aft6,bef6,now6,-one,ic6,ind6,mfac,mg)
4110 : 49 : n3_save=n3
4111 : : end if
4112 : :
4113 : : !------------------------------------------------------------------
4114 : : !Here, call general k-point code
4115 : :
4116 [ + + ]: 1094206 : if(istwf_k==1)then
4117 : :
4118 : : ! Note that the z transform will appear as a y transform
4119 [ - + + - : 4373132 : ABI_MALLOC(wk1d_a,(2,mgb,n3,1))
- + + - +
- + - - +
- + ]
4120 [ - + + - : 3279849 : ABI_MALLOC(wk1d_b,(2,mgb,n3,1))
- + + - -
+ - + ]
4121 : :
4122 [ + + ]: 1093283 : if(option/=3)then
4123 : :
4124 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(n3,ngbin,wk1d_a)
4125 [ + + ]: 19191937 : do i3=1,n3
4126 [ + + ]: 648870515 : do igb=1,ngbin
4127 : 629678578 : wk1d_a(1,igb,i3,1)=zero
4128 : 647777247 : wk1d_a(2,igb,i3,1)=zero
4129 : : end do
4130 : : end do
4131 : : !$OMP END PARALLEL DO
4132 : :
4133 : : ! Insert fofgin into the work array
4134 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(fofgin,indpw_kin,npwin,wk1d_a)
4135 [ + + ]: 147962380 : do ig=1,npwin
4136 : 146869112 : igb=indpw_kin(4,ig) ; i3=indpw_kin(3,ig)
4137 : 146869112 : wk1d_a(1,igb,i3,1)=fofgin(1,ig)
4138 : 147962380 : wk1d_a(2,igb,i3,1)=fofgin(2,ig)
4139 : : end do
4140 : : !$OMP END PARALLEL DO
4141 : :
4142 : : ! Go from wk1d_a to wk1d_b, using 1D FFTs on the z direction
4143 : : ! However, due to special packing of data, use routine ffty
4144 : : !$OMP PARALLEL DO SHARED(aft3,bef3,fftcache,ind3,ic3,lotin,mgb)&
4145 : : !$OMP&SHARED(ngbin,now3,n3,trig3,wk1d_a,wk1d_b)&
4146 : : !$OMP&PRIVATE(igb,igbmax)
4147 [ - + - - : 4246621 : do igb=1,ngbin,lotin
- + + + ]
4148 : 3153353 : igbmax=min(igb+lotin-1,ngbin)
4149 : : ! Go from wk1d_a to wk1d_b, using 1D FFTs on the z direction
4150 : : ! However, due to special packing of data, use routine ffty
4151 : : call sg_ffty(fftcache,mfac,mg,mgb,n3,1,igb,igbmax,1,1,wk1d_a,wk1d_b, &
4152 : 4246621 : & trig3,aft3,now3,bef3,one,ind3,ic3)
4153 : : end do
4154 : : !$OMP END PARALLEL DO
4155 : :
4156 : : end if ! if(option/=3)
4157 : :
4158 : : ! Do-loop on the planes stacked in the z direction
4159 : : !$OMP PARALLEL DEFAULT(PRIVATE) &
4160 : : !$OMP&SHARED(aft1,aft2,aft4,aft5,bef1,bef2,bef4,bef5,cplex,denpot) &
4161 : : !$OMP&SHARED(fftcache,fofr,gboundin,gboundout)&
4162 : : !$OMP&SHARED(ic1,ic2,ic4,ic5,ind1,ind2,ind4) &
4163 : : !$OMP&SHARED(ind5,indpw_kin,indpw_kout,mgb,n1,n2,n3,n4,n5,ngbin) &
4164 : : !$OMP&SHARED(ngbout,now1,now2,now4,now5,option,trig1,trig2,trig4,trig5) &
4165 : : !$OMP&SHARED(weight_r,weight_i,wk1d_a,wk1d_b)
4166 : :
4167 : : ! Allocate two 2-dimensional work arrays
4168 [ - + + - : 4373132 : ABI_MALLOC(wk2d_a,(2,n4,n5,1))
- + + - +
- + - - +
- + ]
4169 [ - + + - : 3279849 : ABI_MALLOC(wk2d_b,(2,n4,n5,1))
- + + - -
+ - + ]
4170 : : !$OMP DO
4171 [ + + ]: 19193402 : do i3=1,n3
4172 : :
4173 [ + + ]: 18100119 : if(option/=3)then
4174 : : ! Zero the values on the current plane
4175 : : ! wk2d_a(1:2,1:n1,1:n2,1)=zero
4176 [ + + ]: 312441000 : do i2=1,n2
4177 [ + + ]: 5265756293 : do i1=1,n1
4178 : 4953315293 : wk2d_a(1,i1,i2,1)=zero
4179 : 5247657624 : wk2d_a(2,i1,i2,1)=zero
4180 : : end do
4181 : : end do
4182 : : ! Copy the data in the current plane
4183 [ + + ]: 647777247 : do igb=1,ngbin
4184 : 629678578 : i1=indpw_kin(1,igb) ; i2=indpw_kin(2,igb)
4185 : 629678578 : wk2d_a(1,i1,i2,1)=wk1d_b(1,igb,i3,1)
4186 : 647777247 : wk2d_a(2,i1,i2,1)=wk1d_b(2,igb,i3,1)
4187 : : end do
4188 : : ! Perform x transform, taking into account arrays of zeros
4189 : 18098669 : g2min=gboundin(3,1) ; g2max=gboundin(4,1)
4190 [ + - ]: 18098669 : if ( g2min+n2 >= g2max+2 ) then
4191 [ + + ]: 188349504 : do i2=g2max+2,g2min+n2
4192 [ + + ]: 3039458791 : do i1=1,n1
4193 : 2851109287 : wk2d_b(1,i1,i2,1)=zero
4194 : 3021360122 : wk2d_b(2,i1,i2,1)=zero
4195 : : end do
4196 : : end do
4197 : : end if
4198 : 18098669 : gbound_dum(1)=1 ; gbound_dum(2)=1
4199 : 18098669 : gbound_dum(3)=g2min ; gbound_dum(4)=g2max
4200 : : call sg_fftpx(fftcache,mfac,mg,0,n4,n5,1,n2,1,wk2d_a,wk2d_b,&
4201 : 18098669 : & trig1,aft1,now1,bef1,one,ind1,ic1,gbound_dum)
4202 : : ! Perform y transform
4203 : 18098669 : n1i=1
4204 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,n1i,n1,1,1,wk2d_b,wk2d_a, &
4205 : 18098669 : & trig2,aft2,now2,bef2,one,ind2,ic2)
4206 : : ! The wave function is now in real space, for the current plane
4207 : : end if
4208 : :
4209 [ + + ]: 18100119 : if(option==0)then ! Copy the transformed function at the right place
4210 [ + + ]: 63675490 : do i2=1,n2
4211 [ + + ]: 962390250 : do i1=1,n1
4212 : 898714760 : fofr(1,i1,i2,i3)=wk2d_a(1,i1,i2,1)
4213 : 958330540 : fofr(2,i1,i2,i3)=wk2d_a(2,i1,i2,1)
4214 : : end do
4215 : : end do
4216 : : end if
4217 : :
4218 [ + + ]: 18100119 : if(option==1)then ! Accumulate density
4219 [ + + ]: 14349936 : do i2=1,n2
4220 [ + + ]: 276920964 : do i1=1,n1
4221 : 276178104 : denpot(i1,i2,i3)=denpot(i1,i2,i3)+weight_r*wk2d_a(1,i1,i2,1)**2+weight_i*wk2d_a(2,i1,i2,1)**2
4222 : : end do
4223 : : end do
4224 : : end if
4225 : :
4226 [ + + ]: 18100119 : if(option==2)then ! Apply local potential
4227 [ + + ]: 13296099 : if(cplex==1)then
4228 [ + + ]: 208807794 : do i2=1,n2
4229 [ + + ]: 3606994739 : do i1=1,n1
4230 : 3398186945 : wk2d_a(1,i1,i2,1)=denpot(i1,i2,i3)*wk2d_a(1,i1,i2,1)
4231 : 3595217700 : wk2d_a(2,i1,i2,1)=denpot(i1,i2,i3)*wk2d_a(2,i1,i2,1)
4232 : : end do
4233 : : end do
4234 : : else
4235 [ + + ]: 25607780 : do i2=1,n2
4236 [ + + ]: 419450340 : do i1=1,n1
4237 : 393842560 : wkre=wk2d_a(1,i1,i2,1)
4238 : 393842560 : wkim=wk2d_a(2,i1,i2,1)
4239 : 393842560 : wk2d_a(1,i1,i2,1)=denpot(2*i1-1,i2,i3)*wkre -denpot(2*i1 ,i2,i3)*wkim
4240 : 417931280 : wk2d_a(2,i1,i2,1)=denpot(2*i1-1,i2,i3)*wkim +denpot(2*i1 ,i2,i3)*wkre
4241 : : end do
4242 : : end do
4243 : : end if
4244 : : end if
4245 : :
4246 [ + + ]: 18100119 : if(option==3)then ! Copy the function to be tranformed at the right place
4247 [ + + ]: 141950 : do i2=1,n2
4248 [ + + ]: 13786950 : do i1=1,n1
4249 : 13645000 : wk2d_a(1,i1,i2,1)=fofr(1,i1,i2,i3)
4250 : 13785500 : wk2d_a(2,i1,i2,1)=fofr(2,i1,i2,i3)
4251 : : end do
4252 : : end do
4253 : : end if
4254 : :
4255 [ + + ]: 19193402 : if(option==2 .or. option==3)then ! Perform y transform
4256 : 13297549 : n1i=1
4257 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,n1i,n1,1,1,wk2d_a,wk2d_b, &
4258 : 13297549 : & trig5,aft5,now5,bef5,-one,ind5,ic5)
4259 : : ! Perform x transform, taking into account arrays of zeros
4260 : 13297549 : gbound_dum(1)=1 ; gbound_dum(2)=1
4261 : 13297549 : gbound_dum(3)=gboundout(3,1) ; gbound_dum(4)=gboundout(4,1)
4262 : : call sg_fftpx(fftcache,mfac,mg,0,n4,n5,1,n2,1,wk2d_b,wk2d_a,&
4263 : 13297549 : & trig4,aft4,now4,bef4,-one,ind4,ic4,gbound_dum)
4264 : : ! Copy the data from the current plane to wk1d_b
4265 [ + + ]: 507115879 : do igb=1,ngbout
4266 : 493818330 : i1=indpw_kout(1,igb) ; i2=indpw_kout(2,igb)
4267 : 493818330 : wk1d_b(1,igb,i3,1)=wk2d_a(1,i1,i2,1)
4268 : 507115879 : wk1d_b(2,igb,i3,1)=wk2d_a(2,i1,i2,1)
4269 : : end do
4270 : : end if
4271 : :
4272 : : ! End loop on planes
4273 : : end do
4274 : : !$OMP END DO
4275 [ - + ]: 1093283 : ABI_FREE(wk2d_a)
4276 [ - + ]: 1093283 : ABI_FREE(wk2d_b)
4277 : : !$OMP END PARALLEL
4278 : :
4279 [ + + ]: 1093283 : if(option==2 .or. option==3)then
4280 : :
4281 : : ! Go from wk1d_b to wk1d_a, using 1D FFTs on the z direction
4282 : : ! However, due to special packing of data, use routine ffty
4283 : : !$OMP PARALLEL DO SHARED(aft6,bef6,fftcache,ind6,ic6,lotout,mgb)&
4284 : : !$OMP&SHARED(ngbout,now6,n3,trig6,wk1d_a,wk1d_b)&
4285 : : !$OMP&PRIVATE(igb,igbmax)
4286 [ - + - - : 3198687 : do igb=1,ngbout,lotout
- + + + ]
4287 : 2421384 : igbmax=min(igb+lotout-1,ngbout)
4288 : : ! Go from wk1d_b to wk1d_a, using 1D FFTs on the z direction
4289 : : ! However, due to special packing of data, use routine ffty
4290 : : call sg_ffty(fftcache,mfac,mg,mgb,n3,1,igb,igbmax,1,1,wk1d_b,wk1d_a, &
4291 : 3198687 : & trig6,aft6,now6,bef6,-one,ind6,ic6)
4292 : :
4293 : : end do
4294 : : !$OMP END PARALLEL DO
4295 : :
4296 : : ! Transfer the data in the output array, after normalization
4297 : 777303 : norm=1.d0/dble(nfftot)
4298 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(fofgout,indpw_kout,norm,npwout,wk1d_a)
4299 [ + + ]: 116753350 : do ig=1,npwout
4300 : 115976047 : igb=indpw_kout(4,ig) ; i3=indpw_kout(3,ig)
4301 : 115976047 : fofgout(1,ig)=wk1d_a(1,igb,i3,1)*norm
4302 : 116753350 : fofgout(2,ig)=wk1d_a(2,igb,i3,1)*norm
4303 : : end do
4304 : : !$OMP END PARALLEL DO
4305 : : end if
4306 : :
4307 [ - + ]: 1093283 : ABI_FREE(wk1d_a)
4308 [ - + ]: 1093283 : ABI_FREE(wk1d_b)
4309 : :
4310 : : ! End general k-point part
4311 : : end if
4312 : :
4313 : : !------------------------------------------------------------------
4314 : : !Here, use of time-reversal symmetry
4315 : :
4316 [ + + ]: 1094206 : if(istwf_k>=2)then
4317 : :
4318 : 923 : n1half1=n1/2+1 ; n1halfm=(n1+1)/2
4319 : 923 : n2half1=n2/2+1
4320 : : ! n4half1 or n5half1 are the odd integers >= n1half1 or n2half1
4321 : 923 : n4half1=(n1half1/2)*2+1
4322 : 923 : n5half1=(n2half1/2)*2+1
4323 : : ! Note that the z transform will appear as a y transform
4324 [ - + + - : 3692 : ABI_MALLOC(wk1d_a,(2,mgb,n3,1))
- + + - +
- + - - +
- + ]
4325 [ - + + - : 2769 : ABI_MALLOC(wk1d_b,(2,mgb,n3,1))
- + + - -
+ - + ]
4326 : :
4327 [ + + ]: 923 : if(istwf_k/=2)then
4328 [ - + + - : 1401 : ABI_MALLOC(pha1,(2,n1))
+ - + - -
+ - + ]
4329 [ - + + - : 1401 : ABI_MALLOC(pha2,(2,n2))
+ - + - -
+ - + ]
4330 [ - + + - : 1401 : ABI_MALLOC(pha3,(3,n3))
+ - + - -
+ - + ]
4331 [ + + ]: 11672 : do i1=1,n1
4332 : 11205 : pha1(1,i1)=cos(dble(i1-1)*pi/dble(n1))
4333 : 11672 : pha1(2,i1)=sin(dble(i1-1)*pi/dble(n1))
4334 : : end do
4335 [ + + ]: 11462 : do i2=1,n2
4336 : 10995 : pha2(1,i2)=cos(dble(i2-1)*pi/dble(n2))
4337 : 11462 : pha2(2,i2)=sin(dble(i2-1)*pi/dble(n2))
4338 : : end do
4339 [ + + ]: 12022 : do i3=1,n3
4340 : 11555 : pha3(1,i3)=cos(dble(i3-1)*pi/dble(n3))
4341 : 12022 : pha3(2,i3)=sin(dble(i3-1)*pi/dble(n3))
4342 : : end do
4343 : : end if
4344 : :
4345 [ + - ]: 923 : if(option/=3)then
4346 : :
4347 : : ! Zero the components of wk1d_a
4348 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(n3,ngbin,wk1d_a)
4349 [ + + ]: 30966 : do i3=1,n3
4350 [ + + ]: 8001269 : do igb=1,ngbin
4351 : 7970303 : wk1d_a(1,igb,i3,1)=zero
4352 : 8000346 : wk1d_a(2,igb,i3,1)=zero
4353 : : end do
4354 : : end do
4355 : : !$OMP END PARALLEL DO
4356 : :
4357 : : ! Insert fofgin into the work array
4358 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(fofgin,indpw_kin,npwin,wk1d_a)
4359 [ + + ]: 2495513 : do ig=1,npwin
4360 : 2494590 : igb=indpw_kin(4,ig) ; i3=indpw_kin(3,ig)
4361 : 2494590 : wk1d_a(1,igb,i3,1)=fofgin(1,ig)
4362 : 2495513 : wk1d_a(2,igb,i3,1)=fofgin(2,ig)
4363 : : end do
4364 : : !$OMP END PARALLEL DO
4365 : :
4366 : : ! Must complete the i2=1 plane when $k_y \equiv 0$
4367 : :
4368 : : ! Take care of i1=1 when $k_x \equiv 0$
4369 [ + + ]: 923 : if(istwf_k==2)then
4370 : : ! Take care of i1=1
4371 [ + + ]: 9766 : do i3=n3/2+1,n3
4372 : 9310 : i3inv=n3+2-i3
4373 : 9310 : wk1d_a(1,1,i3,1)= wk1d_a(1,1,i3inv,1)
4374 : 9766 : wk1d_a(2,1,i3,1)=-wk1d_a(2,1,i3inv,1)
4375 : : end do
4376 [ + + ]: 467 : else if(istwf_k==4)then
4377 : : ! Take care of i1=1
4378 [ + + ]: 896 : do i3=n3/2+1,n3
4379 : 832 : i3inv=n3+1-i3
4380 : 832 : wk1d_a(1,1,i3,1)= wk1d_a(1,1,i3inv,1)
4381 : 896 : wk1d_a(2,1,i3,1)=-wk1d_a(2,1,i3inv,1)
4382 : : end do
4383 : : end if
4384 : :
4385 : : ! Now, take care of other i1 values, except i3==1 when $k_z \equiv 0$
4386 : 923 : i1max=gboundin(6,1)+1
4387 [ + + ]: 923 : if(istwf_k==2)then
4388 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(i1max,n3,wk1d_a)
4389 [ + + ]: 9100 : do igb=2,2*i1max-1
4390 : 8644 : igb_inv=2*i1max+1-igb
4391 [ + + ]: 222860 : do i3=n3/2+1,n3
4392 : 213760 : i3inv=n3+2-i3
4393 : 213760 : wk1d_a(1,igb,i3,1)= wk1d_a(1,igb_inv,i3inv,1)
4394 : 222404 : wk1d_a(2,igb,i3,1)=-wk1d_a(2,igb_inv,i3inv,1)
4395 : : end do
4396 : : end do
4397 : : !$OMP END PARALLEL DO
4398 : :
4399 [ + + ]: 467 : else if(istwf_k==3)then
4400 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(i1max,n3,wk1d_a)
4401 [ + + ]: 755 : do igb=1,2*i1max
4402 : 690 : igb_inv=2*i1max+1-igb
4403 [ + + ]: 17795 : do i3=n3/2+1,n3
4404 : 17040 : i3inv=n3+2-i3
4405 : 17040 : wk1d_a(1,igb,i3,1)= wk1d_a(1,igb_inv,i3inv,1)
4406 : 17730 : wk1d_a(2,igb,i3,1)=-wk1d_a(2,igb_inv,i3inv,1)
4407 : : end do
4408 : : end do
4409 : : !$OMP END PARALLEL DO
4410 : :
4411 [ + + ]: 402 : else if(istwf_k==4)then
4412 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(i1max,n3,wk1d_a)
4413 [ + + ]: 748 : do igb=2,2*i1max-1
4414 : 684 : igb_inv=2*i1max+1-igb
4415 [ + + ]: 17740 : do i3=n3/2+1,n3
4416 : 16992 : i3inv=n3+1-i3
4417 : 16992 : wk1d_a(1,igb,i3,1)= wk1d_a(1,igb_inv,i3inv,1)
4418 : 17676 : wk1d_a(2,igb,i3,1)=-wk1d_a(2,igb_inv,i3inv,1)
4419 : : end do
4420 : : end do
4421 : : !$OMP END PARALLEL DO
4422 : :
4423 [ + + ]: 338 : else if(istwf_k==5)then
4424 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(i1max,n3,wk1d_a)
4425 [ + + ]: 790 : do igb=1,2*i1max
4426 : 720 : igb_inv=2*i1max+1-igb
4427 [ + + ]: 18070 : do i3=n3/2+1,n3
4428 : 17280 : i3inv=n3+1-i3
4429 : 17280 : wk1d_a(1,igb,i3,1)= wk1d_a(1,igb_inv,i3inv,1)
4430 : 18000 : wk1d_a(2,igb,i3,1)=-wk1d_a(2,igb_inv,i3inv,1)
4431 : : end do
4432 : : end do
4433 : : !$OMP END PARALLEL DO
4434 : :
4435 : : end if
4436 : :
4437 : : ! Now, i3==1
4438 [ + + ]: 923 : if(istwf_k==2)then
4439 [ + + ]: 4778 : do igb=2,i1max
4440 : 4322 : igb_inv=2*i1max+1-igb
4441 : 4322 : wk1d_a(1,igb_inv,1,1)= wk1d_a(1,igb,1,1)
4442 : 4778 : wk1d_a(2,igb_inv,1,1)=-wk1d_a(2,igb,1,1)
4443 : : end do
4444 [ + + ]: 467 : else if(istwf_k==3)then
4445 [ + + ]: 410 : do igb=1,i1max
4446 : 345 : igb_inv=2*i1max+1-igb
4447 : 345 : wk1d_a(1,igb_inv,1,1)= wk1d_a(1,igb,1,1)
4448 : 410 : wk1d_a(2,igb_inv,1,1)=-wk1d_a(2,igb,1,1)
4449 : : end do
4450 : : end if
4451 : :
4452 : : ! Go from wk1d_a to wk1d_b, using 1D FFTs on the z direction
4453 : : ! However, due to special packing of data, use routine ffty
4454 : : !$OMP PARALLEL DO SHARED(aft3,bef3,fftcache,ind3,ic3,lotin,mgb)&
4455 : : !$OMP&SHARED(ngbin,now3,n3,trig3,wk1d_a,wk1d_b)&
4456 : : !$OMP&PRIVATE(igb,igbmax)
4457 [ - + - - : 28173 : do igb=1,ngbin,lotin
- + + + ]
4458 : 27250 : igbmax=min(igb+lotin-1,ngbin)
4459 : : ! Go from wk1d_a to wk1d_b, using 1D FFTs on the z direction
4460 : : ! However, due to special packing of data, use routine ffty
4461 : : call sg_ffty(fftcache,mfac,mg,mgb,n3,1,igb,igbmax,1,1,wk1d_a,wk1d_b, &
4462 : 28173 : & trig3,aft3,now3,bef3,one,ind3,ic3)
4463 : : end do
4464 : : !$OMP END PARALLEL DO
4465 : :
4466 : : ! Change the phase if $k_z \neq 0$
4467 [ + + ]: 923 : if(istwf_k==4 .or. istwf_k==5 .or. istwf_k==8 .or. istwf_k==9 )then
4468 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(ngbin,n3,pha3,wk1d_b)
4469 [ + + ]: 6904 : do i3=1,n3
4470 : 6635 : phar=pha3(1,i3)
4471 : 6635 : phai=pha3(2,i3)
4472 [ + + ]: 1608459 : do igb=1,ngbin
4473 : 1601555 : ar=wk1d_b(1,igb,i3,1)
4474 : 1601555 : ai=wk1d_b(2,igb,i3,1)
4475 : 1601555 : wk1d_b(1,igb,i3,1)=phar*ar-phai*ai
4476 : 1608190 : wk1d_b(2,igb,i3,1)=phai*ar+phar*ai
4477 : : end do
4478 : : end do
4479 : : !$OMP END PARALLEL DO
4480 : : end if
4481 : :
4482 : : end if ! if(option/=3)
4483 : :
4484 : : ! Do-loop on the planes stacked in the z direction
4485 : :
4486 : : !$OMP PARALLEL DEFAULT(PRIVATE) &
4487 : : !$OMP&SHARED(aft1,aft2,aft4,aft5,bef1,bef2,bef4,bef5,denpot) &
4488 : : !$OMP&SHARED(fftcache,fofr,gboundin,ic1,ic2,ic4,ic5,ind1,ind2,ind4,ind5) &
4489 : : !$OMP&SHARED(indpw_kin,indpw_kout,istwf_k,mgb,n1,n1half1) &
4490 : : !$OMP&SHARED(n1halfm,n2,n2half1,n3,n4,n5,ngbin,ngbout) &
4491 : : !$OMP&SHARED(now1,now2,now4,now5,option,pha1,pha2,trig1) &
4492 : : !$OMP&SHARED(trig2,trig4,trig5,weight_r,weight_i,wk1d_a,wk1d_b)
4493 : :
4494 : : ! Allocate two 2-dimensional work arrays
4495 [ - + + - : 3692 : ABI_MALLOC(wk2d_a,(2,n4,n5,1))
- + + - +
- + - - +
- + ]
4496 [ - + + - : 2769 : ABI_MALLOC(wk2d_b,(2,n4,n5,1))
- + + - -
+ - + ]
4497 [ + - - + : 3692 : ABI_MALLOC(wk2d_c,(2,2*n1halfm,n5,1))
+ - - + +
- + - + -
- + - + ]
4498 [ - + + - : 2769 : ABI_MALLOC(wk2d_d,(2,2*n1halfm,n5,1))
- + + - -
+ - + ]
4499 : : !$OMP DO
4500 [ + + ]: 30966 : do i3=1,n3
4501 : :
4502 : 30043 : g2max=gboundin(4,1)
4503 : :
4504 [ + - ]: 30043 : if(option/=3)then
4505 : : ! Zero the values on the current plane : need only from i2=1 to g2max+1
4506 [ + + ]: 360827 : do i2=1,g2max+1
4507 [ + + ]: 21292195 : do i1=1,n1
4508 : 20931368 : wk2d_a(1,i1,i2,1)=zero
4509 : 21262152 : wk2d_a(2,i1,i2,1)=zero
4510 : : end do
4511 : : end do
4512 : :
4513 : : ! Copy the data in the current plane
4514 [ + + ]: 8000346 : do igb=1,ngbin
4515 : 7970303 : i1=indpw_kin(1,igb) ; i2=indpw_kin(2,igb)
4516 : 7970303 : wk2d_a(1,i1,i2,1)=wk1d_b(1,igb,i3,1)
4517 : 8000346 : wk2d_a(2,i1,i2,1)=wk1d_b(2,igb,i3,1)
4518 : : end do
4519 : :
4520 : : ! Perform x transform, taking into account arrays of zeros
4521 : : call sg_fftx(fftcache,mfac,mg,n4,n5,1,g2max+1,1,wk2d_a,wk2d_b,&
4522 : 30043 : & trig1,aft1,now1,bef1,one,ind1,ic1)
4523 : :
4524 : : ! Change the phase if $k_x \neq 0$
4525 [ + + ]: 30043 : if(istwf_k==3 .or. istwf_k==5 .or. istwf_k==7 .or. istwf_k==9)then
4526 [ + + ]: 298400 : do i1=1,n1
4527 : 291750 : phar=pha1(1,i1)
4528 : 291750 : phai=pha1(2,i1)
4529 [ + + ]: 4559525 : do i2=1,g2max+1
4530 : 4261125 : ar=wk2d_b(1,i1,i2,1)
4531 : 4261125 : ai=wk2d_b(2,i1,i2,1)
4532 : 4261125 : wk2d_b(1,i1,i2,1)=phar*ar-phai*ai
4533 : 4552875 : wk2d_b(2,i1,i2,1)=phai*ar+phar*ai
4534 : : end do
4535 : : end do
4536 : : end if
4537 : :
4538 : : ! Compute symmetric and antisymmetric combinations
4539 [ + + ]: 30043 : if(istwf_k>=2 .and. istwf_k<=5)then
4540 [ + + ]: 601436 : do i1=1,n1half1-1
4541 : 578013 : wk2d_a(1,i1,1,1)=wk2d_b(1,2*i1-1,1,1)
4542 : 601436 : wk2d_a(2,i1,1,1)=wk2d_b(1,2*i1 ,1,1)
4543 : : end do
4544 : : ! If n1 odd, must add last data
4545 [ + + ]: 23423 : if((2*n1half1-2)/=n1)then
4546 : 6135 : wk2d_a(1,n1half1,1,1)=wk2d_b(1,n1,1,1)
4547 : 6135 : wk2d_a(2,n1half1,1,1)=zero
4548 : : end if
4549 : : ii2=2
4550 : : else
4551 : : ii2=1
4552 : : end if
4553 [ + - ]: 30043 : if( g2max+1 >= ii2)then
4554 [ + + ]: 337404 : do i2=ii2,g2max+1
4555 [ + + ]: 10127032 : do i1=1,n1half1-1
4556 : 9819671 : wk2d_a(1,i1,i2,1)= wk2d_b(1,2*i1-1,i2,1)-wk2d_b(2,2*i1,i2,1)
4557 : 9819671 : wk2d_a(2,i1,i2,1)= wk2d_b(2,2*i1-1,i2,1)+wk2d_b(1,2*i1,i2,1)
4558 : 9819671 : wk2d_a(1,i1,n2+ii2-i2,1)= wk2d_b(1,2*i1-1,i2,1)+wk2d_b(2,2*i1,i2,1)
4559 : 10127032 : wk2d_a(2,i1,n2+ii2-i2,1)=-wk2d_b(2,2*i1-1,i2,1)+wk2d_b(1,2*i1,i2,1)
4560 : : end do
4561 [ + + ]: 337404 : if((2*n1half1-2)/=n1)then
4562 : 129865 : wk2d_a(1,n1half1,i2,1)= wk2d_b(1,n1,i2,1)
4563 : 129865 : wk2d_a(2,n1half1,i2,1)= wk2d_b(2,n1,i2,1)
4564 : 129865 : wk2d_a(1,n1half1,n2+ii2-i2,1)= wk2d_b(1,n1,i2,1)
4565 : 129865 : wk2d_a(2,n1half1,n2+ii2-i2,1)=-wk2d_b(2,n1,i2,1)
4566 : : end if
4567 : : end do
4568 : : end if
4569 [ + - ]: 30043 : if ( n2half1 >= g2max+2 ) then
4570 [ + + ]: 407755 : do i2=g2max+2,n2half1
4571 [ + + ]: 12042944 : do i1=1,n1half1-1
4572 : 11665232 : wk2d_a(1,i1,i2,1)=zero
4573 : 11665232 : wk2d_a(2,i1,i2,1)=zero
4574 : 11665232 : wk2d_a(1,i1,n2+ii2-i2,1)=zero
4575 : 12042944 : wk2d_a(2,i1,n2+ii2-i2,1)=zero
4576 : : end do
4577 [ + + ]: 407755 : if((2*n1half1-2)/=n1)then
4578 : 163240 : wk2d_a(1,n1half1,i2,1)=zero
4579 : 163240 : wk2d_a(2,n1half1,i2,1)=zero
4580 : 163240 : wk2d_a(1,n1half1,n2+ii2-i2,1)=zero
4581 : 163240 : wk2d_a(2,n1half1,n2+ii2-i2,1)=zero
4582 : : end if
4583 : : end do
4584 : : end if
4585 : :
4586 : 30043 : n1i=1
4587 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,n1i,n1halfm,1,1,wk2d_a,wk2d_b,&
4588 : 30043 : & trig2,aft2,now2,bef2,one,ind2,ic2)
4589 : :
4590 : : ! Change the phase if $k_y \neq 0$
4591 [ + + ]: 30043 : if(istwf_k>=6 .and. istwf_k<=9)then
4592 [ + + ]: 288320 : do i2=1,n2
4593 : 281700 : phar=pha2(1,i2)
4594 : 281700 : phai=pha2(2,i2)
4595 [ + + ]: 9453920 : do i1=1,n1halfm
4596 : 9165600 : ar=wk2d_b(1,i1,i2,1)
4597 : 9165600 : ai=wk2d_b(2,i1,i2,1)
4598 : 9165600 : wk2d_b(1,i1,i2,1)= phar*ar-phai*ai
4599 : 9447300 : wk2d_b(2,i1,i2,1)= phai*ar+phar*ai
4600 : : end do
4601 : : end do
4602 : : end if
4603 : :
4604 : : end if ! option/=3
4605 : :
4606 : : ! The wave function is now in real space, for the current plane,
4607 : : ! represented by REAL numbers, although packed in the complex array wk2d_b
4608 : :
4609 : 30043 : g2max=gboundin(4,1)
4610 : :
4611 [ + + ]: 30043 : if(option==0)then
4612 : : ! This option is only permitted for istwf_k==2 (Gamma point)
4613 : : ! Copy the transformed function at the right place
4614 [ + + ]: 681364 : do i2=1,n2
4615 [ + + ]: 20170672 : do i1=1,n1half1-1
4616 : 19503836 : fofr(1,2*i1-1,i2,i3)=wk2d_b(1,i1,i2,1)
4617 : 19503836 : fofr(1,2*i1 ,i2,i3)=wk2d_b(2,i1,i2,1)
4618 : 19503836 : fofr(2,2*i1-1,i2,i3)=zero
4619 : 20170672 : fofr(2,2*i1 ,i2,i3)=zero
4620 : : end do
4621 : : ! If n1 odd, must add last data
4622 [ + + ]: 681364 : if((2*n1half1-2)/=n1)then
4623 : 28800 : fofr(1,n1,i2,i3)=wk2d_b(1,n1half1,i2,1)
4624 : 28800 : fofr(2,n1,i2,i3)=zero
4625 : : end if
4626 : : end do
4627 : : end if
4628 : :
4629 [ + + ]: 30043 : if(option==1)then ! Accumulate density
4630 [ + + ]: 314100 : do i2=1,n2
4631 [ + + ]: 11601264 : do i1=1,n1half1-1
4632 : 11292496 : denpot(2*i1-1,i2,i3)=denpot(2*i1-1,i2,i3)+weight_r*wk2d_b(1,i1,i2,1)**2
4633 : 11601264 : denpot(2*i1 ,i2,i3)=denpot(2*i1 ,i2,i3)+weight_i*wk2d_b(2,i1,i2,1)**2
4634 : : end do
4635 : : ! If n1 odd, must add last data
4636 [ + + ]: 314100 : if((2*n1half1-2)/=n1)then
4637 : 248400 : denpot(n1,i2,i3)=denpot(n1,i2,i3)+weight_r*wk2d_b(1,n1half1,i2,1)**2
4638 : : end if
4639 : : end do
4640 : : end if
4641 : :
4642 [ + + ]: 30043 : if(option==2)then ! Apply local potential
4643 [ + + ]: 403380 : do i2=1,n2
4644 [ + + ]: 12484056 : do i1=1,n1half1-1
4645 : 12090859 : wk2d_a(1,i1,i2,1)=denpot(2*i1-1,i2,i3)*wk2d_b(1,i1,i2,1)
4646 : 12484056 : wk2d_a(2,i1,i2,1)=denpot(2*i1 ,i2,i3)*wk2d_b(2,i1,i2,1)
4647 : : end do
4648 : : ! If n1 odd, must add last data
4649 [ + + ]: 403380 : if((2*n1half1-2)/=n1)then
4650 : 301725 : wk2d_a(1,n1half1,i2,1)=denpot(n1,i2,i3)*wk2d_b(1,n1half1,i2,1)
4651 : 301725 : wk2d_a(2,n1half1,i2,1)=zero
4652 : : end if
4653 : : end do
4654 : : end if
4655 : :
4656 [ - + ]: 30043 : if(option==3)then
4657 : : ! This option is only permitted for istwf_k==2 (Gamma point)
4658 : : ! Copy the transformed function at the right place
4659 [ # # ]: 0 : do i2=1,n2
4660 [ # # ]: 0 : do i1=1,n1half1-1
4661 : 0 : wk2d_b(1,i1,i2,1)=fofr(1,2*i1-1,i2,i3)
4662 : 0 : wk2d_b(2,i1,i2,1)=fofr(1,2*i1 ,i2,i3)
4663 : : end do
4664 : : ! If n1 odd, must add last data
4665 [ # # ]: 0 : if((2*n1half1-2)/=n1)then
4666 : 0 : wk2d_b(1,n1half1,i2,1)=fofr(1,n1,i2,i3)
4667 : : end if
4668 : : end do
4669 : : end if
4670 : :
4671 [ + + ]: 30966 : if(option==2 .or. option==3)then ! Change the phase if $k_y \neq 0$
4672 [ + + ]: 10183 : if(istwf_k>=6 .and. istwf_k<=9)then
4673 [ + + ]: 160480 : do i2=1,n2
4674 : 156150 : phar=pha2(1,i2)
4675 : 156150 : phai=pha2(2,i2)
4676 [ + + ]: 4865680 : do i1=1,n1halfm
4677 : 4705200 : ar=wk2d_a(1,i1,i2,1)
4678 : 4705200 : ai=wk2d_a(2,i1,i2,1)
4679 : 4705200 : wk2d_a(1,i1,i2,1)= phar*ar+phai*ai
4680 : 4861350 : wk2d_a(2,i1,i2,1)=-phai*ar+phar*ai
4681 : : end do
4682 : : end do
4683 : : end if
4684 : :
4685 : : ! Perform y transform
4686 : 10183 : n1i=1
4687 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,n1i,n1halfm,1,1,wk2d_a,wk2d_b, &
4688 : 10183 : & trig5,aft5,now5,bef5,-one,ind5,ic5)
4689 : :
4690 : : ! Decompose symmetric and antisymmetric parts
4691 [ + + ]: 10183 : if(istwf_k>=2 .and. istwf_k<=5)then
4692 [ + + ]: 131469 : do i1=1,n1halfm
4693 : 125616 : wk2d_c(1,2*i1-1,1,1)=wk2d_b(1,i1,1,1)
4694 : 125616 : wk2d_c(2,2*i1-1,1,1)=zero
4695 : 125616 : wk2d_c(1,2*i1,1,1)=wk2d_b(2,i1,1,1)
4696 : 131469 : wk2d_c(2,2*i1,1,1)=zero
4697 : : end do
4698 : : ii2=2
4699 : : else
4700 : : ii2=1
4701 : : end if
4702 [ + + ]: 97888 : do i2=ii2,g2max+1
4703 [ + + ]: 2936488 : do i1=1,n1halfm
4704 : 2838600 : wk2d_c(1,2*i1-1,i2,1)=(wk2d_b(1,i1,i2,1)+wk2d_b(1,i1,n2+ii2-i2,1))*0.5d0
4705 : 2838600 : wk2d_c(2,2*i1-1,i2,1)=(wk2d_b(2,i1,i2,1)-wk2d_b(2,i1,n2+ii2-i2,1))*0.5d0
4706 : 2838600 : wk2d_c(1,2*i1,i2,1)= ( wk2d_b(2,i1,i2,1)+wk2d_b(2,i1,n2+ii2-i2,1))*0.5d0
4707 : 2926305 : wk2d_c(2,2*i1,i2,1)= (-wk2d_b(1,i1,i2,1)+wk2d_b(1,i1,n2+ii2-i2,1))*0.5d0
4708 : : end do
4709 : : end do
4710 : :
4711 : : ! Change the phase if $k_x \neq 0$
4712 [ + + ]: 10183 : if(istwf_k==3 .or. istwf_k==5 .or. istwf_k==7 .or. istwf_k==9 )then
4713 [ + + ]: 165760 : do i1=1,n1
4714 : 161400 : phar=pha1(1,i1)
4715 : 161400 : phai=pha1(2,i1)
4716 [ + + ]: 2350660 : do i2=1,g2max+1
4717 : 2184900 : ar=wk2d_c(1,i1,i2,1)
4718 : 2184900 : ai=wk2d_c(2,i1,i2,1)
4719 : 2184900 : wk2d_c(1,i1,i2,1)= phar*ar+phai*ai
4720 : 2346300 : wk2d_c(2,i1,i2,1)=-phai*ar+phar*ai
4721 : : end do
4722 : : end do
4723 : : end if
4724 : :
4725 : : ! Perform x transform : for y=1 to g2max+1, to benefit from zeros
4726 : : call sg_fftx(fftcache,mfac,mg,2*n1halfm,n5,1,g2max+1,1,wk2d_c,wk2d_d,&
4727 : 10183 : & trig4,aft4,now4,bef4,-one,ind4,ic4)
4728 : :
4729 : : ! Copy the data from the current plane to wk1d_b
4730 [ + + ]: 2206511 : do igb=1,ngbout
4731 : 2196328 : i1=indpw_kout(1,igb) ; i2=indpw_kout(2,igb)
4732 : 2196328 : wk1d_b(1,igb,i3,1)=wk2d_d(1,i1,i2,1)
4733 : 2206511 : wk1d_b(2,igb,i3,1)=wk2d_d(2,i1,i2,1)
4734 : : end do
4735 : :
4736 : : end if ! option==2 or 3
4737 : :
4738 : : ! End loop on planes
4739 : : end do
4740 : :
4741 : : !$OMP END DO
4742 [ - + ]: 923 : ABI_FREE(wk2d_a)
4743 [ - + ]: 923 : ABI_FREE(wk2d_b)
4744 [ - + ]: 923 : ABI_FREE(wk2d_c)
4745 [ - + ]: 923 : ABI_FREE(wk2d_d)
4746 : : !$OMP END PARALLEL
4747 : :
4748 [ + + ]: 923 : if(option==2 .or. option==3)then
4749 : :
4750 : : ! Change the phase if $k_z \neq 0$
4751 [ + + ]: 426 : if(istwf_k==4 .or. istwf_k==5 .or. istwf_k==8 .or. istwf_k==9 )then
4752 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(ngbout,n3,pha3,wk1d_b)
4753 [ + + ]: 4548 : do i3=1,n3
4754 : 4345 : phar=pha3(1,i3)
4755 : 4345 : phai=pha3(2,i3)
4756 [ + + ]: 822538 : do igb=1,ngbout
4757 : 817990 : ar=wk1d_b(1,igb,i3,1)
4758 : 817990 : ai=wk1d_b(2,igb,i3,1)
4759 : 817990 : wk1d_b(1,igb,i3,1)= phar*ar+phai*ai
4760 : 822335 : wk1d_b(2,igb,i3,1)=-phai*ar+phar*ai
4761 : : end do
4762 : : end do
4763 : : !$OMP END PARALLEL DO
4764 : : end if
4765 : :
4766 : : ! Go from wk1d_b to wk1d_a, using 1D FFTs on the z direction
4767 : : ! However, due to special packing of data, use routine ffty
4768 : : !$OMP PARALLEL DO SHARED(aft6,bef6,fftcache,ind6,ic6,lotout,mgb)&
4769 : : !$OMP&SHARED(ngbout,now6,n3,trig6,wk1d_a,wk1d_b)&
4770 : : !$OMP&PRIVATE(igb,igbmax)
4771 [ - + - - : 7695 : do igb=1,ngbout,lotout
- + + + ]
4772 : 7269 : igbmax=min(igb+lotout-1,ngbout)
4773 : : ! Go from wk1d_b to wk1d_a, using 1D FFTs on the z direction
4774 : : ! However, due to special packing of data, use routine ffty
4775 : : call sg_ffty(fftcache,mfac,mg,mgb,n3,1,igb,igbmax,1,1,wk1d_b,wk1d_a, &
4776 : 7695 : & trig6,aft6,now6,bef6,-one,ind6,ic6)
4777 : :
4778 : : end do
4779 : : !$OMP END PARALLEL DO
4780 : :
4781 : : ! Transfer the data in the output array, after normalization
4782 : 426 : norm=1.d0/dble(nfftot)
4783 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(fofgout,indpw_kout,norm,npwout,wk1d_a)
4784 [ + + ]: 688937 : do ig=1,npwout
4785 : 688511 : igb=indpw_kout(4,ig) ; i3=indpw_kout(3,ig)
4786 : 688511 : fofgout(1,ig)=wk1d_a(1,igb,i3,1)*norm
4787 : 688937 : fofgout(2,ig)=wk1d_a(2,igb,i3,1)*norm
4788 : : end do
4789 : : !$OMP END PARALLEL DO
4790 : :
4791 : : end if
4792 : :
4793 [ - + ]: 923 : ABI_FREE(wk1d_a)
4794 [ - + ]: 923 : ABI_FREE(wk1d_b)
4795 : :
4796 [ + + ]: 923 : if(istwf_k/=2)then
4797 [ - + ]: 467 : ABI_FREE(pha1)
4798 [ - + ]: 467 : ABI_FREE(pha2)
4799 [ - + ]: 467 : ABI_FREE(pha3)
4800 : : end if
4801 : :
4802 : : end if ! End time-reversal symmetry
4803 : :
4804 : : !------------------------------------------------------------------
4805 : :
4806 [ + + ]: 1094206 : if(option/=3) then
4807 [ - + ]: 1094191 : ABI_FREE(indpw_kin)
4808 : : end if
4809 [ + + ]: 1094206 : if(option==2 .or. option==3) then
4810 [ - + ]: 777729 : ABI_FREE(indpw_kout)
4811 : : end if
4812 : :
4813 [ - + - + : 1094206 : end subroutine fftrisc_one_nothreadsafe
- + - + -
+ ]
4814 : : !!***
4815 : :
4816 : : !----------------------------------------------------------------------
4817 : :
4818 : : !!****f* m_sgfft/sg_fftrisc_2
4819 : : !! NAME
4820 : : !! sg_fftrisc_2
4821 : : !!
4822 : : !! FUNCTION
4823 : : !! Carry out Fourier transforms between real and reciprocal (G) space,
4824 : : !! for wavefunctions, contained in a sphere in reciprocal space,
4825 : : !! in both directions. Also accomplish some post-processing.
4826 : : !! if luse_ndo is activated, do two FFT, and compute the density with
4827 : : !! non-diagonal occupations.
4828 : : !!
4829 : : !! NOTES
4830 : : !! * Specifically uses rather sophisticated algorithms, based on S Goedecker
4831 : : !! routines, specialized for superscalar RISC architecture.
4832 : : !! Zero padding : saves 7/12 execution time
4833 : : !! Bi-dimensional data locality in most of the routine : cache reuse
4834 : : !! For k-point (0 0 0) : takes advantage of symmetry of data.
4835 : : !! Note however that no blocking is used, in both 1D z-transform
4836 : : !! or subsequent 2D transform. This should be improved.
4837 : : !!
4838 : : !! * This routine is not thread-safe due to the presence of variables with the save attribute!
4839 : : !! DO NOT CALL THIS ROUTINE INSIDE A OPENMP PARALLEL REGION
4840 : : !!
4841 : : !! INPUTS
4842 : : !! cplex= if 1 , denpot is real, if 2 , denpot is complex
4843 : : !! (cplex=2 only allowed for option=2 when istwf_k=1)
4844 : : !! one can also use cplex=0 if option=0 or option=3
4845 : : !! fofgin(2,npwin)=holds input wavefunction in G vector basis sphere.
4846 : : !! fofgin_p(2,npwin) (optional) =holds second input wavefunction in G vector basis sphere.
4847 : : !! gboundin(2*mgfft+8,2)=sphere boundary info for reciprocal to real space
4848 : : !! gboundout(2*mgfft+8,2)=sphere boundary info for real to reciprocal space
4849 : : !! istwf_k=option parameter that describes the storage of wfs
4850 : : !! kg_kin(3,npwin)=reduced planewave coordinates, input
4851 : : !! kg_kout(3,npwout)=reduced planewave coordinates, output
4852 : : !! luse_ndo (optional) = use non diagonal occup (in this case, exists fofgin_p)
4853 : : !! npwin=number of elements in fofgin array (for option 0, 1 and 2)
4854 : : !! npwout=number of elements in fofgout array (for option 2 and 3)
4855 : : !! mgfft=maximum size of 1D FFTs
4856 : : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
4857 : : !! n4,n5,n6=ngfft(4),ngfft(5),ngfft(6), dimensions of fofr.
4858 : : !! option= if 0: do direct FFT
4859 : : !! if 1: do direct FFT, then sum the density
4860 : : !! if 2: do direct FFT, multiply by the potential, then do reverse FFT
4861 : : !! if 3: do reverse FFT only
4862 : : !! weight=weight to be used for the accumulation of the density in real space
4863 : : !! (needed only when option=1)
4864 : : !!
4865 : : !! OUTPUT
4866 : : !! (see side effects)
4867 : : !!
4868 : : !! OPTIONS
4869 : : !! The different options are:
4870 : : !! - reciprocal to real space and output the result (when option=0),
4871 : : !! - reciprocal to real space and accumulate the density (when option=1) or
4872 : : !! - reciprocal to real space, apply the local potential to the wavefunction
4873 : : !! in real space and produce the result in reciprocal space (when option=2)
4874 : : !! - real space to reciprocal space (when option=3).
4875 : : !! option=0 IS NOT ALLOWED when istwf_k>2
4876 : : !! option=3 IS NOT ALLOWED when istwf_k>=2
4877 : : !! (this version can be used to compute fft of two wavefunction and
4878 : : !! compute the product in denpot)
4879 : : !!
4880 : : !! SIDE EFFECTS
4881 : : !! for option==0, fofgin(2,npwin)=holds input wavefunction in G sphere;
4882 : : !! fofr(2,n4,n5,n6) contains the Fourier Transform of fofgin;
4883 : : !! no use of denpot, fofgout and npwout.
4884 : : !! for option==1, fofgin(2,npwin)=holds input wavefunction in G sphere;
4885 : : !! denpot(cplex*n4,n5,n6) contains the input density at input,
4886 : : !! and the updated density at output;
4887 : : !! fofr(2,n4,n5,n6) contains the Fourier transform of fofgin,
4888 : : !! except in the case of the hp library subroutine;
4889 : : !! no use of fofgout and npwout.
4890 : : !! for option==2, fofgin(2,npwin)=holds input wavefunction in G sphere;
4891 : : !! denpot(cplex*n4,n5,n6) contains the input local potential;
4892 : : !! fofgout(2,npwout) contains the output function;
4893 : : !! fofr(2,n4,n5,n6) contains the Fourier transform of fofgin,
4894 : : !! except in the case of the hp library subroutine.
4895 : : !! for option==3, fofr(2,n4,n5,n6) contains the real space wavefunction;
4896 : : !! fofgout(2,npwout) contains its Fourier transform;
4897 : : !! no use of fofgin and npwin.
4898 : : !!
4899 : : !! TODO
4900 : : !! Complete input and output list.
4901 : : !!
4902 : : !! SOURCE
4903 : :
4904 : 66020 : subroutine sg_fftrisc_2(cplex,denpot,fofgin,fofgout,fofr,gboundin,gboundout,&
4905 : 33010 : & istwf_k,kg_kin,kg_kout,&
4906 : : & mgfft,ngfft,npwin,npwout,n4,n5,n6,option,weight_r,weight_2,&
4907 [ + - + - : 33010 : & luse_ndo,fofgin_p) ! optional
- + ]
4908 : :
4909 : : !Arguments ------------------------------------
4910 : : !scalars
4911 : : integer,intent(in) :: cplex,istwf_k,mgfft,n4,n5,n6,npwin,npwout,option
4912 : : real(dp),intent(in) :: weight_r
4913 : : real(dp),intent(in),optional :: weight_2
4914 : : !arrays
4915 : : integer,intent(in) :: gboundin(2*mgfft+8,2),gboundout(2*mgfft+8,2)
4916 : : integer,intent(in) :: kg_kin(3,npwin),kg_kout(3,npwout),ngfft(18)
4917 : : logical,intent(in),optional :: luse_ndo
4918 : : real(dp),intent(in) :: fofgin(2,npwin)
4919 : : real(dp),intent(in),optional :: fofgin_p(:,:)
4920 : : real(dp),intent(inout) :: denpot(cplex*n4,n5,n6),fofr(2,n4,n5,n6)
4921 : : real(dp),intent(out) :: fofgout(2,npwout)
4922 : :
4923 : : !Local variables-------------------------------
4924 : : !scalars
4925 : : integer,parameter :: mfac=11
4926 : : integer,save :: ic1,ic2,ic3,ic4,ic5,ic6,n1_save=0,n2_save=0,n3_save=0
4927 : : integer :: fftcache,g2max,g2min,i1,i1max,i2,i3,i3inv,ig,igb
4928 : : integer :: igb_inv,igbmax,ii2,lot,lotin,lotout,mgb,n1
4929 : : integer :: n1half1,n1halfm,n1i,n2,n2half1,n3,n4half1,n5half1,nfftot,ngbin
4930 : : integer :: ngbout,nlot,nproc_omp
4931 : : integer :: weight_i
4932 : : real(dp) :: ai,ar,fraction,norm,phai,phar,wkim,wkre
4933 : : character(len=500) :: message
4934 : : !arrays
4935 : : integer,save :: aft1(mfac),aft2(mfac),aft3(mfac),aft4(mfac),aft5(mfac)
4936 : : integer,save :: aft6(mfac),bef1(mfac),bef2(mfac),bef3(mfac),bef4(mfac)
4937 : : integer,save :: bef5(mfac),bef6(mfac),ind1(mg),ind2(mg),ind3(mg),ind4(mg)
4938 : : integer,save :: ind5(mg),ind6(mg),now1(mfac),now2(mfac),now3(mfac),now4(mfac)
4939 : : integer,save :: now5(mfac),now6(mfac)
4940 : : integer :: gbound_dum(4)
4941 : 33010 : integer,allocatable :: indpw_kin(:,:),indpw_kout(:,:)
4942 : : logical :: lluse_ndo
4943 : : real(dp),save :: trig1(2,mg),trig2(2,mg),trig3(2,mg),trig4(2,mg),trig5(2,mg)
4944 : : real(dp),save :: trig6(2,mg)
4945 : 33010 : real(dp),allocatable :: pha1(:,:),pha2(:,:),pha3(:,:),wk1d_a(:,:,:,:)
4946 : 33010 : real(dp),allocatable :: wk1d_b(:,:,:,:),wk2d_a(:,:,:,:),wk2d_b(:,:,:,:)
4947 : 33010 : real(dp),allocatable :: wk2d_c(:,:,:,:),wk2d_d(:,:,:,:)
4948 : 33010 : real(dp),allocatable :: wk1d_a_p(:,:,:,:),wk1d_b_p(:,:,:,:)
4949 : 33010 : real(dp),allocatable :: wk2d_a_p(:,:,:,:),wk2d_b_p(:,:,:,:)
4950 : : #if defined HAVE_OPENMP
4951 : : integer,external :: OMP_GET_NUM_THREADS
4952 : : #endif
4953 : :
4954 : : ! *************************************************************************
4955 : :
4956 : : !DBG_ENTER("COLL")
4957 : :
4958 : : !DEBUG
4959 : : !write(std_out,*)' sg_fftrisc_2 : enter, istwf_k= ',istwf_k
4960 : : !write(std_out,*)' sg_fftrisc_2 : option,mgfft=',option,mgfft
4961 : : !write(std_out,*)' sg_fftrisc_2 : gboundin(3:2*mgfft+6,1)='
4962 : : !do ii=1,mgfft+2
4963 : : !write(std_out,*)gboundin(2*ii+1,1),gboundin(2*ii+2,1)
4964 : : !end do
4965 : : !stop
4966 : : !ENDDEBUG
4967 : : !
4968 : 33010 : lluse_ndo=.true.
4969 [ - + ]: 33010 : if(istwf_k/=1)then
4970 : 0 : write(message,'(a,i0)' )' It is not yet allowed to use dmft with istwf_k=',istwf_k
4971 : 0 : ABI_BUG(message)
4972 : : end if
4973 : :
4974 [ - + - - ]: 33010 : if(istwf_k>2 .and. option==0)then
4975 : 0 : write(message, '(a,i0)' )' It is not allowed to use option=0 with istwf_k=',istwf_k
4976 : 0 : ABI_BUG(message)
4977 : : end if
4978 : :
4979 [ - + - - ]: 33010 : if(istwf_k>=2 .and. option==3)then
4980 : 0 : write(message, '(a,i0)' )' It is not allowed to use option=3 with istwf_k=',istwf_k
4981 : 0 : ABI_BUG(message)
4982 : : end if
4983 : :
4984 : 33010 : lluse_ndo=.false.
4985 [ + - ]: 33010 : if(present(luse_ndo).and.present(fofgin_p)) then
4986 [ + - ]: 33010 : if(luse_ndo) lluse_ndo=.true.
4987 : : end if
4988 : : if(lluse_ndo) then
4989 [ - + ]: 33010 : if((size(fofgin_p,2)==0).and.(luse_ndo)) then
4990 : : write(message, '(a,a,a,i4,i5)' )&
4991 : 0 : & 'fofgin_p has a dimension equal to zero and luse_ndo true',ch10,&
4992 : 0 : & 'Action: check dimension of fofgin_p',size(fofgin_p,2),luse_ndo
4993 : 0 : ABI_BUG(message)
4994 : : end if
4995 : : end if
4996 : :
4997 : 33010 : weight_i= weight_r
4998 [ + - ]: 33010 : if ( present (weight_2 )) then
4999 : 33010 : weight_i= weight_2
5000 [ + - - + ]: 33010 : if ( present(luse_ndo) .and. (luse_ndo) )weight_i=weight_r
5001 : : end if
5002 : :
5003 : : !For all other tests of validity of inputs, assume that they
5004 : : !have been done in the calling routine
5005 : :
5006 : 33010 : n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3) ; nfftot=n1*n2*n3
5007 : 33010 : fftcache=ngfft(8)
5008 : :
5009 [ + - ]: 33010 : if(option/=3)then
5010 [ - + + - : 99030 : ABI_MALLOC(indpw_kin,(4,npwin))
+ - + - -
+ - + ]
5011 : 33010 : call indfftrisc(gboundin(3:3+2*mgfft+4,1),indpw_kin,kg_kin,mgfft,ngbin,ngfft,npwin)
5012 : : end if
5013 [ - + ]: 33010 : if(option==2 .or. option==3)then
5014 [ # # # # : 0 : ABI_MALLOC(indpw_kout,(4,npwout))
# # # # #
# # # ]
5015 : 0 : call indfftrisc(gboundout(3:3+2*mgfft+4,1),indpw_kout,kg_kout,mgfft,ngbout,ngfft,npwout)
5016 : : end if
5017 : :
5018 : : !Define the dimension of the first work arrays, for 1D transforms along z ,
5019 : : !taking into account the need to avoid the cache trashing
5020 [ - + ]: 33010 : if(option==2)then
5021 : 0 : mgb=max(ngbin,ngbout)
5022 [ + - ]: 33010 : else if(option==0 .or. option==1)then
5023 : 33010 : mgb=ngbin ; ngbout=1
5024 [ # # ]: 0 : else if(option==3)then
5025 : 0 : mgb=ngbout ; ngbin=1
5026 : : end if
5027 : :
5028 [ + + ]: 33010 : if(mod(mgb,2)/=1)mgb=mgb+1
5029 : :
5030 : : !Initialise openmp, if needed
5031 : : !$OMP PARALLEL
5032 : : !$OMP SINGLE
5033 : 33010 : nproc_omp=1
5034 : : #if defined HAVE_OPENMP
5035 : : nproc_omp=OMP_GET_NUM_THREADS()
5036 : : #endif
5037 : : !$OMP END SINGLE
5038 : : !$OMP END PARALLEL
5039 : :
5040 : : !For the treatment of the z transform,
5041 : : !one tries to use only a fraction of the cache, since the
5042 : : !treatment of the array wk1d_a will not involve contiguous segments
5043 : 33010 : fraction=0.25
5044 : : !First estimation of lot and nlot
5045 : 33010 : lot=(fftcache*fraction*1000)/(n3*8*2)+1
5046 : : !Select the smallest integer multiple of nproc_omp, larger
5047 : : !or equal to nlot. In this way, the cache size is not exhausted,
5048 : : !and one takes care correctly of the number of processors.
5049 : : !Treat separately the in and out cases
5050 : 33010 : nlot=(ngbin-1)/lot+1
5051 : 33010 : nlot=nproc_omp*((nlot-1)/nproc_omp+1)
5052 : 33010 : lotin=(ngbin-1)/nlot+1
5053 : 33010 : nlot=(ngbout-1)/lot+1
5054 : 33010 : nlot=nproc_omp*((nlot-1)/nproc_omp+1)
5055 : 33010 : lotout=(ngbout-1)/nlot+1
5056 : : !The next line impose only one lot. Usually, comment it.
5057 : : !lotin=mgb ; lotout=mgb
5058 : :
5059 : : !Compute auxiliary arrays needed for FFTs
5060 [ + + ]: 33010 : if(n1/=n1_save)then
5061 : 32 : call sg_ctrig(n1,trig1,aft1,bef1,now1,one,ic1,ind1,mfac,mg)
5062 : 32 : call sg_ctrig(n1,trig4,aft4,bef4,now4,-one,ic4,ind4,mfac,mg)
5063 : 32 : n1_save=n1
5064 : : end if
5065 [ + + ]: 33010 : if(n2/=n2_save)then
5066 : 32 : call sg_ctrig(n2,trig2,aft2,bef2,now2,one,ic2,ind2,mfac,mg)
5067 : 32 : call sg_ctrig(n2,trig5,aft5,bef5,now5,-one,ic5,ind5,mfac,mg)
5068 : 32 : n2_save=n2
5069 : : end if
5070 [ + + ]: 33010 : if(n3/=n3_save)then
5071 : 32 : call sg_ctrig(n3,trig3,aft3,bef3,now3,one,ic3,ind3,mfac,mg)
5072 : 32 : call sg_ctrig(n3,trig6,aft6,bef6,now6,-one,ic6,ind6,mfac,mg)
5073 : 32 : n3_save=n3
5074 : : end if
5075 : :
5076 : : !------------------------------------------------------------------
5077 : : !Here, call general k-point code
5078 : :
5079 [ + - ]: 33010 : if(istwf_k==1)then
5080 : :
5081 : : ! Note that the z transform will appear as a y transform
5082 [ - + + - : 132040 : ABI_MALLOC(wk1d_a,(2,mgb,n3,1))
- + + - +
- + - - +
- + ]
5083 [ - + + - : 99030 : ABI_MALLOC(wk1d_b,(2,mgb,n3,1))
- + + - -
+ - + ]
5084 [ - + + - : 99030 : ABI_MALLOC(wk1d_a_p,(2,mgb,n3,1))
- + + - -
+ - + ]
5085 [ - + + - : 99030 : ABI_MALLOC(wk1d_b_p,(2,mgb,n3,1))
- + + - -
+ - + ]
5086 : :
5087 [ + - ]: 33010 : if(option/=3)then
5088 : :
5089 [ + - ]: 33010 : if(lluse_ndo) then
5090 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5091 : : !$OMP&SHARED(n3,ngbin,wk1d_a_p)
5092 [ + + ]: 833045 : do i3=1,n3
5093 [ + + ]: 45056731 : do igb=1,ngbin
5094 : 44223686 : wk1d_a_p(1,igb,i3,1)=zero
5095 : 45023721 : wk1d_a_p(2,igb,i3,1)=zero
5096 : : end do
5097 : : end do
5098 : : !$OMP END PARALLEL DO
5099 : :
5100 : : ! Insert fofgin_p into the work array
5101 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5102 : : !$OMP&SHARED(fofgin_p,indpw_kin,npwin,wk1d_a_p)
5103 [ + + ]: 10892636 : do ig=1,npwin
5104 : 10859626 : igb=indpw_kin(4,ig) ; i3=indpw_kin(3,ig)
5105 : 10859626 : wk1d_a_p(1,igb,i3,1)=fofgin_p(1,ig)
5106 : 10892636 : wk1d_a_p(2,igb,i3,1)=fofgin_p(2,ig)
5107 : : end do
5108 : : !$OMP END PARALLEL DO
5109 : :
5110 : : ! Go from wk1d_a_p to wk1d_b_p, using 1D FFTs on the z direction
5111 : : ! However, due to special packing of data, use routine ffty
5112 : : !$OMP PARALLEL DO SHARED(aft3,bef3,fftcache,ind3,ic3,lotin,mgb)&
5113 : : !$OMP&SHARED(ngbin,now3,n3,trig3,wk1d_a_p,wk1d_b_p)&
5114 : : !$OMP&PRIVATE(igb,igbmax)
5115 [ - + - - : 221139 : do igb=1,ngbin,lotin
- + + + ]
5116 : 188129 : igbmax=min(igb+lotin-1,ngbin)
5117 : : ! Go from wk1d_a_p to wk1d_b_p, using 1D FFTs on the z direction
5118 : : ! However, due to special packing of data, use routine ffty
5119 : : call sg_ffty(fftcache,mfac,mg,mgb,n3,1,igb,igbmax,1,1,wk1d_a_p,wk1d_b_p, &
5120 : 221139 : & trig3,aft3,now3,bef3,one,ind3,ic3)
5121 : : end do
5122 : : !$OMP END PARALLEL DO
5123 : :
5124 : : end if ! lluse_ndo
5125 : :
5126 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5127 : : !$OMP&SHARED(n3,ngbin,wk1d_a)
5128 [ + + ]: 833045 : do i3=1,n3
5129 [ + + ]: 45056731 : do igb=1,ngbin
5130 : 44223686 : wk1d_a(1,igb,i3,1)=zero
5131 : 45023721 : wk1d_a(2,igb,i3,1)=zero
5132 : : end do
5133 : : end do
5134 : : !$OMP END PARALLEL DO
5135 : :
5136 : : ! Insert fofgin into the work array
5137 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5138 : : !$OMP&SHARED(fofgin,indpw_kin,npwin,wk1d_a)
5139 [ + + ]: 10892636 : do ig=1,npwin
5140 : 10859626 : igb=indpw_kin(4,ig) ; i3=indpw_kin(3,ig)
5141 : 10859626 : wk1d_a(1,igb,i3,1)=fofgin(1,ig)
5142 : 10892636 : wk1d_a(2,igb,i3,1)=fofgin(2,ig)
5143 : : end do
5144 : : !$OMP END PARALLEL DO
5145 : :
5146 : : ! Go from wk1d_a to wk1d_b, using 1D FFTs on the z direction
5147 : : ! However, due to special packing of data, use routine ffty
5148 : : !$OMP PARALLEL DO SHARED(aft3,bef3,fftcache,ind3,ic3,lotin,mgb)&
5149 : : !$OMP&SHARED(ngbin,now3,n3,trig3,wk1d_a,wk1d_b)&
5150 : : !$OMP&PRIVATE(igb,igbmax)
5151 [ - + - - : 221139 : do igb=1,ngbin,lotin
- + + + ]
5152 : 188129 : igbmax=min(igb+lotin-1,ngbin)
5153 : : ! Go from wk1d_a to wk1d_b, using 1D FFTs on the z direction
5154 : : ! However, due to special packing of data, use routine ffty
5155 : : call sg_ffty(fftcache,mfac,mg,mgb,n3,1,igb,igbmax,1,1,wk1d_a,wk1d_b, &
5156 : 221139 : & trig3,aft3,now3,bef3,one,ind3,ic3)
5157 : : end do
5158 : : !$OMP END PARALLEL DO
5159 : :
5160 : : end if ! if(option/=3)
5161 : :
5162 : : ! Do-loop on the planes stacked in the z direction
5163 : : !$OMP PARALLEL DEFAULT(PRIVATE) &
5164 : : !$OMP&SHARED(aft1,aft2,aft4,aft5,bef1,bef2,bef4,bef5,cplex,denpot) &
5165 : : !$OMP&SHARED(fftcache,fofr,gboundin,gboundout)&
5166 : : !$OMP&SHARED(ic1,ic2,ic4,ic5,ind1,ind2,ind4) &
5167 : : !$OMP&SHARED(ind5,indpw_kin,indpw_kout,lluse_ndo,mgb,n1,n2,n3,n4,n5,ngbin) &
5168 : : !$OMP&SHARED(ngbout,now1,now2,now4,now5,option,trig1,trig2,trig4,trig5) &
5169 : : !$OMP&SHARED(weight_r,weight_i,weight_2,wk1d_a,wk1d_b,wk1d_b_p)
5170 : :
5171 : : ! Allocate two 2-dimensional work arrays
5172 [ - + + - : 132040 : ABI_MALLOC(wk2d_a,(2,n4,n5,1))
- + + - +
- + - - +
- + ]
5173 [ - + + - : 99030 : ABI_MALLOC(wk2d_b,(2,n4,n5,1))
- + + - -
+ - + ]
5174 [ - + + - : 99030 : ABI_MALLOC(wk2d_a_p,(2,n4,n5,1))
- + + - -
+ - + ]
5175 [ - + + - : 99030 : ABI_MALLOC(wk2d_b_p,(2,n4,n5,1))
- + + - -
+ - + ]
5176 : : !$OMP DO
5177 [ + + ]: 833045 : do i3=1,n3
5178 : :
5179 [ + - ]: 800035 : if(option/=3)then
5180 [ + - ]: 800035 : if(lluse_ndo) then
5181 : : ! Zero the values on the current plane
5182 : : ! wk2d_a_p(1:2,1:n1,1:n2,1)=zero
5183 [ + + ]: 16291308 : do i2=1,n2
5184 [ + + ]: 327807355 : do i1=1,n1
5185 : 311516047 : wk2d_a_p(1,i1,i2,1)=zero
5186 : 327007320 : wk2d_a_p(2,i1,i2,1)=zero
5187 : : end do
5188 : : end do
5189 : : ! Copy the data in the current plane
5190 [ + + ]: 45023721 : do igb=1,ngbin
5191 : 44223686 : i1=indpw_kin(1,igb) ; i2=indpw_kin(2,igb)
5192 : 44223686 : wk2d_a_p(1,i1,i2,1)=wk1d_b_p(1,igb,i3,1)
5193 : 45023721 : wk2d_a_p(2,i1,i2,1)=wk1d_b_p(2,igb,i3,1)
5194 : : end do
5195 : : ! Perform x transform, taking into account arrays of zeros
5196 : 800035 : g2min=gboundin(3,1) ; g2max=gboundin(4,1)
5197 [ + - ]: 800035 : if ( g2min+n2 >= g2max+2 ) then
5198 [ + + ]: 9397655 : do i2=g2max+2,g2min+n2
5199 [ + + ]: 182748847 : do i1=1,n1
5200 : 173351192 : wk2d_b_p(1,i1,i2,1)=zero
5201 : 181948812 : wk2d_b_p(2,i1,i2,1)=zero
5202 : : end do
5203 : : end do
5204 : : end if
5205 : 800035 : gbound_dum(1)=1 ; gbound_dum(2)=1
5206 : 800035 : gbound_dum(3)=g2min ; gbound_dum(4)=g2max
5207 : : call sg_fftpx(fftcache,mfac,mg,0,n4,n5,1,n2,1,wk2d_a_p,wk2d_b_p,&
5208 : 800035 : & trig1,aft1,now1,bef1,one,ind1,ic1,gbound_dum)
5209 : : ! Perform y transform
5210 : 800035 : n1i=1
5211 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,n1i,n1,1,1,wk2d_b_p,wk2d_a_p, &
5212 : 800035 : & trig2,aft2,now2,bef2,one,ind2,ic2)
5213 : : ! The wave function is now in real space, for the current plane
5214 : : end if ! lluse_ndo
5215 : :
5216 : : ! Zero the values on the current plane
5217 : : ! wk2d_a(1:2,1:n1,1:n2,1)=zero
5218 [ + + ]: 16291308 : do i2=1,n2
5219 [ + + ]: 327807355 : do i1=1,n1
5220 : 311516047 : wk2d_a(1,i1,i2,1)=zero
5221 : 327007320 : wk2d_a(2,i1,i2,1)=zero
5222 : : end do
5223 : : end do
5224 : : ! Copy the data in the current plane
5225 [ + + ]: 45023721 : do igb=1,ngbin
5226 : 44223686 : i1=indpw_kin(1,igb) ; i2=indpw_kin(2,igb)
5227 : 44223686 : wk2d_a(1,i1,i2,1)=wk1d_b(1,igb,i3,1)
5228 : 45023721 : wk2d_a(2,i1,i2,1)=wk1d_b(2,igb,i3,1)
5229 : : end do
5230 : : ! Perform x transform, taking into account arrays of zeros
5231 : 800035 : g2min=gboundin(3,1) ; g2max=gboundin(4,1)
5232 [ + - ]: 800035 : if ( g2min+n2 >= g2max+2 ) then
5233 [ + + ]: 9397655 : do i2=g2max+2,g2min+n2
5234 [ + + ]: 182748847 : do i1=1,n1
5235 : 173351192 : wk2d_b(1,i1,i2,1)=zero
5236 : 181948812 : wk2d_b(2,i1,i2,1)=zero
5237 : : end do
5238 : : end do
5239 : : end if
5240 : 800035 : gbound_dum(1)=1 ; gbound_dum(2)=1
5241 : 800035 : gbound_dum(3)=g2min ; gbound_dum(4)=g2max
5242 : : call sg_fftpx(fftcache,mfac,mg,0,n4,n5,1,n2,1,wk2d_a,wk2d_b,&
5243 : 800035 : & trig1,aft1,now1,bef1,one,ind1,ic1,gbound_dum)
5244 : : ! Perform y transform
5245 : 800035 : n1i=1
5246 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,n1i,n1,1,1,wk2d_b,wk2d_a, &
5247 : 800035 : & trig2,aft2,now2,bef2,one,ind2,ic2)
5248 : : ! The wave function is now in real space, for the current plane
5249 : : end if
5250 : :
5251 [ - + ]: 800035 : if(option==0)then
5252 : : ! Copy the transformed function at the right place
5253 [ # # ]: 0 : do i2=1,n2
5254 [ # # ]: 0 : do i1=1,n1
5255 : 0 : fofr(1,i1,i2,i3)=wk2d_a(1,i1,i2,1)
5256 : 0 : fofr(2,i1,i2,i3)=wk2d_a(2,i1,i2,1)
5257 : : end do
5258 : : end do
5259 : : end if
5260 : :
5261 [ + - ]: 800035 : if(option==1)then
5262 : : ! Accumulate density
5263 [ + + ]: 16291308 : do i2=1,n2
5264 [ + + ]: 327807355 : do i1=1,n1
5265 [ + - ]: 327007320 : if(lluse_ndo) then
5266 : : denpot(i1,i2,i3)=denpot(i1,i2,i3)+&
5267 : : & weight_r*(wk2d_a(1,i1,i2,1)*wk2d_a_p(1,i1,i2,1)&
5268 : 311516047 : & +wk2d_a(2,i1,i2,1)*wk2d_a_p(2,i1,i2,1))
5269 [ + - ]: 311516047 : if(present(weight_2)) then
5270 : : denpot(i1,i2,i3)=denpot(i1,i2,i3)+&
5271 : : & weight_2*(wk2d_a_p(2,i1,i2,1)*wk2d_a(1,i1,i2,1)&
5272 : 311516047 : & -wk2d_a_p(1,i1,i2,1)*wk2d_a(2,i1,i2,1))
5273 : : end if
5274 : : else
5275 : : denpot(i1,i2,i3)=denpot(i1,i2,i3)+&
5276 : 0 : & weight_r*wk2d_a(1,i1,i2,1)**2+ weight_i*wk2d_a(2,i1,i2,1)**2
5277 : : end if
5278 : : end do
5279 : : end do
5280 : : end if
5281 : :
5282 [ - + ]: 800035 : if(option==2)then
5283 : : ! Apply local potential
5284 [ # # ]: 0 : if(cplex==1)then
5285 [ # # ]: 0 : do i2=1,n2
5286 [ # # ]: 0 : do i1=1,n1
5287 : 0 : wk2d_a(1,i1,i2,1)=denpot(i1,i2,i3)*wk2d_a(1,i1,i2,1)
5288 : 0 : wk2d_a(2,i1,i2,1)=denpot(i1,i2,i3)*wk2d_a(2,i1,i2,1)
5289 : : end do
5290 : : end do
5291 : : else
5292 [ # # ]: 0 : do i2=1,n2
5293 [ # # ]: 0 : do i1=1,n1
5294 : 0 : wkre=wk2d_a(1,i1,i2,1)
5295 : 0 : wkim=wk2d_a(2,i1,i2,1)
5296 : : wk2d_a(1,i1,i2,1)=denpot(2*i1-1,i2,i3)*wkre &
5297 : 0 : & -denpot(2*i1 ,i2,i3)*wkim
5298 : : wk2d_a(2,i1,i2,1)=denpot(2*i1-1,i2,i3)*wkim &
5299 : 0 : & +denpot(2*i1 ,i2,i3)*wkre
5300 : : end do
5301 : : end do
5302 : : end if
5303 : : end if
5304 : :
5305 [ - + ]: 800035 : if(option==3)then
5306 : : ! Copy the function to be tranformed at the right place
5307 [ # # ]: 0 : do i2=1,n2
5308 [ # # ]: 0 : do i1=1,n1
5309 : 0 : wk2d_a(1,i1,i2,1)=fofr(1,i1,i2,i3)
5310 : 0 : wk2d_a(2,i1,i2,1)=fofr(2,i1,i2,i3)
5311 : : end do
5312 : : end do
5313 : : end if
5314 : :
5315 [ - + ]: 833045 : if(option==2 .or. option==3)then
5316 : : ! Perform y transform
5317 : 0 : n1i=1
5318 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,n1i,n1,1,1,wk2d_a,wk2d_b, &
5319 : 0 : & trig5,aft5,now5,bef5,-one,ind5,ic5)
5320 : : ! Perform x transform, taking into account arrays of zeros
5321 : 0 : gbound_dum(1)=1 ; gbound_dum(2)=1
5322 : 0 : gbound_dum(3)=gboundout(3,1) ; gbound_dum(4)=gboundout(4,1)
5323 : : call sg_fftpx(fftcache,mfac,mg,0,n4,n5,1,n2,1,wk2d_b,wk2d_a,&
5324 : 0 : & trig4,aft4,now4,bef4,-one,ind4,ic4,gbound_dum)
5325 : : ! Copy the data from the current plane to wk1d_b
5326 [ # # ]: 0 : do igb=1,ngbout
5327 : 0 : i1=indpw_kout(1,igb) ; i2=indpw_kout(2,igb)
5328 : 0 : wk1d_b(1,igb,i3,1)=wk2d_a(1,i1,i2,1)
5329 : 0 : wk1d_b(2,igb,i3,1)=wk2d_a(2,i1,i2,1)
5330 : : end do
5331 : : end if
5332 : :
5333 : : ! End loop on planes
5334 : : end do
5335 : : !$OMP END DO
5336 [ - + ]: 33010 : ABI_FREE(wk2d_a)
5337 [ - + ]: 33010 : ABI_FREE(wk2d_b)
5338 [ - + ]: 33010 : ABI_FREE(wk2d_a_p)
5339 [ - + ]: 33010 : ABI_FREE(wk2d_b_p)
5340 : : !$OMP END PARALLEL
5341 : :
5342 [ - + ]: 33010 : if(option==2 .or. option==3)then
5343 : :
5344 : : ! Go from wk1d_b to wk1d_a, using 1D FFTs on the z direction
5345 : : ! However, due to special packing of data, use routine ffty
5346 : : !$OMP PARALLEL DO SHARED(aft6,bef6,fftcache,ind6,ic6,lotout,mgb)&
5347 : : !$OMP&SHARED(ngbout,now6,n3,trig6,wk1d_a,wk1d_b)&
5348 : : !$OMP&PRIVATE(igb,igbmax)
5349 [ # # # # : 0 : do igb=1,ngbout,lotout
# # # # ]
5350 : 0 : igbmax=min(igb+lotout-1,ngbout)
5351 : : ! Go from wk1d_b to wk1d_a, using 1D FFTs on the z direction
5352 : : ! However, due to special packing of data, use routine ffty
5353 : : call sg_ffty(fftcache,mfac,mg,mgb,n3,1,igb,igbmax,1,1,wk1d_b,wk1d_a, &
5354 : 0 : & trig6,aft6,now6,bef6,-one,ind6,ic6)
5355 : :
5356 : : end do
5357 : : !$OMP END PARALLEL DO
5358 : :
5359 : : ! Transfer the data in the output array, after normalization
5360 : 0 : norm=1.d0/dble(nfftot)
5361 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5362 : : !$OMP&SHARED(fofgout,indpw_kout,norm,npwout,wk1d_a)
5363 [ # # ]: 0 : do ig=1,npwout
5364 : 0 : igb=indpw_kout(4,ig) ; i3=indpw_kout(3,ig)
5365 : 0 : fofgout(1,ig)=wk1d_a(1,igb,i3,1)*norm
5366 : 0 : fofgout(2,ig)=wk1d_a(2,igb,i3,1)*norm
5367 : : end do
5368 : : !$OMP END PARALLEL DO
5369 : : end if
5370 : :
5371 [ - + ]: 33010 : ABI_FREE(wk1d_a)
5372 [ - + ]: 33010 : ABI_FREE(wk1d_b)
5373 [ - + ]: 33010 : ABI_FREE(wk1d_a_p)
5374 [ - + ]: 33010 : ABI_FREE(wk1d_b_p)
5375 : :
5376 : : ! End general k-point part
5377 : : end if
5378 : :
5379 : : !------------------------------------------------------------------
5380 : : !Here, use of time-reversal symmetry
5381 : :
5382 [ + - ]: 33010 : if(istwf_k>=2)then
5383 : :
5384 : 0 : n1half1=n1/2+1 ; n1halfm=(n1+1)/2
5385 : 0 : n2half1=n2/2+1
5386 : : ! n4half1 or n5half1 are the odd integers >= n1half1 or n2half1
5387 : 0 : n4half1=(n1half1/2)*2+1
5388 : 0 : n5half1=(n2half1/2)*2+1
5389 : : ! Note that the z transform will appear as a y transform
5390 [ # # # # : 0 : ABI_MALLOC(wk1d_a,(2,mgb,n3,1))
# # # # #
# # # # #
# # ]
5391 [ # # # # : 0 : ABI_MALLOC(wk1d_b,(2,mgb,n3,1))
# # # # #
# # # ]
5392 : :
5393 [ # # ]: 0 : if(istwf_k/=2)then
5394 [ # # # # : 0 : ABI_MALLOC(pha1,(2,n1))
# # # # #
# # # ]
5395 [ # # # # : 0 : ABI_MALLOC(pha2,(2,n2))
# # # # #
# # # ]
5396 [ # # # # : 0 : ABI_MALLOC(pha3,(3,n3))
# # # # #
# # # ]
5397 [ # # ]: 0 : do i1=1,n1
5398 : 0 : pha1(1,i1)=cos(dble(i1-1)*pi/dble(n1))
5399 : 0 : pha1(2,i1)=sin(dble(i1-1)*pi/dble(n1))
5400 : : end do
5401 [ # # ]: 0 : do i2=1,n2
5402 : 0 : pha2(1,i2)=cos(dble(i2-1)*pi/dble(n2))
5403 : 0 : pha2(2,i2)=sin(dble(i2-1)*pi/dble(n2))
5404 : : end do
5405 [ # # ]: 0 : do i3=1,n3
5406 : 0 : pha3(1,i3)=cos(dble(i3-1)*pi/dble(n3))
5407 : 0 : pha3(2,i3)=sin(dble(i3-1)*pi/dble(n3))
5408 : : end do
5409 : : end if
5410 : :
5411 [ # # ]: 0 : if(option/=3)then
5412 : :
5413 : : ! Zero the components of wk1d_a
5414 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5415 : : !$OMP&SHARED(n3,ngbin,wk1d_a)
5416 [ # # ]: 0 : do i3=1,n3
5417 [ # # ]: 0 : do igb=1,ngbin
5418 : 0 : wk1d_a(1,igb,i3,1)=zero
5419 : 0 : wk1d_a(2,igb,i3,1)=zero
5420 : : end do
5421 : : end do
5422 : : !$OMP END PARALLEL DO
5423 : :
5424 : : ! Insert fofgin into the work array
5425 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5426 : : !$OMP&SHARED(fofgin,indpw_kin,npwin,wk1d_a)
5427 [ # # ]: 0 : do ig=1,npwin
5428 : 0 : igb=indpw_kin(4,ig) ; i3=indpw_kin(3,ig)
5429 : 0 : wk1d_a(1,igb,i3,1)=fofgin(1,ig)
5430 : 0 : wk1d_a(2,igb,i3,1)=fofgin(2,ig)
5431 : : end do
5432 : : !$OMP END PARALLEL DO
5433 : :
5434 : : ! Must complete the i2=1 plane when $k_y \equiv 0$
5435 : :
5436 : : ! Take care of i1=1 when $k_x \equiv 0$
5437 [ # # ]: 0 : if(istwf_k==2)then
5438 : : ! Take care of i1=1
5439 [ # # ]: 0 : do i3=n3/2+1,n3
5440 : 0 : i3inv=n3+2-i3
5441 : 0 : wk1d_a(1,1,i3,1)= wk1d_a(1,1,i3inv,1)
5442 : 0 : wk1d_a(2,1,i3,1)=-wk1d_a(2,1,i3inv,1)
5443 : : end do
5444 [ # # ]: 0 : else if(istwf_k==4)then
5445 : : ! Take care of i1=1
5446 [ # # ]: 0 : do i3=n3/2+1,n3
5447 : 0 : i3inv=n3+1-i3
5448 : 0 : wk1d_a(1,1,i3,1)= wk1d_a(1,1,i3inv,1)
5449 : 0 : wk1d_a(2,1,i3,1)=-wk1d_a(2,1,i3inv,1)
5450 : : end do
5451 : : end if
5452 : :
5453 : : ! Now, take care of other i1 values, except i3==1 when $k_z \equiv 0$
5454 : 0 : i1max=gboundin(6,1)+1
5455 [ # # ]: 0 : if(istwf_k==2)then
5456 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5457 : : !$OMP&SHARED(i1max,n3,wk1d_a)
5458 [ # # ]: 0 : do igb=2,2*i1max-1
5459 : 0 : igb_inv=2*i1max+1-igb
5460 [ # # ]: 0 : do i3=n3/2+1,n3
5461 : 0 : i3inv=n3+2-i3
5462 : 0 : wk1d_a(1,igb,i3,1)= wk1d_a(1,igb_inv,i3inv,1)
5463 : 0 : wk1d_a(2,igb,i3,1)=-wk1d_a(2,igb_inv,i3inv,1)
5464 : : end do
5465 : : end do
5466 : : !$OMP END PARALLEL DO
5467 : :
5468 [ # # ]: 0 : else if(istwf_k==3)then
5469 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5470 : : !$OMP&SHARED(i1max,n3,wk1d_a)
5471 [ # # ]: 0 : do igb=1,2*i1max
5472 : 0 : igb_inv=2*i1max+1-igb
5473 [ # # ]: 0 : do i3=n3/2+1,n3
5474 : 0 : i3inv=n3+2-i3
5475 : 0 : wk1d_a(1,igb,i3,1)= wk1d_a(1,igb_inv,i3inv,1)
5476 : 0 : wk1d_a(2,igb,i3,1)=-wk1d_a(2,igb_inv,i3inv,1)
5477 : : end do
5478 : : end do
5479 : : !$OMP END PARALLEL DO
5480 : :
5481 [ # # ]: 0 : else if(istwf_k==4)then
5482 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5483 : : !$OMP&SHARED(i1max,n3,wk1d_a)
5484 [ # # ]: 0 : do igb=2,2*i1max-1
5485 : 0 : igb_inv=2*i1max+1-igb
5486 [ # # ]: 0 : do i3=n3/2+1,n3
5487 : 0 : i3inv=n3+1-i3
5488 : 0 : wk1d_a(1,igb,i3,1)= wk1d_a(1,igb_inv,i3inv,1)
5489 : 0 : wk1d_a(2,igb,i3,1)=-wk1d_a(2,igb_inv,i3inv,1)
5490 : : end do
5491 : : end do
5492 : : !$OMP END PARALLEL DO
5493 : :
5494 [ # # ]: 0 : else if(istwf_k==5)then
5495 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5496 : : !$OMP&SHARED(i1max,n3,wk1d_a)
5497 [ # # ]: 0 : do igb=1,2*i1max
5498 : 0 : igb_inv=2*i1max+1-igb
5499 [ # # ]: 0 : do i3=n3/2+1,n3
5500 : 0 : i3inv=n3+1-i3
5501 : 0 : wk1d_a(1,igb,i3,1)= wk1d_a(1,igb_inv,i3inv,1)
5502 : 0 : wk1d_a(2,igb,i3,1)=-wk1d_a(2,igb_inv,i3inv,1)
5503 : : end do
5504 : : end do
5505 : : !$OMP END PARALLEL DO
5506 : :
5507 : : end if
5508 : :
5509 : : ! Now, i3==1
5510 [ # # ]: 0 : if(istwf_k==2)then
5511 [ # # ]: 0 : do igb=2,i1max
5512 : 0 : igb_inv=2*i1max+1-igb
5513 : 0 : wk1d_a(1,igb_inv,1,1)= wk1d_a(1,igb,1,1)
5514 : 0 : wk1d_a(2,igb_inv,1,1)=-wk1d_a(2,igb,1,1)
5515 : : end do
5516 [ # # ]: 0 : else if(istwf_k==3)then
5517 [ # # ]: 0 : do igb=1,i1max
5518 : 0 : igb_inv=2*i1max+1-igb
5519 : 0 : wk1d_a(1,igb_inv,1,1)= wk1d_a(1,igb,1,1)
5520 : 0 : wk1d_a(2,igb_inv,1,1)=-wk1d_a(2,igb,1,1)
5521 : : end do
5522 : : end if
5523 : :
5524 : : ! Go from wk1d_a to wk1d_b, using 1D FFTs on the z direction
5525 : : ! However, due to special packing of data, use routine ffty
5526 : : !$OMP PARALLEL DO SHARED(aft3,bef3,fftcache,ind3,ic3,lotin,mgb)&
5527 : : !$OMP&SHARED(ngbin,now3,n3,trig3,wk1d_a,wk1d_b)&
5528 : : !$OMP&PRIVATE(igb,igbmax)
5529 [ # # # # : 0 : do igb=1,ngbin,lotin
# # # # ]
5530 : 0 : igbmax=min(igb+lotin-1,ngbin)
5531 : : ! Go from wk1d_a to wk1d_b, using 1D FFTs on the z direction
5532 : : ! However, due to special packing of data, use routine ffty
5533 : : call sg_ffty(fftcache,mfac,mg,mgb,n3,1,igb,igbmax,1,1,wk1d_a,wk1d_b, &
5534 : 0 : & trig3,aft3,now3,bef3,one,ind3,ic3)
5535 : : end do
5536 : : !$OMP END PARALLEL DO
5537 : :
5538 : : ! Change the phase if $k_z \neq 0$
5539 [ # # ]: 0 : if(istwf_k==4 .or. istwf_k==5 .or. istwf_k==8 .or. istwf_k==9 )then
5540 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5541 : : !$OMP&SHARED(ngbin,n3,pha3,wk1d_b)
5542 [ # # ]: 0 : do i3=1,n3
5543 : 0 : phar=pha3(1,i3)
5544 : 0 : phai=pha3(2,i3)
5545 [ # # ]: 0 : do igb=1,ngbin
5546 : 0 : ar=wk1d_b(1,igb,i3,1)
5547 : 0 : ai=wk1d_b(2,igb,i3,1)
5548 : 0 : wk1d_b(1,igb,i3,1)=phar*ar-phai*ai
5549 : 0 : wk1d_b(2,igb,i3,1)=phai*ar+phar*ai
5550 : : end do
5551 : : end do
5552 : : !$OMP END PARALLEL DO
5553 : : end if
5554 : :
5555 : : end if ! if(option/=3)
5556 : :
5557 : : ! Do-loop on the planes stacked in the z direction
5558 : :
5559 : : !$OMP PARALLEL DEFAULT(PRIVATE) &
5560 : : !$OMP&SHARED(aft1,aft2,aft4,aft5,bef1,bef2,bef4,bef5,denpot) &
5561 : : !$OMP&SHARED(fftcache,fofr,gboundin,ic1,ic2,ic4,ic5,ind1,ind2,ind4,ind5) &
5562 : : !$OMP&SHARED(indpw_kin,indpw_kout,istwf_k,mgb,n1,n1half1) &
5563 : : !$OMP&SHARED(n1halfm,n2,n2half1,n3,n4,n5,ngbin,ngbout) &
5564 : : !$OMP&SHARED(now1,now2,now4,now5,option,pha1,pha2,trig1) &
5565 : : !$OMP&SHARED(trig2,trig4,trig5,weight_r,weight_i,wk1d_a,wk1d_b)
5566 : :
5567 : : ! Allocate two 2-dimensional work arrays
5568 [ # # # # : 0 : ABI_MALLOC(wk2d_a,(2,n4,n5,1))
# # # # #
# # # # #
# # ]
5569 [ # # # # : 0 : ABI_MALLOC(wk2d_b,(2,n4,n5,1))
# # # # #
# # # ]
5570 [ # # # # : 0 : ABI_MALLOC(wk2d_c,(2,2*n1halfm,n5,1))
# # # # #
# # # # #
# # # # ]
5571 [ # # # # : 0 : ABI_MALLOC(wk2d_d,(2,2*n1halfm,n5,1))
# # # # #
# # # ]
5572 : : !$OMP DO
5573 [ # # ]: 0 : do i3=1,n3
5574 : :
5575 : 0 : g2max=gboundin(4,1)
5576 : :
5577 [ # # ]: 0 : if(option/=3)then
5578 : : ! Zero the values on the current plane : need only from i2=1 to g2max+1
5579 [ # # ]: 0 : do i2=1,g2max+1
5580 [ # # ]: 0 : do i1=1,n1
5581 : 0 : wk2d_a(1,i1,i2,1)=zero
5582 : 0 : wk2d_a(2,i1,i2,1)=zero
5583 : : end do
5584 : : end do
5585 : :
5586 : : ! Copy the data in the current plane
5587 [ # # ]: 0 : do igb=1,ngbin
5588 : 0 : i1=indpw_kin(1,igb) ; i2=indpw_kin(2,igb)
5589 : 0 : wk2d_a(1,i1,i2,1)=wk1d_b(1,igb,i3,1)
5590 : 0 : wk2d_a(2,i1,i2,1)=wk1d_b(2,igb,i3,1)
5591 : : end do
5592 : :
5593 : : ! Perform x transform, taking into account arrays of zeros
5594 : : call sg_fftx(fftcache,mfac,mg,n4,n5,1,g2max+1,1,wk2d_a,wk2d_b,&
5595 : 0 : & trig1,aft1,now1,bef1,one,ind1,ic1)
5596 : :
5597 : : ! Change the phase if $k_x \neq 0$
5598 [ # # ]: 0 : if(istwf_k==3 .or. istwf_k==5 .or. istwf_k==7 .or. istwf_k==9)then
5599 [ # # ]: 0 : do i1=1,n1
5600 : 0 : phar=pha1(1,i1)
5601 : 0 : phai=pha1(2,i1)
5602 [ # # ]: 0 : do i2=1,g2max+1
5603 : 0 : ar=wk2d_b(1,i1,i2,1)
5604 : 0 : ai=wk2d_b(2,i1,i2,1)
5605 : 0 : wk2d_b(1,i1,i2,1)=phar*ar-phai*ai
5606 : 0 : wk2d_b(2,i1,i2,1)=phai*ar+phar*ai
5607 : : end do
5608 : : end do
5609 : : end if
5610 : :
5611 : : ! Compute symmetric and antisymmetric combinations
5612 [ # # ]: 0 : if(istwf_k>=2 .and. istwf_k<=5)then
5613 [ # # ]: 0 : do i1=1,n1half1-1
5614 : 0 : wk2d_a(1,i1,1,1)=wk2d_b(1,2*i1-1,1,1)
5615 : 0 : wk2d_a(2,i1,1,1)=wk2d_b(1,2*i1 ,1,1)
5616 : : end do
5617 : : ! If n1 odd, must add last data
5618 [ # # ]: 0 : if((2*n1half1-2)/=n1)then
5619 : 0 : wk2d_a(1,n1half1,1,1)=wk2d_b(1,n1,1,1)
5620 : 0 : wk2d_a(2,n1half1,1,1)=zero
5621 : : end if
5622 : : ii2=2
5623 : : else
5624 : : ii2=1
5625 : : end if
5626 [ # # ]: 0 : if( g2max+1 >= ii2)then
5627 [ # # ]: 0 : do i2=ii2,g2max+1
5628 [ # # ]: 0 : do i1=1,n1half1-1
5629 : 0 : wk2d_a(1,i1,i2,1)= wk2d_b(1,2*i1-1,i2,1)-wk2d_b(2,2*i1,i2,1)
5630 : 0 : wk2d_a(2,i1,i2,1)= wk2d_b(2,2*i1-1,i2,1)+wk2d_b(1,2*i1,i2,1)
5631 : 0 : wk2d_a(1,i1,n2+ii2-i2,1)= wk2d_b(1,2*i1-1,i2,1)+wk2d_b(2,2*i1,i2,1)
5632 : 0 : wk2d_a(2,i1,n2+ii2-i2,1)=-wk2d_b(2,2*i1-1,i2,1)+wk2d_b(1,2*i1,i2,1)
5633 : : end do
5634 [ # # ]: 0 : if((2*n1half1-2)/=n1)then
5635 : 0 : wk2d_a(1,n1half1,i2,1)= wk2d_b(1,n1,i2,1)
5636 : 0 : wk2d_a(2,n1half1,i2,1)= wk2d_b(2,n1,i2,1)
5637 : 0 : wk2d_a(1,n1half1,n2+ii2-i2,1)= wk2d_b(1,n1,i2,1)
5638 : 0 : wk2d_a(2,n1half1,n2+ii2-i2,1)=-wk2d_b(2,n1,i2,1)
5639 : : end if
5640 : : end do
5641 : : end if
5642 [ # # ]: 0 : if ( n2half1 >= g2max+2 ) then
5643 [ # # ]: 0 : do i2=g2max+2,n2half1
5644 [ # # ]: 0 : do i1=1,n1half1-1
5645 : 0 : wk2d_a(1,i1,i2,1)=zero
5646 : 0 : wk2d_a(2,i1,i2,1)=zero
5647 : 0 : wk2d_a(1,i1,n2+ii2-i2,1)=zero
5648 : 0 : wk2d_a(2,i1,n2+ii2-i2,1)=zero
5649 : : end do
5650 [ # # ]: 0 : if((2*n1half1-2)/=n1)then
5651 : 0 : wk2d_a(1,n1half1,i2,1)=zero
5652 : 0 : wk2d_a(2,n1half1,i2,1)=zero
5653 : 0 : wk2d_a(1,n1half1,n2+ii2-i2,1)=zero
5654 : 0 : wk2d_a(2,n1half1,n2+ii2-i2,1)=zero
5655 : : end if
5656 : : end do
5657 : : end if
5658 : :
5659 : 0 : n1i=1
5660 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,n1i,n1halfm,1,1,wk2d_a,wk2d_b,&
5661 : 0 : & trig2,aft2,now2,bef2,one,ind2,ic2)
5662 : :
5663 : : ! Change the phase if $k_y \neq 0$
5664 [ # # ]: 0 : if(istwf_k>=6 .and. istwf_k<=9)then
5665 [ # # ]: 0 : do i2=1,n2
5666 : 0 : phar=pha2(1,i2)
5667 : 0 : phai=pha2(2,i2)
5668 [ # # ]: 0 : do i1=1,n1halfm
5669 : 0 : ar=wk2d_b(1,i1,i2,1)
5670 : 0 : ai=wk2d_b(2,i1,i2,1)
5671 : 0 : wk2d_b(1,i1,i2,1)= phar*ar-phai*ai
5672 : 0 : wk2d_b(2,i1,i2,1)= phai*ar+phar*ai
5673 : : end do
5674 : : end do
5675 : : end if
5676 : :
5677 : : end if ! option/=3
5678 : :
5679 : : ! The wave function is now in real space, for the current plane,
5680 : : ! represented by REAL numbers, although packed in the complex array wk2d_b
5681 : :
5682 : 0 : g2max=gboundin(4,1)
5683 : :
5684 [ # # ]: 0 : if(option==0)then
5685 : : ! This option is only permitted for istwf_k==2 (Gamma point)
5686 : : ! Copy the transformed function at the right place
5687 [ # # ]: 0 : do i2=1,n2
5688 [ # # ]: 0 : do i1=1,n1half1-1
5689 : 0 : fofr(1,2*i1-1,i2,i3)=wk2d_b(1,i1,i2,1)
5690 : 0 : fofr(1,2*i1 ,i2,i3)=wk2d_b(2,i1,i2,1)
5691 : 0 : fofr(2,2*i1-1,i2,i3)=zero
5692 : 0 : fofr(2,2*i1 ,i2,i3)=zero
5693 : : end do
5694 : : ! If n1 odd, must add last data
5695 [ # # ]: 0 : if((2*n1half1-2)/=n1)then
5696 : 0 : fofr(1,n1,i2,i3)=wk2d_b(1,n1half1,i2,1)
5697 : 0 : fofr(2,n1,i2,i3)=zero
5698 : : end if
5699 : : end do
5700 : : end if
5701 : :
5702 [ # # ]: 0 : if(option==1)then
5703 : : ! Accumulate density
5704 [ # # ]: 0 : do i2=1,n2
5705 [ # # ]: 0 : do i1=1,n1half1-1
5706 : 0 : denpot(2*i1-1,i2,i3)=denpot(2*i1-1,i2,i3)+weight_r*wk2d_b(1,i1,i2,1)**2
5707 : 0 : denpot(2*i1 ,i2,i3)=denpot(2*i1 ,i2,i3)+weight_i*wk2d_b(2,i1,i2,1)**2
5708 : : end do
5709 : : ! If n1 odd, must add last data
5710 [ # # ]: 0 : if((2*n1half1-2)/=n1)then
5711 : 0 : denpot(n1,i2,i3)=denpot(n1,i2,i3)+weight_r*wk2d_b(1,n1half1,i2,1)**2
5712 : : ! not use in DMFT because istwfk required to be one.
5713 : : end if
5714 : : end do
5715 : : end if
5716 : :
5717 [ # # ]: 0 : if(option==2)then
5718 : : ! Apply local potential
5719 [ # # ]: 0 : do i2=1,n2
5720 [ # # ]: 0 : do i1=1,n1half1-1
5721 : 0 : wk2d_a(1,i1,i2,1)=denpot(2*i1-1,i2,i3)*wk2d_b(1,i1,i2,1)
5722 : 0 : wk2d_a(2,i1,i2,1)=denpot(2*i1 ,i2,i3)*wk2d_b(2,i1,i2,1)
5723 : : end do
5724 : : ! If n1 odd, must add last data
5725 [ # # ]: 0 : if((2*n1half1-2)/=n1)then
5726 : 0 : wk2d_a(1,n1half1,i2,1)=denpot(n1,i2,i3)*wk2d_b(1,n1half1,i2,1)
5727 : 0 : wk2d_a(2,n1half1,i2,1)=zero
5728 : : end if
5729 : : end do
5730 : : end if
5731 : :
5732 [ # # ]: 0 : if(option==3)then
5733 : : ! This option is only permitted for istwf_k==2 (Gamma point)
5734 : : ! Copy the transformed function at the right place
5735 [ # # ]: 0 : do i2=1,n2
5736 [ # # ]: 0 : do i1=1,n1half1-1
5737 : 0 : wk2d_b(1,i1,i2,1)=fofr(1,2*i1-1,i2,i3)
5738 : 0 : wk2d_b(2,i1,i2,1)=fofr(1,2*i1 ,i2,i3)
5739 : : end do
5740 : : ! If n1 odd, must add last data
5741 [ # # ]: 0 : if((2*n1half1-2)/=n1)then
5742 : 0 : wk2d_b(1,n1half1,i2,1)=fofr(1,n1,i2,i3)
5743 : : end if
5744 : : end do
5745 : : end if
5746 : :
5747 [ # # ]: 0 : if(option==2 .or. option==3)then
5748 : : ! Change the phase if $k_y \neq 0$
5749 [ # # ]: 0 : if(istwf_k>=6 .and. istwf_k<=9)then
5750 [ # # ]: 0 : do i2=1,n2
5751 : 0 : phar=pha2(1,i2)
5752 : 0 : phai=pha2(2,i2)
5753 [ # # ]: 0 : do i1=1,n1halfm
5754 : 0 : ar=wk2d_a(1,i1,i2,1)
5755 : 0 : ai=wk2d_a(2,i1,i2,1)
5756 : 0 : wk2d_a(1,i1,i2,1)= phar*ar+phai*ai
5757 : 0 : wk2d_a(2,i1,i2,1)=-phai*ar+phar*ai
5758 : : end do
5759 : : end do
5760 : : end if
5761 : :
5762 : : ! Perform y transform
5763 : 0 : n1i=1
5764 : : call sg_ffty(fftcache,mfac,mg,n4,n5,1,n1i,n1halfm,1,1,wk2d_a,wk2d_b, &
5765 : 0 : & trig5,aft5,now5,bef5,-one,ind5,ic5)
5766 : :
5767 : : ! Decompose symmetric and antisymmetric parts
5768 [ # # ]: 0 : if(istwf_k>=2 .and. istwf_k<=5)then
5769 [ # # ]: 0 : do i1=1,n1halfm
5770 : 0 : wk2d_c(1,2*i1-1,1,1)=wk2d_b(1,i1,1,1)
5771 : 0 : wk2d_c(2,2*i1-1,1,1)=zero
5772 : 0 : wk2d_c(1,2*i1,1,1)=wk2d_b(2,i1,1,1)
5773 : 0 : wk2d_c(2,2*i1,1,1)=zero
5774 : : end do
5775 : : ii2=2
5776 : : else
5777 : : ii2=1
5778 : : end if
5779 [ # # ]: 0 : do i2=ii2,g2max+1
5780 [ # # ]: 0 : do i1=1,n1halfm
5781 : 0 : wk2d_c(1,2*i1-1,i2,1)=(wk2d_b(1,i1,i2,1)+wk2d_b(1,i1,n2+ii2-i2,1))*0.5d0
5782 : 0 : wk2d_c(2,2*i1-1,i2,1)=(wk2d_b(2,i1,i2,1)-wk2d_b(2,i1,n2+ii2-i2,1))*0.5d0
5783 : 0 : wk2d_c(1,2*i1,i2,1)= ( wk2d_b(2,i1,i2,1)+wk2d_b(2,i1,n2+ii2-i2,1))*0.5d0
5784 : 0 : wk2d_c(2,2*i1,i2,1)= (-wk2d_b(1,i1,i2,1)+wk2d_b(1,i1,n2+ii2-i2,1))*0.5d0
5785 : : end do
5786 : : end do
5787 : :
5788 : : ! Change the phase if $k_x \neq 0$
5789 [ # # ]: 0 : if(istwf_k==3 .or. istwf_k==5 .or. istwf_k==7 .or. istwf_k==9 )then
5790 [ # # ]: 0 : do i1=1,n1
5791 : 0 : phar=pha1(1,i1)
5792 : 0 : phai=pha1(2,i1)
5793 [ # # ]: 0 : do i2=1,g2max+1
5794 : 0 : ar=wk2d_c(1,i1,i2,1)
5795 : 0 : ai=wk2d_c(2,i1,i2,1)
5796 : 0 : wk2d_c(1,i1,i2,1)= phar*ar+phai*ai
5797 : 0 : wk2d_c(2,i1,i2,1)=-phai*ar+phar*ai
5798 : : end do
5799 : : end do
5800 : : end if
5801 : :
5802 : : ! Perform x transform : for y=1 to g2max+1, to benefit from zeros
5803 : : call sg_fftx(fftcache,mfac,mg,2*n1halfm,n5,1,g2max+1,1,wk2d_c,wk2d_d,&
5804 : 0 : & trig4,aft4,now4,bef4,-one,ind4,ic4)
5805 : :
5806 : : ! Copy the data from the current plane to wk1d_b
5807 [ # # ]: 0 : do igb=1,ngbout
5808 : 0 : i1=indpw_kout(1,igb) ; i2=indpw_kout(2,igb)
5809 : 0 : wk1d_b(1,igb,i3,1)=wk2d_d(1,i1,i2,1)
5810 : 0 : wk1d_b(2,igb,i3,1)=wk2d_d(2,i1,i2,1)
5811 : : end do
5812 : :
5813 : : end if ! option==2 or 3
5814 : :
5815 : : ! End loop on planes
5816 : : end do
5817 : :
5818 : : !$OMP END DO
5819 [ # # ]: 0 : ABI_FREE(wk2d_a)
5820 [ # # ]: 0 : ABI_FREE(wk2d_b)
5821 [ # # ]: 0 : ABI_FREE(wk2d_c)
5822 [ # # ]: 0 : ABI_FREE(wk2d_d)
5823 : : !$OMP END PARALLEL
5824 : :
5825 [ # # ]: 0 : if(option==2 .or. option==3)then
5826 : :
5827 : : ! Change the phase if $k_z \neq 0$
5828 [ # # ]: 0 : if(istwf_k==4 .or. istwf_k==5 .or. istwf_k==8 .or. istwf_k==9 )then
5829 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5830 : : !$OMP&SHARED(ngbout,n3,pha3,wk1d_b)
5831 [ # # ]: 0 : do i3=1,n3
5832 : 0 : phar=pha3(1,i3)
5833 : 0 : phai=pha3(2,i3)
5834 [ # # ]: 0 : do igb=1,ngbout
5835 : 0 : ar=wk1d_b(1,igb,i3,1)
5836 : 0 : ai=wk1d_b(2,igb,i3,1)
5837 : 0 : wk1d_b(1,igb,i3,1)= phar*ar+phai*ai
5838 : 0 : wk1d_b(2,igb,i3,1)=-phai*ar+phar*ai
5839 : : end do
5840 : : end do
5841 : : !$OMP END PARALLEL DO
5842 : : end if
5843 : :
5844 : : ! Go from wk1d_b to wk1d_a, using 1D FFTs on the z direction
5845 : : ! However, due to special packing of data, use routine ffty
5846 : : !$OMP PARALLEL DO SHARED(aft6,bef6,fftcache,ind6,ic6,lotout,mgb)&
5847 : : !$OMP&SHARED(ngbout,now6,n3,trig6,wk1d_a,wk1d_b)&
5848 : : !$OMP&PRIVATE(igb,igbmax)
5849 [ # # # # : 0 : do igb=1,ngbout,lotout
# # # # ]
5850 : 0 : igbmax=min(igb+lotout-1,ngbout)
5851 : : ! Go from wk1d_b to wk1d_a, using 1D FFTs on the z direction
5852 : : ! However, due to special packing of data, use routine ffty
5853 : : call sg_ffty(fftcache,mfac,mg,mgb,n3,1,igb,igbmax,1,1,wk1d_b,wk1d_a, &
5854 : 0 : & trig6,aft6,now6,bef6,-one,ind6,ic6)
5855 : :
5856 : : end do
5857 : : !$OMP END PARALLEL DO
5858 : :
5859 : : ! Transfer the data in the output array, after normalization
5860 : 0 : norm=1.d0/dble(nfftot)
5861 : : !$OMP PARALLEL DO DEFAULT(PRIVATE) &
5862 : : !$OMP&SHARED(fofgout,indpw_kout,norm,npwout,wk1d_a)
5863 [ # # ]: 0 : do ig=1,npwout
5864 : 0 : igb=indpw_kout(4,ig) ; i3=indpw_kout(3,ig)
5865 : 0 : fofgout(1,ig)=wk1d_a(1,igb,i3,1)*norm
5866 : 0 : fofgout(2,ig)=wk1d_a(2,igb,i3,1)*norm
5867 : : end do
5868 : : !$OMP END PARALLEL DO
5869 : :
5870 : : end if
5871 : :
5872 [ # # ]: 0 : ABI_FREE(wk1d_a)
5873 [ # # ]: 0 : ABI_FREE(wk1d_b)
5874 : :
5875 [ # # ]: 0 : if(istwf_k/=2)then
5876 [ # # ]: 0 : ABI_FREE(pha1)
5877 [ # # ]: 0 : ABI_FREE(pha2)
5878 [ # # ]: 0 : ABI_FREE(pha3)
5879 : : end if
5880 : :
5881 : : ! End time-reversal symmetry
5882 : : end if
5883 : :
5884 [ + - ]: 33010 : if(option/=3) then
5885 [ - + ]: 33010 : ABI_FREE(indpw_kin)
5886 : : end if
5887 [ - + ]: 33010 : if(option==2 .or. option==3) then
5888 [ # # ]: 0 : ABI_FREE(indpw_kout)
5889 : : end if
5890 : :
5891 : : !DBG_EXIT("COLL")
5892 : :
5893 [ - + - + : 33010 : end subroutine sg_fftrisc_2
- + - + -
+ ]
5894 : : !!***
5895 : :
5896 : : !----------------------------------------------------------------------
5897 : :
5898 : : !!****f* m_sgfft/sg_poisson
5899 : : !! NAME
5900 : : !! sg_poisson
5901 : : !!
5902 : : !! FUNCTION
5903 : : !! Solve the Poisson equation in G-space given the density, n(r),
5904 : : !! in real space of the FFT box.
5905 : : !!
5906 : : !! INPUTS
5907 : : !! fftcache=size of the cache (kB)
5908 : : !! cplex=1 if fofr is real, 2 if fofr is complex
5909 : : !! nx,ny,nz=Number of FFT points along the three directions.
5910 : : !! ldx,ldy,ldz=Leading dimension of the array nr and vg.
5911 : : !! ndat = Number of densities
5912 : : !! vg(nx*ny*nz)=Potential in reciprocal space.
5913 : : !!
5914 : : !! SIDE EFFECTS
5915 : : !! nr(cplex*ldx*ldy*ldz*ndat)
5916 : : !! input: n(r) (real or complex)
5917 : : !! output: the hartree potential in real space
5918 : : !!
5919 : : !! NOTES
5920 : : !! vg is given on the FFT mesh instead of the augmented mesh [ldx,ldy,ldz]
5921 : : !! in order to simplify the interface with the other routines operating of vg
5922 : : !!
5923 : : !! SOURCE
5924 : :
5925 : 0 : subroutine sg_poisson(fftcache,cplex,nx,ny,nz,ldx,ldy,ldz,ndat,vg,nr)
5926 : :
5927 : : !Arguments ------------------------------------
5928 : : !scalars
5929 : : integer,intent(in) :: fftcache,cplex,nx,ny,nz,ldx,ldy,ldz,ndat
5930 : : !arrays
5931 : : real(dp),intent(inout) :: nr(cplex*ldx*ldy*ldz*ndat)
5932 : : real(dp),intent(in) :: vg(nx*ny*nz)
5933 : :
5934 : : !Local variables-------------------------------
5935 : : integer,parameter :: ndat1=1
5936 : : integer :: ii,jj,kk,ifft,dat,ptr,ig
5937 : : real(dp) :: fft_fact
5938 : : !arrays
5939 : 0 : real(dp),allocatable :: work(:,:)
5940 : :
5941 : : ! *************************************************************************
5942 : :
5943 : 0 : fft_fact = one/(nx*ny*nz)
5944 : :
5945 [ # # ]: 0 : ABI_CHECK(cplex==2,"cplex!=2 not coded")
5946 : :
5947 [ # # # # : 0 : ABI_MALLOC(work, (2,ldx*ldy*ldz))
# # # # #
# # # ]
5948 : :
5949 [ # # ]: 0 : do dat=1,ndat
5950 : : ! n(r) --> n(G)
5951 : 0 : ptr = 1 + (dat-1)*cplex*ldx*ldy*ldz
5952 : 0 : call sg_fft_cc(fftcache,nx,ny,nz,ldx,ldy,ldz,ndat1,-1,nr(ptr),work)
5953 : :
5954 : : ! Multiply by v(G)
5955 : 0 : ig = 0
5956 [ # # ]: 0 : do kk=1,nz
5957 [ # # ]: 0 : do jj=1,ny
5958 [ # # ]: 0 : do ii=1,nx
5959 : 0 : ig = ig + 1
5960 : 0 : ifft = ii + (jj-1)*ldx + (kk-1)*ldx*ldy
5961 [ # # ]: 0 : work(1:2,ifft) = work(1:2,ifft) * vg(ig) * fft_fact
5962 : : end do
5963 : : end do
5964 : : end do
5965 : :
5966 : : ! compute vh(r)
5967 : 0 : call sg_fft_cc(fftcache,nx,ny,nz,ldx,ldy,ldz,ndat1,+1,work,nr(ptr))
5968 : : end do
5969 : :
5970 [ # # ]: 0 : ABI_FREE(work)
5971 : :
5972 : 0 : end subroutine sg_poisson
5973 : : !!***
5974 : :
5975 : : END MODULE m_sgfft
|