LCOV - code coverage report
Current view: top level - src/52_fft_mpi_noabirule - m_sg2002.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.5 % 2389 1971
Test Date: 2026-09-21 19:39:32 Functions: 100.0 % 10 10

            Line data    Source code
       1              : !!****m* ABINIT/m_sg2002
       2              : !! NAME
       3              : !!  m_sg2002
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 2002-2007 Stefan Goedecker, CEA Grenoble
       9              : !!  Copyright (C) 2014-2026 ABINIT group (XG)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! NOTES
      15              : !!
      16              : !! SOURCE
      17              : 
      18              : #if defined HAVE_CONFIG_H
      19              : #include "config.h"
      20              : #endif
      21              : 
      22              : #include "abi_common.h"
      23              : 
      24              : module m_sg2002
      25              : 
      26              :  use defs_basis
      27              :  use defs_fftdata
      28              :  use m_abicore
      29              :  use m_errors
      30              :  use m_xmpi
      31              : 
      32              :  use m_time,         only : timab
      33              :  use m_fstrings,     only : itoa
      34              :  use m_fftcore,      only : sphere_fft1, fill, scramble, switchreal, switch, mpiswitch,&
      35              : &                           unfill, unscramble, unswitchreal, unswitch, unmpiswitch,&
      36              : &                           fill_cent, switch_cent, switchreal_cent, mpiswitch_cent, multpot, addrho,&
      37              : &                           unfill_cent, unswitchreal_cent, unswitch_cent, unmpiswitch_cent, unscramble,&
      38              : &                           mpifft_fg2dbox, mpifft_dbox2fr, mpifft_fr2dbox, mpifft_dbox2fg
      39              : 
      40              :  implicit none
      41              : 
      42              :  private
      43              : 
      44              :  ! Public API:
      45              :  !public :: sg2002_seqfourdp   ! seq-FFT of densities and potentials.
      46              :  public :: sg2002_mpifourdp    ! MPI-FFT of densities and potentials.
      47              :  !public :: mpi_fourwf
      48              :  !public :: sg2002_seqfourwf   ! seq-FFT of wavefunctions.
      49              :  !public :: sg2002_mpifourwf   ! MPI-FFT of wavefunctions.
      50              : 
      51              : ! Low-level tools.
      52              : ! These procedure shouls be accessed via a wrapper that selected the library via fftalg
      53              :  public :: sg2002_back           ! G --> R for densities and potentials
      54              :  public :: sg2002_forw           ! R --> G for densities and potentials
      55              :  public :: sg2002_mpiback_wf     ! G --> R for wavefunctions
      56              :  public :: sg2002_mpiforw_wf     ! R --> G for wavefunctions
      57              :  public :: sg2002_applypot       ! Compute <G|vloc|u> where u is given in reciprocal space.
      58              :  public :: sg2002_applypot_many  ! Compute <G|vloc|u> where u is given in reciprocal space.
      59              :  public :: sg2002_accrho         ! Compute rho = weigth_r*Re(u(r))**2 + weigth_i*Im(u(r))**2
      60              : 
      61              : contains
      62              : !!***
      63              : 
      64              : !!****f* m_sg2002/sg2002_back
      65              : !! NAME
      66              : !!  sg2002_back
      67              : !!
      68              : !! FUNCTION
      69              : !!   CALCULATES THE DISCRETE FOURIER TRANSFORM  in parallel using MPI/OpenMP
      70              : !!
      71              : !!   ZR(I1,I2,I3)= \sum_(j1,j2,j3) EXP(isign*i*2*pi*(j1*i1/n1+j2*i2/n2+j3*i3/n3)) ZF(j1,j3,j2)
      72              : !!
      73              : !! Adopt standard convention that isign=1 for backward transform
      74              : !!
      75              : !! INPUTS:
      76              : !!    cplex=1 for real --> complex, 2 for complex --> complex
      77              : !!    ZF: input array in G-space (note the switch of i2 and i3)
      78              : !!
      79              : !!         real(F(i1,i3,i2,idat))=ZF(1,i1,i3,i2,idat)
      80              : !!         imag(F(i1,i3,i2,idat))=ZF(2,i1,i3,i2,idat)
      81              : !!
      82              : !!         i1=1,n1 , i2=1,n2 , i3=1,n3 , idat=1,ndat
      83              : !! OUTPUTS:
      84              : !!    ZR: output array in R space.
      85              : !!
      86              : !!         ZR(1,i1,i2,i3,idat)=real(R(i1,i2,i3,idat))
      87              : !!         ZR(2,i1,i2,i3,idat)=imag(R(i1,i2,i3,idat))
      88              : !!
      89              : !!         i1=1,n1 , i2=1,n2 , i3=1,n3 , idat=1,ndat
      90              : !!
      91              : !!    nproc_fft: number of processors used as returned by MPI_COMM_SIZE
      92              : !!    me_fft: [0:nproc_fft-1] number of processor as returned by MPI_COMM_RANK
      93              : !!    n1,n2,n3: logical dimension of the transform. As transform lengths
      94              : !!              most products of the prime factors 2,3,5 are allowed.
      95              : !!              The detailed table with allowed transform lengths can
      96              : !!              be found in subroutine CTRIG
      97              : !!    nd1,nd2,nd3: Dimension of ZF and ZR
      98              : !!    nd2proc=((nd2-1)/nproc_fft)+1 maximal number of 2nd dim slices
      99              : !!    nd3proc=((nd3-1)/nproc_fft)+1 maximal number of 3rd dim slices
     100              : !!
     101              : !! NOTES:
     102              : !!   The maximum number of processors that can reasonably be used is max(n2,n3)
     103              : !!   It is very important to find the optimal
     104              : !!   value of NCACHE. NCACHE determines the size of the work array ZW, that
     105              : !!   has to fit into cache. It has therefore to be chosen to equal roughly
     106              : !!    half the size of the physical cache in units of real*8 numbers.
     107              : !!   The optimal value of ncache can easily be determined by numerical
     108              : !!   experimentation. A too large value of ncache leads to a dramatic
     109              : !!   and sudden decrease of performance, a too small value to a to a
     110              : !!   slow and less dramatic decrease of performance. If NCACHE is set
     111              : !!   to a value so small, that not even a single one dimensional transform
     112              : !!   can be done in the workarray zw, the program stops with an error message.
     113              : !!
     114              : !! SOURCE
     115              : 
     116        70446 : subroutine sg2002_back(cplex,ndat,n1,n2,n3,nd1,nd2,nd3,nd1eff,nd2proc,nd3proc,option,zf,zr,comm_fft)
     117              : 
     118              : !Arguments ------------------------------------
     119              : ! real space input
     120              :  integer,intent(in) :: cplex,ndat,n1,n2,n3,nd1,nd2,nd3,nd1eff,nd2proc,nd3proc,option,comm_fft
     121              :  real(dp),intent(in) :: zf(2,nd1,nd3,nd2proc,ndat)
     122              :  real(dp),intent(out) :: zr(2,nd1eff,nd2,nd3proc,ndat)
     123              : 
     124              : !Local variables-------------------------------
     125              : !scalars
     126              :  integer :: i,j,i1,ic1,ic2,ic3,idat,ierr,includelast,inzee,j2,j2st,j3,jeff,jp2st,lot,lzt
     127              :  integer :: ma,mb,n1dfft,n1eff,n2eff,n1zt,ncache,nnd3,nproc_fft,me_fft
     128              :  character(len=500) :: msg
     129              : !arrays
     130        70446 :  real(dp), allocatable :: zt(:,:,:)  ! work arrays for transpositions
     131        70446 :  real(dp), allocatable :: zmpi1(:,:,:,:),zmpi2(:,:,:,:) ! work arrays for MPI
     132        70446 :  real(dp), allocatable :: zw(:,:,:) ! cache work array
     133              :  real(dp) :: tsec(2)
     134              : ! FFT work arrays
     135        70446 :  real(dp), allocatable, dimension(:,:) :: trig1,trig2,trig3
     136        70446 :  integer, allocatable, dimension(:) :: after1,now1,before1,after2,now2,before2,after3,now3,before3
     137              : 
     138              : ! *************************************************************************
     139              : 
     140        70446 :  nproc_fft = xmpi_comm_size(comm_fft); me_fft = xmpi_comm_rank(comm_fft)
     141              : 
     142              :  ! find cache size that gives optimal performance on machine
     143        70446 :  ncache=4*max(n1,n2,n3,1024)
     144              : 
     145        70446 :  if (ncache/(4*max(n1,n2,n3))<1) then
     146              :    write(msg,'(5a)') &
     147            0 : &    'ncache has to be enlarged to be able to hold at',ch10, &
     148            0 : &    'least one 1-d FFT of each size even though this will',ch10,&
     149            0 : &    'reduce the performance for shorter transform lengths'
     150            0 :    ABI_ERROR(msg)
     151              :  end if
     152              : 
     153              : ! check input
     154        70446 :  if (nd1<n1 .or. nd2<n2 .or. nd3<n3) then
     155            0 :    ABI_ERROR("nd1<n1 .or. nd2<n2 .or. nd3<n3")
     156              :  end if
     157              : 
     158              :  ! Effective n1 and n2 (complex-to-complex or real-to-complex)
     159        70446 :  n1eff=n1; n2eff=n2; n1zt=n1
     160        70446 :  if (cplex==1) then
     161           92 :    n1eff=(n1+1)/2 ; n2eff=n2/2+1 ; n1zt=2*(n1/2+1)
     162              :  end if
     163              : 
     164        70446 :  lzt=n2eff
     165        70446 :  if (mod(n2eff,2) == 0) lzt=lzt+1
     166        70446 :  if (mod(n2eff,4) == 0) lzt=lzt+1
     167              : 
     168              : ! maximal number of big box 3rd dim slices for all procs
     169        70446 :  nnd3=nd3proc*nproc_fft
     170              : 
     171       211338 :  ABI_MALLOC(trig1,(2,n1))
     172        70446 :  ABI_MALLOC(after1,(mdata))
     173        70446 :  ABI_MALLOC(now1,(mdata))
     174        70446 :  ABI_MALLOC(before1,(mdata))
     175       211338 :  ABI_MALLOC(trig2,(2,n2))
     176        70446 :  ABI_MALLOC(after2,(mdata))
     177        70446 :  ABI_MALLOC(now2,(mdata))
     178        70446 :  ABI_MALLOC(before2,(mdata))
     179       211338 :  ABI_MALLOC(trig3,(2,n3))
     180        70446 :  ABI_MALLOC(after3,(mdata))
     181        70446 :  ABI_MALLOC(now3,(mdata))
     182        70446 :  ABI_MALLOC(before3,(mdata))
     183       281784 :  ABI_MALLOC(zw,(2,ncache/4,2))
     184       281784 :  ABI_MALLOC(zt,(2,lzt,n1zt))
     185       352230 :  ABI_MALLOC(zmpi2,(2,n1,nd2proc,nnd3))
     186        70446 :  if (nproc_fft>1)  then
     187        54288 :    ABI_MALLOC(zmpi1,(2,n1,nd2proc,nnd3))
     188              :  end if
     189              : 
     190        70446 :  call ctrig(n3,trig3,after3,before3,now3,1,ic3)
     191        70446 :  call ctrig(n1,trig1,after1,before1,now1,1,ic1)
     192        70446 :  call ctrig(n2,trig2,after2,before2,now2,1,ic2)
     193              : 
     194              : !DEBUG
     195              : ! write(std_out,'(a,3i4)' )'sg2002_back,zf n1,n2,n3',n1,n2,n3
     196              : ! write(std_out,'(a,3i4)' )'nd1,nd2,nd3proc',nd1,nd2,nd3proc
     197              : ! write(std_out,'(a,3i4)' )'m1,m2,m3',m1,m2,m3
     198              : ! write(std_out,'(a,3i4)' )'max1,max2,max3',max1,max2,max3
     199              : ! write(std_out,'(a,3i4)' )'md1,md2proc,md3',md1,md2proc,md3
     200              : ! write(std_out,'(a,3i4)' )'n1eff,m2eff,m1zt',n1eff,m2eff,m1zt
     201              : !ENDDEBUG
     202              : 
     203       140900 :  do idat=1,ndat
     204              :    ! transform along z axis
     205              :    ! input: I1,I3,J2,(Jp2)
     206        70454 :    lot=ncache/(4*n3)
     207              : 
     208       985673 :    do j2=1,nd2proc
     209       985673 :      if (me_fft*nd2proc+j2 <= n2eff) then
     210              : 
     211      2078304 :        do i1=1,n1,lot
     212      1163090 :          ma=i1
     213      1163090 :          mb=min(i1+(lot-1),n1)
     214      1163090 :          n1dfft=mb-ma+1
     215              : 
     216              :          ! input: G1,G3,G2,(Gp2)
     217      1163090 :          call fill(nd1,nd3,lot,n1dfft,n3,zf(1,i1,1,j2,idat),zw(1,1,1))
     218              : 
     219      1163090 :          inzee=1
     220      3887798 :          do i=1,ic3
     221              :            call fftstp(lot,n1dfft,n3,lot,n3,zw(1,1,inzee),zw(1,1,3-inzee), &
     222      2724708 : &                      trig3,after3(i),now3(i),before3(i),1)
     223      3887798 :            inzee=3-inzee
     224              :          end do
     225              : 
     226              :          ! input:  G1,R3,G2,(Gp2)
     227              :          ! output: G1,G2,R3,(Gp2)
     228      2078304 :          call scramble(i1,j2,lot,n1dfft,n1,n3,nd2proc,nd3,zw(1,1,inzee),zmpi2)
     229              :        end do
     230              :      end if
     231              :    end do
     232              : 
     233              :    ! Interprocessor data transposition
     234              :    ! input:  G1,G2,R3,Rp3,(Gp2)
     235              :    ! output: G1,G2,G3,Gp2,(Rp3)
     236        70454 :    if (nproc_fft>1) then
     237        13572 :      call timab(543,1,tsec)
     238              :      call xmpi_alltoall(zmpi2,2*n1*nd2proc*nd3proc, &
     239        13572 : &                       zmpi1,2*n1*nd2proc*nd3proc,comm_fft,ierr)
     240        13572 :      call timab(543,2,tsec)
     241              :    end if
     242              : 
     243      1061883 :    do j3=1,nd3proc
     244       991437 :      if (me_fft*nd3proc+j3 <= n3) then
     245       920983 :        Jp2st=1
     246       920983 :        J2st=1
     247              : 
     248              :        ! transform along x axis
     249       920983 :        lot=ncache/(4*n1)
     250              : 
     251      2086074 :        do j=1,n2eff,lot
     252      1165091 :          ma=j
     253      1165091 :          mb=min(j+(lot-1),n2eff)
     254      1165091 :          n1dfft=mb-ma+1
     255              : 
     256              :          ! input:  G1,G2,R3,Gp2,(Rp3)
     257              :          ! output: G2,G1,R3,Jp2,(Rp3)
     258      1165091 :          if (nproc_fft == 1) then
     259       865475 :            call mpiswitch(j3,n1dfft,Jp2st,J2st,lot,n1,nd2proc,nd3proc,nproc_fft,option,zmpi2,zw(1,1,1))
     260              :          else
     261       299616 :            call mpiswitch(j3,n1dfft,Jp2st,J2st,lot,n1,nd2proc,nd3proc,nproc_fft,option,zmpi1,zw(1,1,1))
     262              :          end if
     263              : 
     264              :          ! input:  G2,G1,R3,(Rp3)
     265              :          ! output: G2,R1,R3,(Rp3)
     266      1165091 :          inzee=1
     267      2708708 :          do i=1,ic1-1
     268              :            call fftstp(lot,n1dfft,n1,lot,n1,zw(1,1,inzee),zw(1,1,3-inzee), &
     269      1543617 : &                       trig1,after1(i),now1(i),before1(i),1)
     270      2708708 :            inzee=3-inzee
     271              :          end do
     272              : 
     273      1165091 :          i=ic1
     274              :          call fftstp(lot,n1dfft,n1,lzt,n1zt,zw(1,1,inzee),zt(1,j,1), &
     275      2086074 : &                    trig1,after1(i),now1(i),before1(i),1)
     276              :        end do
     277              : 
     278              :        ! transform along y axis
     279       920983 :        lot=ncache/(4*n2)
     280              : 
     281      2086074 :        do j=1,n1eff,lot
     282      1165091 :          ma=j
     283      1165091 :          mb=min(j+(lot-1),n1eff)
     284      1165091 :          n1dfft=mb-ma+1
     285      1165091 :          includelast=1
     286              : 
     287      1165091 :          if (cplex==1) then
     288         6480 :           jeff=2*j-1
     289              :           includelast=1
     290         6480 :           if (mb==n1eff .and. n1eff*2/=n1) includelast=0
     291              :          end if
     292              : 
     293              :          ! input:  G2,R1,R3,(Rp3)
     294              :          ! output: R1,G2,R3,(Rp3)
     295      1165091 :          if (cplex==2) then
     296      1158611 :            call switch(n1dfft,n2,lot,n1,lzt,zt(1,1,j),zw(1,1,1))
     297              :          else
     298         6480 :            call switchreal(includelast,n1dfft,n2,n2eff,lot,n1zt,lzt,zt(1,1,jeff),zw(1,1,1))
     299              :          end if
     300              : 
     301      1165091 :          inzee=1
     302      2708468 :          do i=1,ic2-1
     303              :            call fftstp(lot,n1dfft,n2,lot,n2,zw(1,1,inzee),zw(1,1,3-inzee), &
     304      1543377 : &                       trig2,after2(i),now2(i),before2(i),1)
     305      2708468 :            inzee=3-inzee
     306              :          end do
     307              : 
     308      1165091 :          i=ic2
     309              :          call fftstp(lot,n1dfft,n2,nd1eff,nd2,zw(1,1,inzee),zr(1,j,1,j3,idat), &
     310      2086074 : &                    trig2,after2(i),now2(i),before2(i),1)
     311              : 
     312              :        end do
     313              :        ! output: R1,R2,R3,(Rp3)
     314              : 
     315              :      end if
     316              :    end do
     317              :  end do ! idat
     318              : 
     319        70446 :  ABI_FREE(trig1)
     320        70446 :  ABI_FREE(after1)
     321        70446 :  ABI_FREE(now1)
     322        70446 :  ABI_FREE(before1)
     323        70446 :  ABI_FREE(trig2)
     324        70446 :  ABI_FREE(after2)
     325        70446 :  ABI_FREE(now2)
     326        70446 :  ABI_FREE(before2)
     327        70446 :  ABI_FREE(trig3)
     328        70446 :  ABI_FREE(after3)
     329        70446 :  ABI_FREE(now3)
     330        70446 :  ABI_FREE(before3)
     331        70446 :  ABI_FREE(zmpi2)
     332        70446 :  ABI_FREE(zw)
     333        70446 :  ABI_FREE(zt)
     334        70446 :  if (nproc_fft>1)  then
     335        13572 :    ABI_FREE(zmpi1)
     336              :  end if
     337              : 
     338        70446 : end subroutine sg2002_back
     339              : !!***
     340              : 
     341              : !----------------------------------------------------------------------
     342              : 
     343              : !!****f* m_sg2002/sg2002_forw
     344              : !! NAME
     345              : !!  sg2002_forw
     346              : !!
     347              : !! FUNCTION
     348              : !!   Adopt standard convention that isign=-1 for forward transform
     349              : !!   CALCULATES THE DISCRETE FOURIERTRANSFORM ZF(I1,I3,I2)=
     350              : !!   S_(j1,j2,j3) EXP(isign*i*2*pi*(j1*i1/n1+j2*i2/n2+j3*i3/n3)) ZR(j1,j2,j3)
     351              : !!   in parallel using MPI/OpenMP and BLAS library calls.
     352              : !!
     353              : !! INPUTS
     354              : !!    ZR: input array
     355              : !!         ZR(1,i1,i2,i3,idat)=real(R(i1,i2,i3,idat))
     356              : !!         ZR(2,i1,i2,i3,idat)=imag(R(i1,i2,i3,idat))
     357              : !!         i1=1,n1 , i2=1,n2 , i3=1,n3 , idat=1,ndat
     358              : !! OUTPUTS
     359              : !!    ZF: output array (note the switch of i2 and i3)
     360              : !!         real(F(i1,i3,i2,idat))=ZF(1,i1,i3,i2,idat)
     361              : !!         imag(F(i1,i3,i2,idat))=ZF(2,i1,i3,i2,idat)
     362              : !!         i1=1,n1 , i2=1,n2 , i3=1,n3 , idat=1,ndat
     363              : !!    nproc_fft: number of processors used as returned by MPI_COMM_SIZE
     364              : !!    me_fft: [0:nproc_fft-1] number of processor as returned by MPI_COMM_RANK
     365              : !!     n1,n2,n3: logical dimension of the transform. As transform lengths
     366              : !!               most products of the prime factors 2,3,5 are allowed.
     367              : !!              The detailed table with allowed transform lengths can
     368              : !!              be found in subroutine CTRIG
     369              : !!     nd1,nd2,nd3: Dimension of ZR and ZF
     370              : !!    nd2proc=((nd2-1)/nproc_fft)+1 maximal number of 2nd dim slices
     371              : !!    nd3proc=((nd3-1)/nproc_fft)+1 maximal number of 3rd dim slices
     372              : !!
     373              : !! NOTES
     374              : !!  SHOULD describe nd1eff
     375              : !!  SHOULD put cplex and nd1eff in OMP declarations
     376              : !!  SHOULD describe the change of value of nd2prod
     377              : !!
     378              : !!  The maximum number of processors that can reasonably be used is max(n2,n3)
     379              : !!
     380              : !!  It is very important to find the optimal
     381              : !!  value of NCACHE. NCACHE determines the size of the work array ZW, that
     382              : !!  has to fit into cache. It has therefore to be chosen to equal roughly
     383              : !!   half the size of the physical cache in units of real*8 numbers.
     384              : !!  The optimal value of ncache can easily be determined by numerical
     385              : !!  experimentation. A too large value of ncache leads to a dramatic
     386              : !!  and sudden decrease of performance, a too small value to a to a
     387              : !!  slow and less dramatic decrease of performance. If NCACHE is set
     388              : !!  to a value so small, that not even a single one dimensional transform
     389              : !!  can be done in the workarray zw, the program stops with an error message.
     390              : !!
     391              : !! SOURCE
     392              : 
     393        69867 : subroutine sg2002_forw(cplex,ndat,n1,n2,n3,nd1,nd2,nd3,nd1eff,nd2proc,nd3proc,option,zr,zf,comm_fft)
     394              : 
     395              : !Arguments ------------------------------------
     396              : !scalars
     397              :  integer,intent(in) :: cplex,comm_fft
     398              :  integer,intent(in) :: ndat,n1,n2,n3,nd1,nd2,nd3,nd1eff,nd2proc,nd3proc,option
     399              : !arrays
     400              :  real(dp),intent(in) :: zr(2,nd1eff,nd2,nd3proc,ndat)
     401              :  real(dp),intent(out) :: zf(2,nd1,nd3,nd2proc,ndat)
     402              : 
     403              : !Local variables-------------------------------
     404              : !scalars
     405              :  integer :: i,j,i1,ic1,ic2,ic3,idat,ierr,inzee,j2,j2st,j3,jp2st,lot,lzt
     406              :  integer :: ma,mb,n1dfft,n1eff,n2eff,n1zt,ncache,nnd3,nproc_fft,me_fft
     407              :  character(len=500) :: msg
     408              : !arrays
     409        69867 :  real(dp), allocatable :: zt(:,:,:) ! work arrays for transpositions
     410        69867 :  real(dp), allocatable :: zmpi1(:,:,:,:),zmpi2(:,:,:,:) ! work arrays for MPI
     411        69867 :  real(dp), allocatable :: zw(:,:,:) ! cache work array
     412              :  real(dp) :: tsec(2)
     413              : ! FFT work arrays
     414        69867 :  real(dp), allocatable, dimension(:,:) :: trig1,trig2,trig3
     415        69867 :  integer, allocatable, dimension(:) :: after1,now1,before1,after2,now2,before2,after3,now3,before3
     416              : 
     417              : ! *************************************************************************
     418              : 
     419        69867 :  nproc_fft = xmpi_comm_size(comm_fft); me_fft = xmpi_comm_rank(comm_fft)
     420              : 
     421              :  ! find cache size that gives optimal performance on machine
     422        69867 :  ncache=4*max(n1,n2,n3,1024)
     423        69867 :  if (ncache/(4*max(n1,n2,n3))<1) then
     424              :    write(msg,'(5a)')&
     425            0 : &     'ncache has to be enlarged to be able to hold at',ch10, &
     426            0 : &     'least one 1-d FFT of each size even though this will',ch10,&
     427            0 : &     'reduce the performance for shorter transform lengths'
     428            0 :    ABI_ERROR(msg)
     429              :  end if
     430              : 
     431              :  ! check input
     432        69867 :  if (nd1<n1 .or. nd2<n2 .or. nd3<n3) then
     433            0 :    ABI_ERROR("nd1<n1 .or. nd2<n2 .or. nd3<n3")
     434              :  end if
     435              : 
     436              : !Effective n1 and n2 (complex-to-complex or real-to-complex)
     437        69867 :  n1eff=n1; n2eff=n2; n1zt=n1
     438        69867 :  if (cplex==1) then
     439           80 :    n1eff=(n1+1)/2; n2eff=n2/2+1; n1zt=2*(n1/2+1)
     440              :  end if
     441              : 
     442        69867 :  lzt=n2eff
     443        69867 :  if (mod(n2eff,2) == 0) lzt=lzt+1
     444        69867 :  if (mod(n2eff,4) == 0) lzt=lzt+1
     445              : 
     446              :  ! maximal number of big box 3rd dim slices for all procs
     447        69867 :  nnd3=nd3proc*nproc_fft
     448              : 
     449       209601 :  ABI_MALLOC(trig1,(2,n1))
     450        69867 :  ABI_MALLOC(after1,(mdata))
     451        69867 :  ABI_MALLOC(now1,(mdata))
     452        69867 :  ABI_MALLOC(before1,(mdata))
     453       209601 :  ABI_MALLOC(trig2,(2,n2))
     454        69867 :  ABI_MALLOC(after2,(mdata))
     455        69867 :  ABI_MALLOC(now2,(mdata))
     456        69867 :  ABI_MALLOC(before2,(mdata))
     457       209601 :  ABI_MALLOC(trig3,(2,n3))
     458        69867 :  ABI_MALLOC(after3,(mdata))
     459        69867 :  ABI_MALLOC(now3,(mdata))
     460        69867 :  ABI_MALLOC(before3,(mdata))
     461       279468 :  ABI_MALLOC(zw,(2,ncache/4,2))
     462       279468 :  ABI_MALLOC(zt,(2,lzt,n1zt))
     463       349335 :  ABI_MALLOC(zmpi2,(2,n1,nd2proc,nnd3))
     464        69867 :  if (nproc_fft>1)  then
     465        53792 :    ABI_MALLOC(zmpi1,(2,n1,nd2proc,nnd3))
     466              :  end if
     467              : 
     468        69867 :  call ctrig(n2,trig2,after2,before2,now2,-1,ic2)
     469        69867 :  call ctrig(n1,trig1,after1,before1,now1,-1,ic1)
     470        69867 :  call ctrig(n3,trig3,after3,before3,now3,-1,ic3)
     471              : 
     472       139742 :  do idat=1,ndat
     473      1004478 :    do j3=1,nd3proc
     474      1004478 :      if (me_fft*(nd3proc)+j3 <= n3) then
     475       932830 :        Jp2st=1; J2st=1
     476              : 
     477              :        ! transform along y axis
     478              :        ! input: R1,R2,R3,(Rp3)
     479       932830 :        lot=ncache/(4*n2)
     480              : 
     481      2140692 :        do j=1,n1eff,lot
     482      1207862 :          ma=j
     483      1207862 :          mb=min(j+(lot-1),n1eff)
     484      1207862 :          n1dfft=mb-ma+1
     485      1207862 :          i=1
     486              :          call fftstp(nd1eff,n1dfft,nd2,lot,n2,zr(1,j,1,j3,idat),zw(1,1,1), &
     487      1207862 : &                    trig2,after2(i),now2(i),before2(i),-1)
     488              : 
     489      1207862 :          inzee=1
     490      2876183 :          do i=2,ic2
     491              :            call fftstp(lot,n1dfft,n2,lot,n2,zw(1,1,inzee),zw(1,1,3-inzee), &
     492      1668321 : &                       trig2,after2(i),now2(i),before2(i),-1)
     493      2876183 :             inzee=3-inzee
     494              :          end do
     495              : 
     496              :          !  input: R1,G2,R3,(Rp3)
     497              :          ! output: G2,R1,R3,(Rp3)
     498      2140692 :          if(cplex==2)then
     499      1201940 :            call unswitch(n1dfft,n2,lot,n1zt,lzt,zw(1,1,inzee),zt(1,1,j))
     500              :          else
     501         5922 :            call unswitchreal(n1dfft,n2,n2eff,lot,n1zt,lzt,zw(1,1,inzee),zt(1,1,2*j-1))
     502              :          end if
     503              :        end do
     504              : 
     505              :        ! transform along x axis
     506              :        ! input: G2,R1,R3,(Rp3)
     507       932830 :        lot=ncache/(4*n1)
     508              : 
     509      2140692 :        do j=1,n2eff,lot
     510      1207862 :          ma=j
     511      1207862 :          mb=min(j+(lot-1),n2eff)
     512      1207862 :          n1dfft=mb-ma+1
     513              : 
     514      1207862 :          i=1
     515              :          call fftstp(lzt,n1dfft,n1zt,lot,n1,zt(1,j,1),zw(1,1,1), &
     516      1207862 : &                    trig1,after1(i),now1(i),before1(i),-1)
     517              : 
     518      1207862 :          inzee=1
     519      2876423 :          do i=2,ic1
     520              :            call fftstp(lot,n1dfft,n1,lot,n1,zw(1,1,inzee),zw(1,1,3-inzee), &
     521      1668561 : &                     trig1,after1(i),now1(i),before1(i),-1)
     522      2876423 :            inzee=3-inzee
     523              :          end do
     524              :          ! output: G2,G1,R3,(Rp3)
     525              : 
     526              :          ! input:  G2,G1,R3,Gp2,(Rp3)
     527              :          ! output: G1,G2,R3,Gp2,(Rp3)
     528              :          ! write(std_out,*) 'J2st,Jp2st',J2st,Jp2st
     529      2140692 :          if (nproc_fft == 1) then
     530       851618 :            call unmpiswitch(j3,n1dfft,Jp2st,J2st,lot,n1,nd2proc,nd3proc,nproc_fft,option,zw(1,1,inzee),zmpi2)
     531              :          else
     532       356244 :            call unmpiswitch(j3,n1dfft,Jp2st,J2st,lot,n1,nd2proc,nd3proc,nproc_fft,option,zw(1,1,inzee),zmpi1)
     533              :          end if
     534              :        end do
     535              : 
     536              :      end if
     537              :    end do ! j3
     538              : 
     539              :    ! Interprocessor data transposition
     540              :    ! input:  G1,G2,R3,Gp2,(Rp3)
     541              :    ! output: G1,G2,R3,Rp3,(Gp2)
     542        69875 :    if (nproc_fft>1) then
     543        13448 :      call timab(544,1,tsec)
     544              :      call xmpi_alltoall(zmpi1,2*n1*nd2proc*nd3proc, &
     545        13448 : &                       zmpi2,2*n1*nd2proc*nd3proc,comm_fft,ierr)
     546        13448 :      call timab(544,2,tsec)
     547              :    end if
     548              : 
     549              :    ! transform along z axis
     550              :    ! input: G1,G2,R3,(Gp2)
     551        69875 :    lot=ncache/(4*n3)
     552              : 
     553      1067578 :    do j2=1,nd2proc
     554       997711 :      if (me_fft*(nd2proc)+j2 <= n2eff) then
     555      2133232 :        do i1=1,n1,lot
     556      1205401 :          ma=i1
     557      1205401 :          mb=min(i1+(lot-1),n1)
     558      1205401 :          n1dfft=mb-ma+1
     559              : 
     560              :          ! input:  G1,G2,R3,(Gp2)
     561              :          ! output: G1,R3,G2,(Gp2)
     562      1205401 :          call unscramble(i1,j2,lot,n1dfft,n1,n3,nd2proc,nd3,zmpi2,zw(1,1,1))
     563              : 
     564      1205401 :          inzee=1
     565      4094619 :          do i=1,ic3
     566              :            call fftstp(lot,n1dfft,n3,lot,n3,zw(1,1,inzee),zw(1,1,3-inzee), &
     567      2889218 : &            trig3,after3(i),now3(i),before3(i),-1)
     568      4094619 :            inzee=3-inzee
     569              :          end do
     570              : 
     571      2133232 :          call unfill(nd1,nd3,lot,n1dfft,n3,zw(1,1,inzee),zf(1,i1,1,j2,idat))
     572              :          ! output: G1,G3,G2,(Gp2)
     573              :        end do
     574              :      end if
     575              :    end do
     576              : 
     577              :  end do ! idat
     578              : 
     579        69867 :  ABI_FREE(trig1)
     580        69867 :  ABI_FREE(after1)
     581        69867 :  ABI_FREE(now1)
     582        69867 :  ABI_FREE(before1)
     583        69867 :  ABI_FREE(trig2)
     584        69867 :  ABI_FREE(after2)
     585        69867 :  ABI_FREE(now2)
     586        69867 :  ABI_FREE(before2)
     587        69867 :  ABI_FREE(trig3)
     588        69867 :  ABI_FREE(after3)
     589        69867 :  ABI_FREE(now3)
     590        69867 :  ABI_FREE(before3)
     591        69867 :  ABI_FREE(zmpi2)
     592        69867 :  ABI_FREE(zw)
     593        69867 :  ABI_FREE(zt)
     594        69867 :  if (nproc_fft>1)  then
     595        13448 :    ABI_FREE(zmpi1)
     596              :  end if
     597              : 
     598        69867 : end subroutine sg2002_forw
     599              : !!***
     600              : 
     601              : !----------------------------------------------------------------------
     602              : 
     603              : !!****f* m_sg2002/sg2002_mpiback_wf
     604              : !! NAME
     605              : !!  sg2002_mpiback_wf
     606              : !!
     607              : !! FUNCTION
     608              : !!   Does multiple 3-dim backward FFTs from Fourier into real space
     609              : !!   Adopt standard convention that isign=1 for backward transform
     610              : !!
     611              : !!   CALCULATES THE DISCRETE FOURIER TRANSFORM ZF(I1,I2,I3)=
     612              : !!
     613              : !!   S_(j1,j2,j3) EXP(isign*i*2*pi*(j1*i1/n1+j2*i2/n2+j3*i3/n3)) ZF(j1,j3,j2)
     614              : !!
     615              : !!   in parallel using MPI/OpenMP.
     616              : !!
     617              : !! INPUTS:
     618              : !!    icplexwf=1 if wavefunction is real, 2 if complex
     619              : !!    ndat=Number of wavefunctions to transform.
     620              : !!    n1,n2,n3: logical dimension of the transform. As transform lengths
     621              : !!              most products of the prime factors 2,3,5 are allowed.
     622              : !!              The detailed table with allowed transform lengths can be found in subroutine CTRIG
     623              : !!    nd1,nd2,nd3: Leading Dimension of ZR
     624              : !!    nd3proc=((nd3-1)/nproc_fft)+1 maximal number of big box 3rd dim slices for one proc
     625              : !!    max1 is positive or zero; m1 >=max1+1
     626              : !!      i1= 1... max1+1 corresponds to positive and zero wavevectors 0 ... max1
     627              : !!      then, if m1 > max1+1, one has min1=max1-m1+1 and
     628              : !!      i1= max1+2 ... m1 corresponds to negative wavevectors min1 ... -1
     629              : !!    max2 and max3 have a similar definition of range
     630              : !!    m1,m2,m3=Size of the box enclosing the G-sphere.
     631              : !!    md1,md2,md3: Dimension of ZF given on the **small** FFT box.
     632              : !!    md2proc=((md2-1)/nproc_fft)+1 maximal number of small box 2nd dim slices for one proc
     633              : !!    nproc_fft: number of processors used as returned by MPI_COMM_SIZE
     634              : !!    comm_fft=MPI communicator for the FFT.
     635              : !!    ZF: input array (note the switch of i2 and i3)
     636              : !!          real(F(i1,i3,i2,idat))=ZF(1,i1,i3,i2,idat)
     637              : !!          imag(F(i1,i3,i2,idat))=ZF(2,i1,i3,i2,idat)
     638              : !!
     639              : !! OUTPUTS
     640              : !!    ZR: output array
     641              : !!          ZR(1,i1,i2,i3,idat)=real(R(i1,i2,i3,idat))
     642              : !!          ZR(2,i1,i2,i3,idat)=imag(R(i1,i2,i3,idat))
     643              : !!        i1=1,n1 , i2=1,n2 , i3=1,n3 , idat=1,ndat
     644              : !!
     645              : !! NOTES
     646              : !!   The maximum number of processors that can reasonably be used is max(n2/2,n3/2)
     647              : !!
     648              : !!   It is very important to find the optimal
     649              : !!   value of NCACHE. NCACHE determines the size of the work array ZW, that
     650              : !!   has to fit into cache. It has therefore to be chosen to equal roughly
     651              : !!   half the size of the physical cache in units of real*8 numbers.
     652              : !!   The optimal value of ncache can easily be determined by numerical
     653              : !!   experimentation. A too large value of ncache leads to a dramatic
     654              : !!   and sudden decrease of performance, a too small value to a to a
     655              : !!   slow and less dramatic decrease of performance. If NCACHE is set
     656              : !!   to a value so small, that not even a single one dimensional transform
     657              : !!   can be done in the workarray zw, the program stops with an error message.
     658              : !!
     659              : !! SOURCE
     660              : 
     661       798252 : subroutine sg2002_mpiback_wf(icplexwf,ndat,n1,n2,n3,nd1,nd2,nd3proc,&
     662       798252 : &  max1,max2,max3,m1,m2,m3,md1,md2proc,md3,zf,zr,comm_fft)
     663              : 
     664              : !Arguments ------------------------------------
     665              :  integer,intent(in) :: icplexwf,ndat,n1,n2,n3,nd1,nd2,nd3proc
     666              :  integer,intent(in) :: max1,max2,max3,m1,m2,m3,md1,md2proc,md3,comm_fft
     667              :  real(dp),intent(in) :: zf(2,md1,md3,md2proc,ndat)
     668              :  real(dp),intent(out) :: zr(2,nd1,nd2,nd3proc,ndat)
     669              : 
     670              : !Local variables-------------------------------
     671              :  integer :: i,j,i1,i2,ic1,ic2,ic3,idat,ierr,inzee,includelast
     672              :  integer :: ioption,j2,j3,j2st,jp2st,jeff,lot,lzt,m1zt,ma,mb,n1dfft,nnd3
     673              :  integer :: m2eff,ncache,n1eff,n1half,nproc_fft,me_fft
     674              :  character(len=500) :: msg
     675              : !arrays
     676       798252 :  real(dp),allocatable :: zt(:,:,:) ! work arrays for transpositions
     677       798252 :  real(dp),allocatable :: zmpi1(:,:,:,:,:),zmpi2(:,:,:,:,:)  ! work arrays for MPI
     678       798252 :  real(dp),allocatable :: zw(:,:,:) ! cache work array
     679              : ! FFT work arrays
     680       798252 :  real(dp),allocatable :: trig1(:,:),trig2(:,:),trig3(:,:)
     681       798252 :  integer,allocatable :: after1(:),now1(:),before1(:),after2(:)
     682       798252 :  integer,allocatable :: now2(:),before2(:),after3(:),now3(:),before3(:)
     683              :  real(dp) :: tsec(2)
     684              : 
     685              : ! *************************************************************************
     686              : 
     687              :  ! call timab(541,1,tsec)
     688              :  ! FIXME must provide a default value but which one?
     689              :  ! ioption = 0
     690       798252 :  ioption = 1
     691              :  !if (paral_kgb==1) ioption=1
     692              : 
     693       798252 :  nproc_fft = xmpi_comm_size(comm_fft); me_fft = xmpi_comm_rank(comm_fft)
     694              : 
     695              :  ! Find cache size that gives optimal performance on machine
     696       798252 :  ncache=4*max(n1,n2,n3,1024)
     697       798252 :  if (ncache/(4*max(n1,n2,n3))<1) then
     698              :    write(msg,"(5a)") &
     699            0 : &    'ncache has to be enlarged to be able to hold at',ch10, &
     700            0 : &    'least one 1-d FFT of each size even though this will',ch10,&
     701            0 : &    'reduce the performance for shorter transform lengths'
     702            0 :     ABI_ERROR(msg)
     703              :  end if
     704              : 
     705              :  ! Effective m1 and m2 (complex-to-complex or real-to-complex)
     706       798252 :  n1eff=n1; m2eff=m2; m1zt=n1
     707       798252 :  if (icplexwf==1) then
     708           51 :    n1eff=(n1+1)/2; m2eff=m2/2+1; m1zt=2*(n1/2+1)
     709              :  end if
     710              : 
     711       798252 :  lzt=m2eff
     712       798252 :  if (mod(m2eff,2)==0) lzt=lzt+1
     713       701191 :  if (mod(m2eff,4)==0) lzt=lzt+1
     714              : 
     715              :  ! maximal number of big box 3rd dim slices for all procs
     716       798252 :  nnd3=nd3proc*nproc_fft
     717              : 
     718      2394756 :  ABI_MALLOC(trig1,(2,n1))
     719       798252 :  ABI_MALLOC(after1,(mdata))
     720       798252 :  ABI_MALLOC(now1,(mdata))
     721       798252 :  ABI_MALLOC(before1,(mdata))
     722      2394756 :  ABI_MALLOC(trig2,(2,n2))
     723       798252 :  ABI_MALLOC(after2,(mdata))
     724       798252 :  ABI_MALLOC(now2,(mdata))
     725       798252 :  ABI_MALLOC(before2,(mdata))
     726      2394756 :  ABI_MALLOC(trig3,(2,n3))
     727       798252 :  ABI_MALLOC(after3,(mdata))
     728       798252 :  ABI_MALLOC(now3,(mdata))
     729       798252 :  ABI_MALLOC(before3,(mdata))
     730              : 
     731              :  ! Allocate cache work array and work arrays for MPI transpositions.
     732      3193008 :  ABI_MALLOC(zw,(2,ncache/4,2))
     733      3193008 :  ABI_MALLOC(zt,(2,lzt,m1zt))
     734      4789512 :  ABI_MALLOC(zmpi2,(2,md1,md2proc,nnd3,ndat))
     735       798252 :  if (nproc_fft>1)  then
     736      3482150 :    ABI_MALLOC(zmpi1,(2,md1,md2proc,nnd3,ndat))
     737              :  end if
     738              : 
     739              :  ! Compute twiddle coefficients.
     740       798252 :  call ctrig(n3,trig3,after3,before3,now3,1,ic3)
     741       798252 :  call ctrig(n1,trig1,after1,before1,now1,1,ic1)
     742       798252 :  call ctrig(n2,trig2,after2,before2,now2,1,ic2)
     743              : 
     744              : !DEBUG
     745              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),': sg2002_mpiback_wf,zf n1,n2,n3',n1,n2,n3
     746              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),': nd1,nd2,nd3proc',nd1,nd2,nd3proc
     747              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),': m1,m2,m3',m1,m2,m3
     748              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),': max1,max2,max3',max1,max2,max3
     749              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),': md1,md2proc,md3',md1,md2proc,md3
     750              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),'n1eff,m2eff,m1zt',n1eff,m2eff,m1zt
     751              : !ENDDEBUG
     752              : 
     753      1647045 :  do idat=1,ndat
     754              : 
     755              :     ! transform along z axis
     756              :     ! input: G1,G3,G2,(Gp2)
     757       848793 :     lot=ncache/(4*n3)
     758              : 
     759   5217530571 :     zw(:,:,:)=zero
     760    629165709 :     zt(:,:,:)=zero
     761              : 
     762              :     ! Loop over the y planes treated by this node and trasform n1ddft G_z lines.
     763      5456324 :     do j2=1,md2proc
     764              : 
     765              :       ! if (me_fft*md2proc+j2<=m2eff) then !a faire plus tard
     766              : 
     767     10229324 :       do i1=1,m1,lot
     768      4773000 :         ma=i1
     769      4773000 :         mb=min(i1+(lot-1),m1)
     770      4773000 :         n1dfft=mb-ma+1
     771              : 
     772              :         ! zero-pad n1dfft G_z lines
     773              :         ! input:  G1,G3,G2,(Gp2)
     774              :         ! output: G1,R3,G2,(Gp2)
     775      4773000 :         call fill_cent(md1,md3,lot,n1dfft,max3,m3,n3,zf(1,i1,1,j2,idat),zw(1,1,1))
     776              : 
     777              :         ! Transform along z.
     778      4773000 :         inzee=1
     779     14617403 :         do i=1,ic3
     780              :           call fftstp(lot,n1dfft,n3,lot,n3,zw(1,1,inzee),zw(1,1,3-inzee), &
     781      9844403 : &                     trig3,after3(i),now3(i),before3(i),1)
     782     14617403 :           inzee=3-inzee
     783              :         end do
     784              : 
     785              :         ! Local rotation.
     786              :         ! input:  G1,R3,G2,(Gp2)
     787              :         ! output: G1,G2,R3,(Gp2)
     788      9380531 :         call scramble(i1,j2,lot,n1dfft,md1,n3,md2proc,nnd3,zw(1,1,inzee),zmpi2(:,:,:,:,idat))
     789              :       end do
     790              :       !
     791              :     end do ! j2
     792              : 
     793              :     ! Interprocessor data transposition
     794              :     ! input:  G1,G2,R3,Rp3,(Gp2)
     795              :     ! output: G1,G2,R3,Gp2,(Rp3)
     796       848793 :     if (nproc_fft>1) then
     797       715074 :       call timab(543,1,tsec)
     798              :       call xmpi_alltoall(zmpi2(:,:,:,:,idat),2*md1*md2proc*nd3proc, &
     799       715074 : &                        zmpi1(:,:,:,:,idat),2*md1*md2proc*nd3proc,comm_fft,ierr)
     800       715074 :       call timab(543,2,tsec)
     801              :     end if
     802              : 
     803              :     ! Loop over the z treated by this node.
     804     11218134 :     do j3=1,nd3proc
     805              :       !j3glob = j3 + me_fft*nd3proc
     806     10419882 :       if (me_fft*nd3proc+j3 <= n3) then
     807      9571089 :         Jp2st=1; J2st=1
     808              : 
     809      9571089 :         lot=ncache/(4*n1)
     810              : 
     811              :         ! Loop over G_y in the small box.
     812     19478978 :         do j=1,m2eff,lot
     813      9907889 :           ma=j
     814      9907889 :           mb=min(j+(lot-1),m2eff)
     815      9907889 :           n1dfft=mb-ma+1
     816              : 
     817              :           ! Zero-pad input.
     818              :           ! input:  G1,G2,R3,JG2,(Rp3)
     819              :           ! output: G2,G1,R3,JG2,(Rp3)
     820      9907889 :           if (nproc_fft==1) then
     821              :             call mpiswitch_cent(j3,n1dfft,Jp2st,J2st,lot,max1,md1,m1,n1,&
     822      2628931 : &             md2proc,nd3proc,nproc_fft,ioption,zmpi2(:,:,:,:,idat),zw(1,1,1),max2,m2,n2)
     823              :           else
     824              :             call mpiswitch_cent(j3,n1dfft,Jp2st,J2st,lot,max1,md1,m1,n1,&
     825      7278958 : &             md2proc,nd3proc,nproc_fft,ioption,zmpi1(:,:,:,:,idat),zw(1,1,1),max2,m2,n2)
     826              :           end if
     827              : 
     828              :           ! Transform along x
     829              :           ! input:  G2,G1,R3,(Rp3)
     830              :           ! output: G2,R1,R3,(Rp3)
     831      9907889 :           inzee=1
     832     20672388 :           do i=1,ic1-1
     833              :             call fftstp(lot,n1dfft,n1,lot,n1,zw(1,1,inzee),zw(1,1,3-inzee), &
     834     10764499 : &                       trig1,after1(i),now1(i),before1(i),1)
     835     20672388 :             inzee=3-inzee
     836              :           end do
     837              : 
     838      9907889 :           i=ic1
     839              :           call fftstp(lot,n1dfft,n1,lzt,m1zt,zw(1,1,inzee),zt(1,j,1), &
     840     19478978 : &                     trig1,after1(i),now1(i),before1(i),1)
     841              :         end do
     842              : 
     843              :         ! Transform along y axis (take into account c2c or c2r case).
     844              :         ! Must loop over the full box.
     845      9571089 :         lot=ncache/(4*n2)
     846              : 
     847     19830678 :         do j=1,n1eff,lot
     848     10259589 :           ma=j
     849     10259589 :           mb=min(j+(lot-1),n1eff)
     850     10259589 :           n1dfft=mb-ma+1
     851     10259589 :           includelast=1
     852     10259589 :           if (icplexwf==1) then
     853        15082 :             jeff=2*j-1
     854        15082 :             if (mb==n1eff .and. n1eff*2/=n1) includelast=0
     855              :           end if
     856              : 
     857              :           ! Zero-pad the input.
     858              :           ! input:  G2,R1,R3,(Rp3)
     859              :           ! output: R1,G2,R3,(Rp3)
     860     10259589 :           if (icplexwf==2) then
     861     10244507 :             call switch_cent(n1dfft,max2,m2,n2,lot,n1,lzt,zt(1,1,j),zw(1,1,1))
     862              :           else
     863        15082 :             call switchreal_cent(includelast,n1dfft,max2,n2,lot,m1zt,lzt,zt(1,1,jeff),zw(1,1,1))
     864              :           end if
     865              : 
     866              :           ! input:  R1,G2,R3,(Rp3)
     867              :           ! output: R1,R2,R3,(Rp3)
     868     10259589 :           inzee=1
     869     21485778 :           do i=1,ic2-1
     870              :             call fftstp(lot,n1dfft,n2,lot,n2,zw(1,1,inzee),zw(1,1,3-inzee), &
     871     11226189 : &                        trig2,after2(i),now2(i),before2(i),1)
     872     21485778 :             inzee=3-inzee
     873              :           end do
     874              : 
     875     10259589 :           i=ic2
     876              : 
     877              :         call fftstp(lot,n1dfft,n2,nd1,nd2,zw(1,1,inzee),zr(1,j,1,j3,idat), &
     878     19830678 : &                     trig2,after2(i),now2(i),before2(i),1)
     879              : 
     880              : 
     881              :         end do
     882              : 
     883              :         ! Treat real wavefunctions.
     884      9571089 :         if (icplexwf==1) then
     885         3882 :           n1half=n1/2
     886              :           ! If odd
     887         3882 :           if (n1half*2/=n1) then
     888       116800 :             do i2=1,n2
     889       115200 :               zr(1,n1,i2,j3,idat)=zr(1,n1eff,i2,j3,idat)
     890       116800 :               zr(2,n1,i2,j3,idat)=zero
     891              :             end do
     892              :           end if
     893       325850 :           do i2=1,n2
     894     14675946 :             do i1=n1half,1,-1
     895     14350096 :               zr(1,2*i1-1,i2,j3,idat)=zr(1,i1,i2,j3,idat)
     896     14350096 :               zr(1,2*i1  ,i2,j3,idat)=zr(2,i1,i2,j3,idat)
     897     14350096 :               zr(2,2*i1-1,i2,j3,idat)=zero
     898     14672064 :               zr(2,2*i1  ,i2,j3,idat)=zero
     899              :             end do
     900              :           end do
     901              :         end if
     902              : 
     903              :       end if
     904              : 
     905              :    end do ! j3
     906              :  end do ! idat
     907              : 
     908       798252 :  ABI_FREE(trig1)
     909       798252 :  ABI_FREE(after1)
     910       798252 :  ABI_FREE(now1)
     911       798252 :  ABI_FREE(before1)
     912       798252 :  ABI_FREE(trig2)
     913       798252 :  ABI_FREE(after2)
     914       798252 :  ABI_FREE(now2)
     915       798252 :  ABI_FREE(before2)
     916       798252 :  ABI_FREE(trig3)
     917       798252 :  ABI_FREE(after3)
     918       798252 :  ABI_FREE(now3)
     919       798252 :  ABI_FREE(before3)
     920       798252 :  ABI_FREE(zmpi2)
     921       798252 :  ABI_FREE(zw)
     922       798252 :  ABI_FREE(zt)
     923       798252 :  if (nproc_fft>1)  then
     924       696430 :    ABI_FREE(zmpi1)
     925              :  end if
     926              : 
     927              :  !call timab(541,2,tsec)
     928              : 
     929       798252 : end subroutine sg2002_mpiback_wf
     930              : !!***
     931              : 
     932              : !----------------------------------------------------------------------
     933              : 
     934              : !!****f* m_sg2002/sg2002_mpiforw_wf
     935              : !! NAME
     936              : !!  sg2002_mpiforw_wf
     937              : !!
     938              : !! FUNCTION
     939              : !!   Does multiple 3-dim backward FFTs from real into Fourier space
     940              : !!   Adopt standard convention that isign=-1 for forward transform
     941              : !!   CALCULATES THE DISCRETE FOURIERTRANSFORM
     942              : !!
     943              : !!   ZF(I1,I3,I2)=S_(j1,j2,j3) EXP(isign*i*2*pi*(j1*i1/n1+j2*i2/n2+j3*i3/n3)) ZR(j1,j2,j3)
     944              : !!
     945              : !!   in parallel using MPI/OpenMP.
     946              : !!
     947              : !! INPUT:
     948              : !!   ZR: input array
     949              : !!        ZR(1,i1,i2,i3,idat)=real(R(i1,i2,i3,idat))
     950              : !!        ZR(2,i1,i2,i3,idat)=imag(R(i1,i2,i3,idat))
     951              : !!        i1=1,n1 , i2=1,n2 , i3=1,n3 , idat=1,ndat
     952              : !!   NOTE that ZR is changed by the routine
     953              : !!
     954              : !!   n1,n2,n3: logical dimension of the transform. As transform lengths
     955              : !!             most products of the prime factors 2,3,5 are allowed.
     956              : !!             The detailed table with allowed transform lengths can
     957              : !!             be found in subroutine CTRIG
     958              : !!   nd1,nd2,nd3: Dimension of ZR
     959              : !!   nd3proc=((nd3-1)/nproc_fft)+1  maximal number of big box 3rd dim slices for one proc
     960              : !!
     961              : !! OUTPUT:
     962              : !!   ZF: output array (note the switch of i2 and i3)
     963              : !!        real(F(i1,i3,i2,idat))=ZF(1,i1,i3,i2,idat)
     964              : !!        imag(F(i1,i3,i2,idat))=ZF(2,i1,i3,i2,idat)
     965              : !!   max1 is positive or zero ; m1 >=max1+1
     966              : !!     i1= 1... max1+1 corresponds to positive and zero wavevectors 0 ... max1
     967              : !!     then, if m1 > max1+1, one has min1=max1-m1+1 and
     968              : !!     i1= max1+2 ... m1 corresponds to negative wavevectors min1 ... -1
     969              : !!     i2 and i3 have a similar definition of range
     970              : !!   idat=1,ndat
     971              : !!   md1,md2,md3: Dimension of ZF
     972              : !!   md2proc=((md2-1)/nproc_fft)+1  maximal number of small box 2nd dim slices for one proc
     973              : !!   nproc_fft: number of processors used as returned by MPI_COMM_SIZE
     974              : !!   me_fft: [0:nproc-1] rank of the processor in the FFT communicator.
     975              : !!   comm_fft=MPI communicator for parallel FFT.
     976              : !!
     977              : !! NOTES
     978              : !!  The maximum number of processors that can reasonably be used is max(n2/2,n3/2)
     979              : !!
     980              : !!  It is very important to find the optimal
     981              : !!  value of NCACHE. NCACHE determines the size of the work array ZW, that
     982              : !!  has to fit into cache. It has therefore to be chosen to equal roughly
     983              : !!   half the size of the physical cache in units of real*8 numbers.
     984              : !!  The optimal value of ncache can easily be determined by numerical
     985              : !!  experimentation. A too large value of ncache leads to a dramatic
     986              : !!  and sudden decrease of performance, a too small value to a to a
     987              : !!  slow and less dramatic decrease of performance. If NCACHE is set
     988              : !!  to a value so small, that not even a single one dimensional transform
     989              : !!  can be done in the workarray zw, the program stops with an error message.
     990              : !!
     991              : !! SOURCE
     992              : 
     993       735144 : subroutine sg2002_mpiforw_wf(icplexwf,ndat,n1,n2,n3,nd1,nd2,nd3proc,&
     994       735144 : &        max1,max2,max3,m1,m2,m3,md1,md2proc,md3,zr,zf,comm_fft)
     995              : 
     996              : !Arguments ------------------------------------
     997              : !scalars
     998              :  integer,intent(in) :: icplexwf,ndat,n1,n2,n3,nd1,nd2,nd3proc
     999              :  integer,intent(in) :: max1,max2,max3,m1,m2,m3,md1,md2proc,md3,comm_fft
    1000              : !arrays
    1001              :  real(dp),intent(inout) :: zr(2,nd1,nd2,nd3proc,ndat)
    1002              :  real(dp),intent(out) :: zf(2,md1,md3,md2proc,ndat)
    1003              : 
    1004              : !Local variables-------------------------------
    1005              : !scalars
    1006              :  integer :: i,j,i1,i2,i3,ic1,ic2,ic3,idat,ierr,inzee,nproc_fft,me_fft
    1007              :  integer :: ioption,j2,j3,j2st,jp2st,lot,lzt,m1zt,ma,mb,n1dfft,nnd3
    1008              :  integer :: m2eff,ncache,n1eff,n1half,i1inv,i2inv,i3inv
    1009              :  character(len=500) :: msg
    1010              : !arrays
    1011       735144 :  real(dp), allocatable :: zt(:,:,:) ! work arrays for transpositions
    1012       735144 :  real(dp), allocatable :: zmpi1(:,:,:,:,:),zmpi2(:,:,:,:,:) ! work arrays for MPI
    1013       735144 :  real(dp), allocatable :: zw(:,:,:) ! cache work array
    1014              : ! FFT work arrays
    1015       735144 :  real(dp), allocatable :: trig1(:,:),trig2(:,:),trig3(:,:)
    1016       735144 :  integer, allocatable :: after1(:),now1(:),before1(:),after2(:),now2(:),before2(:),after3(:),now3(:),before3(:)
    1017              :  real(dp) :: tsec(2)
    1018              : 
    1019              : ! *************************************************************************
    1020              : 
    1021              :  ! call timab(542,1,tsec)
    1022              : 
    1023              :  ! FIXME must provide a default value but which one?
    1024              :  !ioption = 0
    1025       735144 :  ioption = 1
    1026              :  !if (paral_kgb==1) ioption=1
    1027              : 
    1028       735144 :  nproc_fft = xmpi_comm_size(comm_fft); me_fft = xmpi_comm_rank(comm_fft)
    1029              : 
    1030              :  ! find cache size that gives optimal performance on machine
    1031       735144 :  ncache=4*max(n1,n2,n3,1024)
    1032       735144 :  if (ncache/(4*max(n1,n2,n3))<1) then
    1033              :    write(msg,'(5a)') &
    1034            0 : &    'ncache has to be enlarged to be able to hold at',ch10, &
    1035            0 : &    'least one 1-d FFT of each size even though this will',ch10,&
    1036            0 : &    'reduce the performance for shorter transform lengths'
    1037            0 :    ABI_ERROR(msg)
    1038              :  end if
    1039              : 
    1040              :  ! Effective m1 and m2 (complex-to-complex or real-to-complex)
    1041       735144 :  n1eff=n1; m2eff=m2; m1zt=n1
    1042       735144 :  if (icplexwf==1) then
    1043           35 :    n1eff=(n1+1)/2; m2eff=m2/2+1; m1zt=2*(n1/2+1)
    1044              :  end if
    1045              : 
    1046       735144 :  lzt=m2eff
    1047       735144 :  if (mod(m2eff,2)==0) lzt=lzt+1
    1048       652351 :  if (mod(m2eff,4)==0) lzt=lzt+1
    1049              : 
    1050              :  ! maximal number of big box 3rd dim slices for all procs
    1051       735144 :  nnd3=nd3proc*nproc_fft
    1052              : 
    1053      2205432 :  ABI_MALLOC(trig1,(2,n1))
    1054       735144 :  ABI_MALLOC(after1,(mdata))
    1055       735144 :  ABI_MALLOC(now1,(mdata))
    1056       735144 :  ABI_MALLOC(before1,(mdata))
    1057      2205432 :  ABI_MALLOC(trig2,(2,n2))
    1058       735144 :  ABI_MALLOC(after2,(mdata))
    1059       735144 :  ABI_MALLOC(now2,(mdata))
    1060       735144 :  ABI_MALLOC(before2,(mdata))
    1061      2205432 :  ABI_MALLOC(trig3,(2,n3))
    1062       735144 :  ABI_MALLOC(after3,(mdata))
    1063       735144 :  ABI_MALLOC(now3,(mdata))
    1064       735144 :  ABI_MALLOC(before3,(mdata))
    1065      2940576 :  ABI_MALLOC(zw,(2,ncache/4,2))
    1066      2940576 :  ABI_MALLOC(zt,(2,lzt,m1zt))
    1067      4410864 :  ABI_MALLOC(zmpi2,(2,md1,md2proc,nnd3,ndat))
    1068       735144 :  if (nproc_fft>1)  then
    1069      3242980 :    ABI_MALLOC(zmpi1,(2,md1,md2proc,nnd3,ndat))
    1070              :  end if
    1071              : 
    1072       735144 :  call ctrig(n2,trig2,after2,before2,now2,-1,ic2)
    1073       735144 :  call ctrig(n1,trig1,after1,before1,now1,-1,ic1)
    1074       735144 :  call ctrig(n3,trig3,after3,before3,now3,-1,ic3)
    1075              : 
    1076              : !DEBUG
    1077              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),'sg2002_mpiforw_wf, enter', i1,i2,i3,zr,n1,n2,n3',n1,n2,n3
    1078              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),'nd1,nd2,nd3proc',nd1,nd2,nd3proc
    1079              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),'m1,m2,m3',m1,m2,m3
    1080              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),'max1,max2,max3',max1,max2,max3
    1081              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),'md1,md2proc,md3',md1,md2proc,md3
    1082              : ! write(std_out,'(2a,3i4)' )itoa(me_fft),'n1eff,m2eff,m1zt',n1eff,m2eff,m1zt
    1083              : !ENDDEBUG
    1084              : 
    1085      1520819 :   do idat=1,ndat
    1086              :     ! Loop over the z-planes treated by this node
    1087      9598729 :     do j3=1,nd3proc
    1088              : 
    1089      9598729 :        if (me_fft*nd3proc+j3 <= n3) then
    1090      8813054 :          Jp2st=1
    1091      8813054 :          J2st=1
    1092              : 
    1093              :          ! Treat real wavefunctions.
    1094      8813054 :          if (icplexwf==1) then
    1095         2826 :            n1half=n1/2
    1096       242250 :            do i2=1,n2
    1097     10977498 :              do i1=1,n1half
    1098     10735248 :                zr(1,i1,i2,j3,idat)=zr(1,2*i1-1,i2,j3,idat)
    1099     10974672 :                zr(2,i1,i2,j3,idat)=zr(1,2*i1  ,i2,j3,idat)
    1100              :              end do
    1101              :            end do
    1102              :            ! If odd
    1103         2826 :            if(n1half*2/=n1)then
    1104        87600 :              do i2=1,n2
    1105        86400 :                zr(1,n1eff,i2,j3,idat)=zr(1,n1,i2,j3,idat)
    1106        87600 :                zr(2,n1eff,i2,j3,idat)=zero
    1107              :              end do
    1108              :            end if
    1109              :          end if
    1110              : 
    1111              :          ! transform along y axis
    1112              :          ! input: R1,R2,R3,(Rp3)
    1113              :          ! input: R1,G2,R3,(Rp3)
    1114      8813054 :          lot=ncache/(4*n2)
    1115              : 
    1116     18197068 :          do j=1,n1eff,lot
    1117      9384014 :            ma=j
    1118      9384014 :            mb=min(j+(lot-1),n1eff)
    1119      9384014 :            n1dfft=mb-ma+1
    1120      9384014 :            i=1
    1121              :            call fftstp(nd1,n1dfft,nd2,lot,n2,zr(1,j,1,j3,idat),zw(1,1,1), &
    1122      9384014 : &                      trig2,after2(i),now2(i),before2(i),-1)
    1123              : 
    1124      9384014 :            inzee=1
    1125     19577528 :            do i=2,ic2
    1126              :              call fftstp(lot,n1dfft,n2,lot,n2,zw(1,1,inzee),zw(1,1,3-inzee), &
    1127     10193514 : &                         trig2,after2(i),now2(i),before2(i),-1)
    1128     19577528 :               inzee=3-inzee
    1129              :            end do
    1130              : 
    1131              :            ! input:  R1,G2,R3,(Rp3)
    1132              :            ! output: G2,R1,R3,(Rp3)
    1133     18197068 :            if(icplexwf==2)then
    1134      9372788 :              call unswitch_cent(n1dfft,max2,m2,n2,lot,n1,lzt,zw(1,1,inzee),zt(1,1,j))
    1135              :            else
    1136        11226 :              call unswitchreal_cent(n1dfft,max2,n2,lot,n1,lzt,zw(1,1,inzee),zt(1,1,2*j-1))
    1137              :            end if
    1138              :          end do
    1139              : 
    1140              :          ! transform along x axis
    1141              :          ! input: G2,R1,R3,(Rp3)
    1142      8813054 :          lot=ncache/(4*n1)
    1143              : 
    1144     17907588 :          do j=1,m2eff,lot
    1145      9094534 :            ma=j
    1146      9094534 :            mb=min(j+(lot-1),m2eff)
    1147      9094534 :            n1dfft=mb-ma+1
    1148      9094534 :            i=1
    1149              :            call fftstp(lzt,n1dfft,m1zt,lot,n1,zt(1,j,1),zw(1,1,1), &
    1150      9094534 : &                      trig1,after1(i),now1(i),before1(i),-1)
    1151              : 
    1152      9094534 :            inzee=1
    1153     18944468 :            do i=2,ic1
    1154              :              call fftstp(lot,n1dfft,n1,lot,n1,zw(1,1,inzee),zw(1,1,3-inzee), &
    1155      9849934 : &                        trig1,after1(i),now1(i),before1(i),-1)
    1156     18944468 :              inzee=3-inzee
    1157              :            end do
    1158              :            ! output: G2,G1,R3,(Rp3)
    1159              : 
    1160              :            ! input:  G2,G1,R3,Gp2,(Rp3)
    1161              :            ! output: G1,G2,R3,Gp2,(Rp3)
    1162     17907588 :            if (nproc_fft==1) then
    1163              :              call unmpiswitch_cent(j3,n1dfft,Jp2st,J2st,lot,max1,md1,m1,n1,&
    1164      2303766 : &              md2proc,nd3proc,nproc_fft,ioption,zw(1,1,inzee),zmpi2(:,:,:,:,idat))
    1165              :            else
    1166              :              call unmpiswitch_cent(j3,n1dfft,Jp2st,J2st,lot,max1,md1,m1,n1,&
    1167      6790768 : &              md2proc,nd3proc,nproc_fft,ioption,zw(1,1,inzee),zmpi1(:,:,:,:,idat))
    1168              :            end if
    1169              :          end do
    1170              : 
    1171              :         end if
    1172              :      end do ! j3
    1173              : 
    1174              :      ! Interprocessor data transposition
    1175              :      ! input:  G1,G2,R3,Gp2,(Rp3)
    1176              :      ! output: G1,G2,R3,Rp3,(Gp2)
    1177       785675 :      if (nproc_fft>1) then
    1178       667240 :         call timab(544,1,tsec)
    1179              :         call xmpi_alltoall(zmpi1(:,:,:,:,idat),2*md1*md2proc*nd3proc, &
    1180       667240 : &                          zmpi2(:,:,:,:,idat),2*md1*md2proc*nd3proc,comm_fft,ierr)
    1181              : 
    1182       667240 :         call timab(544,2,tsec)
    1183              :      end if
    1184              : 
    1185              :      ! transform along z axis
    1186              :      ! input: G1,G2,R3,(Gp2)
    1187       785675 :      lot=ncache/(4*n3)
    1188              : 
    1189      5032424 :      do j2=1,md2proc
    1190      5032424 :        if (me_fft*md2proc+j2 <= m2eff) then
    1191              :          ! write(std_out,*)' forwf_wf : before unscramble, j2,md2proc,me_fft,m2=',j2,md2proc,me_fft,m2
    1192      8627848 :          do i1=1,m1,lot
    1193      4381724 :            ma=i1
    1194      4381724 :            mb=min(i1+(lot-1),m1)
    1195      4381724 :            n1dfft=mb-ma+1
    1196              : 
    1197              :            ! input:  G1,G2,R3,(Gp2)
    1198              :            ! output: G1,R3,G2,(Gp2)
    1199      4381724 :            call unscramble(i1,j2,lot,n1dfft,md1,n3,md2proc,nnd3,zmpi2(:,:,:,:,idat),zw(1,1,1))
    1200              : 
    1201      4381724 :            inzee=1
    1202     13394469 :            do i=1,ic3
    1203              :              call fftstp(lot,n1dfft,n3,lot,n3,zw(1,1,inzee),zw(1,1,3-inzee), &
    1204      9012745 : &              trig3,after3(i),now3(i),before3(i),-1)
    1205     13394469 :              inzee=3-inzee
    1206              :            end do
    1207              : 
    1208      8627848 :            call unfill_cent(md1,md3,lot,n1dfft,max3,m3,n3,zw(1,1,inzee),zf(1,i1,1,j2,idat))
    1209              :            ! output: G1,G3,G2,(Gp2)
    1210              :          end do
    1211              :        end if
    1212              :      end do
    1213              : 
    1214      1520819 :      if (icplexwf==1) then
    1215              :        ! Complete missing values with complex conjugate
    1216              :        ! Inverse of ix is located at nx+2-ix , except for ix=1, for which it is 1.
    1217         1414 :        do i3=1,m3
    1218         1379 :          i3inv=m3+2-i3
    1219         1379 :          if(i3==1)i3inv=1
    1220              : 
    1221         1414 :          if (m2eff>1) then
    1222        28674 :            do i2=2,m2eff
    1223        27295 :              i2inv=m2+2-i2
    1224        27295 :              zf(1,1,i3inv,i2inv,idat)= zf(1,1,i3,i2,idat)
    1225        27295 :              zf(2,1,i3inv,i2inv,idat)=-zf(2,1,i3,i2,idat)
    1226      1215604 :              do i1=2,m1
    1227      1186930 :                i1inv=m1+2-i1
    1228      1186930 :                zf(1,i1inv,i3inv,i2inv,idat)= zf(1,i1,i3,i2,idat)
    1229      1214225 :                zf(2,i1inv,i3inv,i2inv,idat)=-zf(2,i1,i3,i2,idat)
    1230              :              end do
    1231              :            end do
    1232              :          end if
    1233              :        end do
    1234              :      end if
    1235              : 
    1236              :  end do ! idat
    1237              : 
    1238       735144 :  ABI_FREE(trig1)
    1239       735144 :  ABI_FREE(after1)
    1240       735144 :  ABI_FREE(now1)
    1241       735144 :  ABI_FREE(before1)
    1242       735144 :  ABI_FREE(trig2)
    1243       735144 :  ABI_FREE(after2)
    1244       735144 :  ABI_FREE(now2)
    1245       735144 :  ABI_FREE(before2)
    1246       735144 :  ABI_FREE(trig3)
    1247       735144 :  ABI_FREE(after3)
    1248       735144 :  ABI_FREE(now3)
    1249       735144 :  ABI_FREE(before3)
    1250       735144 :  ABI_FREE(zmpi2)
    1251       735144 :  ABI_FREE(zw)
    1252       735144 :  ABI_FREE(zt)
    1253       735144 :  if (nproc_fft>1)  then
    1254       648596 :    ABI_FREE(zmpi1)
    1255              :  end if
    1256              : 
    1257              :  !call timab(542,2,tsec)
    1258              : 
    1259       735144 : end subroutine sg2002_mpiforw_wf
    1260              : !!***
    1261              : 
    1262              : !----------------------------------------------------------------------
    1263              : 
    1264              : !!****f* m_sg2002/sg2002_mpifourdp
    1265              : !! NAME
    1266              : !! sg2002_mpifourdp
    1267              : !!
    1268              : !! FUNCTION
    1269              : !! Conduct Fourier transform of REAL or COMPLEX function f(r)=fofr defined on
    1270              : !! fft grid in real space, to create complex f(G)=fofg defined on full fft grid
    1271              : !! in reciprocal space, in full storage mode, or the reverse operation.
    1272              : !! For the reverse operation, the final data is divided by nfftot.
    1273              : !! REAL case when cplex=1, COMPLEX case when cplex=2
    1274              : !! Usually used for density and potentials.
    1275              : !!
    1276              : !! INPUTS
    1277              : !! cplex=1 if fofr is real, 2 if fofr is complex
    1278              : !! nfft=(effective) number of FFT grid points (for this processor)
    1279              : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
    1280              : !! ndat=Numbre of FFT transforms
    1281              : !! isign=sign of Fourier transform exponent: current convention uses
    1282              : !!    +1 for transforming from G to r
    1283              : !!    -1 for transforming from r to G.
    1284              : !! fftn2_distrib(2),ffti2_local(2)
    1285              : !! fftn3_distrib(3),ffti3_local(3)
    1286              : !! comm_fft=MPI communicator
    1287              : !!
    1288              : !! SIDE EFFECTS
    1289              : !! Input/Output
    1290              : !! fofg(2,nfft)=f(G), complex.
    1291              : !! fofr(cplex*nfft)=input function f(r) (real or complex)
    1292              : !!
    1293              : !! TODO
    1294              : !!  Write simplified API for sequential version.
    1295              : !!
    1296              : !! SOURCE
    1297              : 
    1298       135120 : subroutine sg2002_mpifourdp(cplex,nfft,ngfft,ndat,isign,&
    1299       135120 : &  fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local,fofg,fofr,comm_fft)
    1300              : 
    1301              : !Arguments ------------------------------------
    1302              : !scalars
    1303              :  integer,intent(in) :: cplex,isign,nfft,ndat,comm_fft
    1304              : !arrays
    1305              :  integer,intent(in) :: ngfft(18)
    1306              :  integer,intent(in) :: fftn2_distrib(ngfft(2)),ffti2_local(ngfft(2))
    1307              :  integer,intent(in) :: fftn3_distrib(ngfft(3)),ffti3_local(ngfft(3))
    1308              :  real(dp),intent(inout) :: fofg(2,nfft*ndat),fofr(cplex*nfft*ndat)
    1309              : 
    1310              : !Local variables-------------------------------
    1311              : !scalars
    1312              :  integer :: n1,n2,n3,n4,n5,n6,nd2proc,nd3proc,nproc_fft,me_fft
    1313              : !arrays
    1314       135120 :  real(dp),allocatable :: workf(:,:,:,:,:),workr(:,:,:,:,:)
    1315              : 
    1316              : ! *************************************************************************
    1317              : 
    1318              :  ! Note the only c2c is supported in parallel.
    1319       135120 :  n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
    1320       135120 :  n4=ngfft(4); n5=ngfft(5); n6=ngfft(6)
    1321       135120 :  me_fft=ngfft(11); nproc_fft=ngfft(10)
    1322              : 
    1323       135120 :  nd2proc=((n2-1)/nproc_fft) +1
    1324       135120 :  nd3proc=((n6-1)/nproc_fft) +1
    1325       810720 :  ABI_MALLOC(workr,(2,n4,n5,nd3proc,ndat))
    1326       810720 :  ABI_MALLOC(workf,(2,n4,n6,nd2proc,ndat))
    1327              : 
    1328              :  ! Complex to Complex
    1329       202803 :  select case (isign)
    1330              :  case (1)
    1331              :    ! G --> R
    1332        67683 :    call mpifft_fg2dbox(nfft,ndat,fofg,n1,n2,n3,n4,nd2proc,n6,fftn2_distrib,ffti2_local,me_fft,workf)
    1333              : 
    1334        67683 :    call sg2002_back(2,ndat,n1,n2,n3,n4,n5,n6,n4,nd2proc,nd3proc,2,workf,workr,comm_fft)
    1335              : 
    1336        67683 :    call mpifft_dbox2fr(n1,n2,n3,n4,n5,nd3proc,ndat,fftn3_distrib,ffti3_local,me_fft,workr,cplex,nfft,fofr)
    1337              : 
    1338              :  case (-1)
    1339              :    ! R --> G
    1340        67437 :    call mpifft_fr2dbox(cplex,nfft,ndat,fofr,n1,n2,n3,n4,n5,nd3proc,fftn3_distrib,ffti3_local,me_fft,workr)
    1341              : 
    1342        67437 :    call sg2002_forw(2,ndat,n1,n2,n3,n4,n5,n6,n4,nd2proc,nd3proc,2,workr,workf,comm_fft)
    1343              : 
    1344              :    ! Transfer FFT output to the original fft box.
    1345        67437 :    call mpifft_dbox2fg(n1,n2,n3,n4,nd2proc,n6,ndat,fftn2_distrib,ffti2_local,me_fft,workf,nfft,fofg)
    1346              : 
    1347              :  case default
    1348       135120 :    ABI_BUG("Wrong isign")
    1349              :  end select
    1350              : 
    1351       135120 :  ABI_FREE(workr)
    1352       135120 :  ABI_FREE(workf)
    1353              : 
    1354       135120 : end subroutine sg2002_mpifourdp
    1355              : !!***
    1356              : 
    1357              : !----------------------------------------------------------------------
    1358              : 
    1359              : !!****f* m_sg2002/sg2002_applypot
    1360              : !! NAME
    1361              : !!  sg2002_applypot
    1362              : !!
    1363              : !! FUNCTION
    1364              : !! Applies the local real space potential to multiple wavefunctions in Fourier space
    1365              : !!
    1366              : !! INPUTS
    1367              : !!   ZF: Wavefunction (input/output) (note the switch of i2 and i3)
    1368              : !!        real(F(i1,i3,i2,idat))=ZF(1,i1,i3,i2,idat)
    1369              : !!        imag(F(i1,i3,i2,idat))=ZF(2,i1,i3,i2,idat)
    1370              : !!   max1 is positive or zero ; m1 >=max1+1
    1371              : !!   i1= 1... max1+1 corresponds to positive and zero wavevectors 0 ... max1
    1372              : !!   then, if m1 > max1+1, one has min1=max1-m1+1 and
    1373              : !!   i1= max1+2 ... m1 corresponds to negative wavevectors min1 ... -1
    1374              : !!   i2 and i3 have a similar definition of range
    1375              : !!   idat=1,ndat
    1376              : !!   md1,md2,md3: Dimension of ZF (input as well as output), distributed on different procs
    1377              : !!   md2proc=((md2-1)/nproc_fft)+1  maximal number of small box 2nd dim slices for one proc
    1378              : !!
    1379              : !!   POT: Potential
    1380              : !!        POT(cplex*i1,i2,i3)
    1381              : !!        cplex=1 or 2 ,  i1=1,n1 , i2=1,n2 , i3=1,n3
    1382              : !!   nd1,nd2,nd3: dimension of pot
    1383              : !!   comm_fft: MPI communicator
    1384              : !!   nproc_fft: number of processors used as returned by MPI_COMM_SIZE
    1385              : !!   me_fft: [0:nproc_fft-1] number of processor as returned by MPI_COMM_RANK
    1386              : !!    n1,n2,n3: logical dimension of the transform. As transform lengths
    1387              : !!              most products of the prime factors 2,3,5 are allowed.
    1388              : !!             The detailed table with allowed transform lengths can
    1389              : !!             be found in subroutine CTRIG
    1390              : !!
    1391              : !! NOTES:
    1392              : !!   PERFORMANCE CONSIDERATIONS:
    1393              : !!   The maximum number of processors that can reasonably be used is max(n2/2,n3/2)
    1394              : !!
    1395              : !!   It is very important to find the optimal
    1396              : !!   value of NCACHE. NCACHE determines the size of the work array ZW, that
    1397              : !!   has to fit into cache. It has therefore to be chosen to equal roughly
    1398              : !!    half the size of the physical cache in units of real*8 numbers.
    1399              : !!   The optimal value of ncache can easily be determined by numerical
    1400              : !!   experimentation. A too large value of ncache leads to a dramatic
    1401              : !!   and sudden decrease of performance, a too small value to a to a
    1402              : !!   slow and less dramatic decrease of performance. If NCACHE is set
    1403              : !!   to a value so small, that not even a single one dimensional transform
    1404              : !!   can be done in the workarray zw, the program stops with an error message.
    1405              : !!
    1406              : !! SOURCE
    1407              : 
    1408              : 
    1409          223 : subroutine sg2002_applypot(icplexwf,cplex,ndat,n1,n2,n3,nd1,nd2,nd3,nd3proc,&
    1410              : &  max1i,max2i,max3i,m1i,m2i,m3i,md1,md2proc,md3,&
    1411          223 : &  max1o,max2o,max3o,m1o,m2o,m3o,comm_fft,nproc_fft,me_fft,pot,zf)
    1412              : 
    1413              : !Arguments ------------------------------------
    1414              :  integer,intent(in) :: icplexwf,cplex,ndat,n1,n2,n3,nd1,nd2,nd3,nd3proc
    1415              :  integer,intent(in) :: max1i,max2i,max3i,m1i,m2i,m3i,md1,md2proc,md3
    1416              :  integer,intent(in) :: max1o,max2o,max3o,m1o,m2o,m3o,comm_fft,nproc_fft,me_fft
    1417              :  real(dp),intent(in) :: pot(cplex*nd1,nd2,nd3)
    1418              :  real(dp),intent(inout) :: zf(2,md1,md3,md2proc,ndat)
    1419              : 
    1420              : !Local variables-------------------------------
    1421              : !scalars
    1422              :  integer,parameter :: unused0=0
    1423              :  integer :: i,j,i1,i2,i3,ic1,ic2,ic3,idat,ierr,inzee,j3glob
    1424              :  integer :: ioption,j2,j3,lot,lzt,m1zt,ma,mb,n1dfft,nnd3
    1425              :  integer :: m2eff,ncache,n1eff,i1inv,i2inv,i3inv,jeff,includelast,j2stb
    1426              :  integer :: jx,j2stf,Jp2stb,Jp2stf,m2ieff,m2oeff
    1427              : !arrays
    1428              :  real(dp) :: tsec(2)
    1429          223 :  real(dp), allocatable :: zt(:,:,:) ! work arrays for transpositions
    1430          223 :  real(dp), allocatable :: zmpi1(:,:,:,:),zmpi2(:,:,:,:) ! work arrays for MPI
    1431          223 :  real(dp), allocatable :: zw(:,:,:) ! cache work array
    1432              : ! FFT work arrays
    1433          223 :  real(dp), allocatable, dimension(:,:) :: btrig1,btrig2,btrig3
    1434          223 :  real(dp), allocatable, dimension(:,:) :: ftrig1,ftrig2,ftrig3
    1435          223 :  integer, allocatable, dimension(:) :: after1,now1,before1,after2,now2,before2,after3,now3,before3
    1436              : 
    1437              : ! *************************************************************************
    1438              : 
    1439              :  !ioption=0 ! This was in the old version.
    1440          223 :  ioption=1 ! This one is needed to be compatible with paral_kgb
    1441              : 
    1442          223 :  ncache=4*max(n1,n2,n3,1024)
    1443          223 :  if (ncache/(4*max(n1,n2,n3)) < 1) then
    1444              :    write(std_out,*) &
    1445            0 : &    'ncache has to be enlarged to be able to hold at', &
    1446            0 : &    'least one 1-d FFT of each size even though this will', &
    1447            0 : &    'reduce the performance for shorter transform lengths'
    1448            0 :    ABI_ERROR("Aborting now")
    1449              :  end if
    1450              : 
    1451              :  ! Effective m1 and m2 (complex-to-complex or real-to-complex)
    1452          223 :  n1eff=n1; m2ieff=m2i; m2oeff=m2o; m1zt=n1
    1453          223 :  if (icplexwf==1) then
    1454           15 :    n1eff=(n1+1)/2; m2ieff=m2i/2+1; m2oeff=m2o/2+1; m1zt=2*(n1/2+1)
    1455              :  end if
    1456              : 
    1457          223 :  m2eff=max(m2ieff,m2oeff)
    1458          223 :  lzt=m2eff
    1459          223 :  if (mod(m2eff,2) == 0) lzt=lzt+1
    1460           39 :  if (mod(m2eff,4) == 0) lzt=lzt+1
    1461              : 
    1462              :  ! maximal number of big box 3rd dim slices for all procs
    1463          223 :  nnd3=nd3proc*nproc_fft
    1464              : 
    1465          669 :  ABI_MALLOC(btrig1,(2,n1))
    1466          446 :  ABI_MALLOC(ftrig1,(2,n1))
    1467          223 :  ABI_MALLOC(after1,(mdata))
    1468          223 :  ABI_MALLOC(now1,(mdata))
    1469          223 :  ABI_MALLOC(before1,(mdata))
    1470          669 :  ABI_MALLOC(btrig2,(2,n2))
    1471          446 :  ABI_MALLOC(ftrig2,(2,n2))
    1472          223 :  ABI_MALLOC(after2,(mdata))
    1473          223 :  ABI_MALLOC(now2,(mdata))
    1474          223 :  ABI_MALLOC(before2,(mdata))
    1475          669 :  ABI_MALLOC(btrig3,(2,n3))
    1476          446 :  ABI_MALLOC(ftrig3,(2,n3))
    1477          223 :  ABI_MALLOC(after3,(mdata))
    1478          223 :  ABI_MALLOC(now3,(mdata))
    1479          223 :  ABI_MALLOC(before3,(mdata))
    1480              : 
    1481          892 :  ABI_MALLOC(zw,(2,ncache/4,2))
    1482          892 :  ABI_MALLOC(zt,(2,lzt,m1zt))
    1483         1115 :  ABI_MALLOC(zmpi2,(2,md1,md2proc,nnd3))
    1484          223 :  if (nproc_fft > 1)  then
    1485            0 :    ABI_MALLOC(zmpi1,(2,md1,md2proc,nnd3))
    1486              :  end if
    1487              : 
    1488          223 :  call ctrig(n3,btrig3,after3,before3,now3,1,ic3)
    1489          223 :  call ctrig(n1,btrig1,after1,before1,now1,1,ic1)
    1490          223 :  call ctrig(n2,btrig2,after2,before2,now2,1,ic2)
    1491              : 
    1492        13345 :  do j=1,n1
    1493        13122 :    ftrig1(1,j)= btrig1(1,j)
    1494        13345 :    ftrig1(2,j)=-btrig1(2,j)
    1495              :  end do
    1496        14701 :  do j=1,n2
    1497        14478 :    ftrig2(1,j)= btrig2(1,j)
    1498        14701 :    ftrig2(2,j)=-btrig2(2,j)
    1499              :  end do
    1500        10569 :  do j=1,n3
    1501        10346 :    ftrig3(1,j)= btrig3(1,j)
    1502        10569 :    ftrig3(2,j)=-btrig3(2,j)
    1503              :  end do
    1504              : 
    1505          446 :  do idat=1,ndat
    1506              :    !
    1507              :    ! transform along z axis
    1508              :    ! input: G1,G3,G2,(Gp2)
    1509          223 :    lot=ncache/(4*n3)
    1510         6924 :    do j2=1,md2proc
    1511         6924 :      if (me_fft*md2proc+j2 <= m2ieff) then
    1512        20118 :        do i1=1,m1i,lot
    1513        13642 :          ma=i1
    1514        13642 :          mb=min(i1+(lot-1),m1i)
    1515        13642 :          n1dfft=mb-ma+1
    1516              : 
    1517              :          ! zero-pad n1dfft G_z lines
    1518              :          ! input: G1,G3,G2,(Gp2)
    1519        13642 :          call fill_cent(md1,md3,lot,n1dfft,max3i,m3i,n3,zf(1,i1,1,j2,idat),zw(1,1,1))
    1520              : 
    1521        13642 :          inzee=1
    1522        54287 :          do i=1,ic3
    1523              :            call fftstp(lot,n1dfft,n3,lot,n3,zw(1,1,inzee),zw(1,1,3-inzee), &
    1524        40645 : &                      btrig3,after3(i),now3(i),before3(i),1)
    1525        54287 :            inzee=3-inzee
    1526              :          end do
    1527              : 
    1528              :          ! Local rotation.
    1529              :          ! input:  G1,R3,G2,(Gp2)
    1530              :          ! output: G1,G2,R3,(Gp2)
    1531        20118 :          call scramble(i1,j2,lot,n1dfft,md1,n3,md2proc,nnd3,zw(1,1,inzee),zmpi2)
    1532              :        end do
    1533              :      end if
    1534              :    end do
    1535              : 
    1536              :    ! Interprocessor data transposition
    1537              :    ! input:  G1,G2,R3,Rp3,(Gp2)
    1538              :    ! output: G1,G2,R3,Gp2,(Rp3)
    1539          223 :    if (nproc_fft > 1) then
    1540            0 :       call timab(543,1,tsec)
    1541              :       call xmpi_alltoall(zmpi2,2*md1*md2proc*nd3proc,&
    1542            0 : &                        zmpi1,2*md1*md2proc*nd3proc,comm_fft,ierr)
    1543            0 :       call timab(543,2,tsec)
    1544              :    end if
    1545              : 
    1546        10569 :    do j3=1,nd3proc
    1547        10346 :      j3glob = j3 + me_fft*nd3proc
    1548              : 
    1549        10569 :      if (me_fft*nd3proc+j3 <= n3) then
    1550        10346 :        Jp2stb=1; J2stb=1
    1551        10346 :        Jp2stf=1; J2stf=1
    1552              : 
    1553              :        ! transform along x axis
    1554        10346 :        lot=ncache/(4*n1)
    1555              : 
    1556        39516 :        do j=1,m2ieff,lot
    1557        29170 :          ma=j
    1558        29170 :          mb=min(j+(lot-1),m2ieff)
    1559        29170 :          n1dfft=mb-ma+1
    1560              : 
    1561              :          ! Zero-pad input.
    1562              :          ! input:  G1,G2,R3,G2,(Rp3)
    1563              :          ! output: G2,G1,R3,G2,(Rp3)
    1564        29170 :          if (nproc_fft == 1) then
    1565              :            call mpiswitch_cent(j3,n1dfft,Jp2stb,J2stb,lot,max1i,md1,m1i,n1,&
    1566        29170 : &           md2proc,nd3proc,nproc_fft,ioption,zmpi2,zw(1,1,1), unused0, unused0, unused0)
    1567              :          else
    1568              :            call mpiswitch_cent(j3,n1dfft,Jp2stb,J2stb,lot,max1i,md1,m1i,n1,&
    1569            0 : &           md2proc,nd3proc,nproc_fft,ioption,zmpi1,zw(1,1,1), unused0, unused0, unused0)
    1570              :          end if
    1571              : 
    1572              :          ! Transform along x
    1573              :          ! input:  G2,G1,R3,(Rp3)
    1574              :          ! output: G2,R1,R3,(Rp3)
    1575        29170 :          inzee=1
    1576        86808 :          do i=1,ic1-1
    1577              :            call fftstp(lot,n1dfft,n1,lot,n1,zw(1,1,inzee),zw(1,1,3-inzee), &
    1578        57638 : &                     btrig1,after1(i),now1(i),before1(i),1)
    1579        86808 :            inzee=3-inzee
    1580              :          end do
    1581              : 
    1582        29170 :          i=ic1
    1583              :          call fftstp(lot,n1dfft,n1,lzt,m1zt,zw(1,1,inzee),zt(1,j,1), &
    1584        39516 : &                    btrig1,after1(i),now1(i),before1(i),1)
    1585              :        end do
    1586              : 
    1587              :        ! Transform along y axis (take into account c2c or c2r case).
    1588              :        ! Must loop over the full box.
    1589        10346 :        lot=ncache/(4*n2)
    1590              : 
    1591        10346 :        if (icplexwf==1) then
    1592         1026 :          if(mod(lot,2).ne.0)lot=lot-1 ! needed to introduce jeff
    1593              :        end if
    1594              : 
    1595        71068 :        do j=1,n1eff,lot
    1596        60722 :          ma=j
    1597        60722 :          mb=min(j+(lot-1),n1eff)
    1598        60722 :          n1dfft=mb-ma+1
    1599        60722 :          jeff=j
    1600        60722 :          includelast=1
    1601              : 
    1602        60722 :          if (icplexwf==1) then
    1603         3826 :            jeff=2*j-1
    1604              :            includelast=1
    1605         3826 :            if (mb==n1eff .and. n1eff*2/=n1) includelast=0
    1606              :          end if
    1607              : 
    1608              :          ! Zero-pad the input.
    1609              :          !  input: G2,R1,R3,(Rp3)
    1610              :          ! output: R1,G2,R3,(Rp3)
    1611        60722 :          if (icplexwf==2) then
    1612        56896 :            call switch_cent(n1dfft,max2i,m2i,n2,lot,n1,lzt,zt(1,1,jeff),zw(1,1,1))
    1613              :          else
    1614         3826 :            call switchreal_cent(includelast,n1dfft,max2i,n2,lot,m1zt,lzt,zt(1,1,jeff),zw(1,1,1))
    1615              :          end if
    1616              : 
    1617              :          ! input:  R1,G2,R3,(Rp3)
    1618              :          ! output: R1,R2,R3,(Rp3)
    1619        60722 :          inzee=1
    1620       242186 :          do i=1,ic2
    1621              :            call fftstp(lot,n1dfft,n2,lot,n2,zw(1,1,inzee),zw(1,1,3-inzee), &
    1622       181464 : &                       btrig2,after2(i),now2(i),before2(i),1)
    1623       242186 :             inzee=3-inzee
    1624              :          end do
    1625              :          ! output: R1,R2,R3,(Rp3)
    1626              : 
    1627              :          ! Multiply with potential in real space
    1628        60722 :          jx=cplex*(jeff-1)+1
    1629        60722 :          call multpot(icplexwf,cplex,includelast,nd1,nd2,n2,lot,n1dfft,pot(jx,1,j3glob),zw(1,1,inzee))
    1630              : 
    1631              :          ! TRANSFORM BACK IN FOURIER SPACE
    1632              :          ! transform along y axis
    1633              :          ! input: R1,R2,R3,(Rp3)
    1634       242186 :          do i=1,ic2
    1635              :            call fftstp(lot,n1dfft,n2,lot,n2,zw(1,1,inzee),zw(1,1,3-inzee), &
    1636       181464 : &                       ftrig2,after2(i),now2(i),before2(i),-1)
    1637       242186 :            inzee=3-inzee
    1638              :          end do
    1639              : 
    1640              :          !  input: R1,G2,R3,(Rp3)
    1641              :          ! output: G2,R1,R3,(Rp3)
    1642        71068 :          if (icplexwf==2) then
    1643        56896 :            call unswitch_cent(n1dfft,max2o,m2o,n2,lot,n1,lzt,zw(1,1,inzee),zt(1,1,jeff))
    1644              :          else
    1645         3826 :            call unswitchreal_cent(n1dfft,max2o,n2,lot,n1,lzt,zw(1,1,inzee),zt(1,1,jeff))
    1646              :          end if
    1647              : 
    1648              :        end do ! j
    1649              : 
    1650              :        ! transform along x axis
    1651              :        ! input:  R2,R1,R3,(Rp3)
    1652              :        ! output: R2,G1,R3,(Rp3)
    1653        10346 :        lot=ncache/(4*n1)
    1654              : 
    1655        39516 :        do j=1,m2oeff,lot
    1656        29170 :          ma=j
    1657        29170 :          mb=min(j+(lot-1),m2oeff)
    1658        29170 :          n1dfft=mb-ma+1
    1659        29170 :          i=1
    1660              :          call fftstp(lzt,n1dfft,m1zt,lot,n1,zt(1,j,1),zw(1,1,1), &
    1661        29170 : &                    ftrig1,after1(i),now1(i),before1(i),-1)
    1662              : 
    1663        29170 :          inzee=1
    1664        86808 :          do i=2,ic1
    1665              :            call fftstp(lot,n1dfft,n1,lot,n1,zw(1,1,inzee),zw(1,1,3-inzee), &
    1666        57638 : &                       ftrig1,after1(i),now1(i),before1(i),-1)
    1667        86808 :            inzee=3-inzee
    1668              :          end do
    1669              : 
    1670              :          ! input:  G2,G1,R3,Gp2,(Rp3)
    1671              :          ! output: G1,G2,R3,Gp2,(Rp3)
    1672        39516 :          if (nproc_fft == 1) then
    1673              :            call unmpiswitch_cent(j3,n1dfft,Jp2stf,J2stf,lot,max1o,md1,m1o,n1,&
    1674        29170 : &           md2proc,nd3proc,nproc_fft,ioption,zw(1,1,inzee),zmpi2)
    1675              :          else
    1676              :            call unmpiswitch_cent(j3,n1dfft,Jp2stf,J2stf,lot,max1o,md1,m1o,n1,&
    1677            0 : &           md2proc,nd3proc,nproc_fft,ioption,zw(1,1,inzee),zmpi1)
    1678              :          end if
    1679              :        end do ! j
    1680              :      end if
    1681              :    end do
    1682              : 
    1683              :    ! Interprocessor data transposition
    1684              :    ! input:  G1,G2,R3,Gp2,(Rp3)
    1685              :    ! output: G1,G2,R3,Rp3,(Gp2)
    1686          223 :    if (nproc_fft > 1) then
    1687            0 :      call timab(544,1,tsec)
    1688              :      call xmpi_alltoall(zmpi1,2*md1*md2proc*nd3proc, &
    1689            0 : &                       zmpi2,2*md1*md2proc*nd3proc,comm_fft,ierr)
    1690            0 :      call timab(544,2,tsec)
    1691              :    end if
    1692              : 
    1693              :    ! transform along z axis
    1694              :    ! input: G1,G2,R3,(Gp2)
    1695          223 :    lot=ncache/(4*n3)
    1696         6924 :    do j2=1,md2proc
    1697         6924 :      if (me_fft*md2proc+j2 <= m2oeff) then
    1698        20118 :        do i1=1,m1o,lot
    1699        13642 :          ma=i1
    1700        13642 :          mb=min(i1+(lot-1),m1o)
    1701        13642 :          n1dfft=mb-ma+1
    1702              : 
    1703              :          ! input:  G1,G2,R3,(Gp2)
    1704              :          ! output: G1,R3,G2,(Gp2)
    1705        13642 :          call unscramble(i1,j2,lot,n1dfft,md1,n3,md2proc,nnd3,zmpi2,zw(1,1,1))
    1706              : 
    1707        13642 :          inzee=1
    1708        54287 :          do i=1,ic3
    1709              :            call fftstp(lot,n1dfft,n3,lot,n3,zw(1,1,inzee),zw(1,1,3-inzee), &
    1710        40645 : &           ftrig3,after3(i),now3(i),before3(i),-1)
    1711        54287 :            inzee=3-inzee
    1712              :          end do
    1713              : 
    1714        20118 :          call unfill_cent(md1,md3,lot,n1dfft,max3o,m3o,n3,zw(1,1,inzee),zf(1,i1,1,j2,idat))
    1715              :          ! output: G1,G3,G2,(Gp2)
    1716              :        end do
    1717              :      end if
    1718              :    end do
    1719              : 
    1720              :    ! Complete missing values with complex conjugate
    1721              :    ! Inverse of ix is located at nx+2-ix , except for ix=1, for which it is 1.
    1722          446 :    if (icplexwf==1) then
    1723          514 :      do i3=1,m3o
    1724          499 :        i3inv=m3o+2-i3
    1725          499 :        if (i3==1) i3inv=1
    1726          514 :        if (m2oeff>1)then
    1727         9794 :          do i2=2,m2oeff
    1728         9295 :            i2inv=m2o+2-i2
    1729         9295 :            zf(1,1,i3inv,i2inv,idat)= zf(1,1,i3,i2,idat)
    1730         9295 :            zf(2,1,i3inv,i2inv,idat)=-zf(2,1,i3,i2,idat)
    1731       407604 :            do i1=2,m1o
    1732       397810 :              i1inv=m1o+2-i1
    1733       397810 :              zf(1,i1inv,i3inv,i2inv,idat)= zf(1,i1,i3,i2,idat)
    1734       407105 :              zf(2,i1inv,i3inv,i2inv,idat)=-zf(2,i1,i3,i2,idat)
    1735              :            end do
    1736              :          end do
    1737              :        end if
    1738              :      end do
    1739              :    end if
    1740              : 
    1741              :  end do ! idat
    1742              : 
    1743          223 :  ABI_FREE(btrig1)
    1744          223 :  ABI_FREE(ftrig1)
    1745          223 :  ABI_FREE(after1)
    1746          223 :  ABI_FREE(now1)
    1747          223 :  ABI_FREE(before1)
    1748          223 :  ABI_FREE(btrig2)
    1749          223 :  ABI_FREE(ftrig2)
    1750          223 :  ABI_FREE(after2)
    1751          223 :  ABI_FREE(now2)
    1752          223 :  ABI_FREE(before2)
    1753          223 :  ABI_FREE(btrig3)
    1754          223 :  ABI_FREE(ftrig3)
    1755          223 :  ABI_FREE(after3)
    1756          223 :  ABI_FREE(now3)
    1757          223 :  ABI_FREE(before3)
    1758              : 
    1759          223 :  ABI_FREE(zmpi2)
    1760          223 :  ABI_FREE(zw)
    1761          223 :  ABI_FREE(zt)
    1762          223 :  if (nproc_fft > 1)  then
    1763            0 :    ABI_FREE(zmpi1)
    1764              :  end if
    1765              : 
    1766          223 : end subroutine sg2002_applypot
    1767              : !!***
    1768              : 
    1769              : !----------------------------------------------------------------------
    1770              : 
    1771              : !!****f* m_sg2002/sg2002_applypot_many
    1772              : !! NAME
    1773              : !!  sg2002_applypot_many
    1774              : !!
    1775              : !! FUNCTION
    1776              : !! Applies the local real space potential to multiple wavefunctions in Fourier space
    1777              : !!
    1778              : !! INPUTS
    1779              : !!   ZF: Wavefunction (input/output) (note the switch of i2 and i3)
    1780              : !!        real(F(i1,i3,i2,idat))=ZF(1,i1,i3,i2,idat)
    1781              : !!        imag(F(i1,i3,i2,idat))=ZF(2,i1,i3,i2,idat)
    1782              : !!   max1 is positive or zero ; m1 >=max1+1
    1783              : !!   i1= 1... max1+1 corresponds to positive and zero wavevectors 0 ... max1
    1784              : !!   then, if m1 > max1+1, one has min1=max1-m1+1 and
    1785              : !!   i1= max1+2 ... m1 corresponds to negative wavevectors min1 ... -1
    1786              : !!   i2 and i3 have a similar definition of range
    1787              : !!   idat=1,ndat
    1788              : !!   md1,md2,md3: Dimension of ZF (input as well as output), distributed on different procs
    1789              : !!   md2proc=((md2-1)/nproc_fft)+1  maximal number of small box 2nd dim slices for one proc
    1790              : !!
    1791              : !!   POT: Potential
    1792              : !!        POT(cplex*i1,i2,i3)
    1793              : !!        cplex=1 or 2 ,  i1=1,n1 , i2=1,n2 , i3=1,n3
    1794              : !!   nd1,nd2,nd3: dimension of pot
    1795              : !!   comm_fft: MPI communicator
    1796              : !!   nproc_fft: number of processors used as returned by MPI_COMM_SIZE
    1797              : !!   me_fft: [0:nproc_fft-1] number of processor as returned by MPI_COMM_RANK
    1798              : !!    n1,n2,n3: logical dimension of the transform. As transform lengths
    1799              : !!              most products of the prime factors 2,3,5 are allowed.
    1800              : !!             The detailed table with allowed transform lengths can
    1801              : !!             be found in subroutine CTRIG
    1802              : !!
    1803              : !! NOTES:
    1804              : !!   PERFORMANCE CONSIDERATIONS:
    1805              : !!   The maximum number of processors that can reasonably be used is max(n2/2,n3/2)
    1806              : !!
    1807              : !!   It is very important to find the optimal
    1808              : !!   value of NCACHE. NCACHE determines the size of the work array ZW, that
    1809              : !!   has to fit into cache. It has therefore to be chosen to equal roughly
    1810              : !!    half the size of the physical cache in units of real*8 numbers.
    1811              : !!   The optimal value of ncache can easily be determined by numerical
    1812              : !!   experimentation. A too large value of ncache leads to a dramatic
    1813              : !!   and sudden decrease of performance, a too small value to a to a
    1814              : !!   slow and less dramatic decrease of performance. If NCACHE is set
    1815              : !!   to a value so small, that not even a single one dimensional transform
    1816              : !!   can be done in the workarray zw, the program stops with an error message.
    1817              : !!
    1818              : !! SOURCE
    1819              : 
    1820              : 
    1821          680 : subroutine sg2002_applypot_many(icplexwf,cplex,ndat,n1,n2,n3,nd1,nd2,nd3,nd3proc,&
    1822              : &  max1i,max2i,max3i,m1i,m2i,m3i,md1,md2proc,md3,&
    1823          680 : &  max1o,max2o,max3o,m1o,m2o,m3o,comm_fft,nproc_fft,me_fft,pot,zf)
    1824              : 
    1825              : !Arguments ------------------------------------
    1826              :  integer,intent(in) :: icplexwf,cplex,ndat,n1,n2,n3,nd1,nd2,nd3,nd3proc
    1827              :  integer,intent(in) :: max1i,max2i,max3i,m1i,m2i,m3i,md1,md2proc,md3
    1828              :  integer,intent(in) :: max1o,max2o,max3o,m1o,m2o,m3o,comm_fft,nproc_fft,me_fft
    1829              :  real(dp),intent(in) :: pot(cplex*nd1,nd2,nd3)
    1830              :  real(dp),intent(inout) :: zf(2,md1,md3,md2proc,ndat)
    1831              : 
    1832              : !Local variables-------------------------------
    1833              : !scalars
    1834              :  integer,parameter :: unused0=0
    1835              :  integer :: i,j,i1,i2,i3,ic1,ic2,ic3,idat,ierr,inzee,j3glob
    1836              :  integer :: ioption,j2,j3,lot,lzt,m1zt,ma,mb,n1dfft,nnd3
    1837              :  integer :: m2eff,ncache,n1eff,i1inv,i2inv,i3inv,jeff,includelast,j2stb
    1838              :  integer :: jx,j2stf,Jp2stb,Jp2stf,m2ieff,m2oeff
    1839              : !arrays
    1840         1360 :  integer :: requests(ndat)
    1841              :  real(dp) :: tsec(2)
    1842          680 :  real(dp), allocatable :: zt(:,:,:) ! work arrays for transpositions
    1843          680 :  real(dp), allocatable :: zmpi1(:,:,:,:,:),zmpi2(:,:,:,:,:) ! work arrays for MPI
    1844          680 :  real(dp), allocatable :: zw(:,:,:) ! cache work array
    1845              : ! FFT work arrays
    1846          680 :  real(dp), allocatable, dimension(:,:) :: btrig1,btrig2,btrig3
    1847          680 :  real(dp), allocatable, dimension(:,:) :: ftrig1,ftrig2,ftrig3
    1848          680 :  integer, allocatable, dimension(:) :: after1,now1,before1,after2,now2,before2,after3,now3,before3
    1849              : 
    1850              : ! *************************************************************************
    1851              : 
    1852              :  !ioption=0 ! This was in the old version.
    1853          680 :  ioption=1 ! This one is needed to be compatible with paral_kgb
    1854              : 
    1855              :  ! call timab(541,1,tsec)
    1856          680 :  ncache=4*max(n1,n2,n3,1024)
    1857          680 :  if (ncache/(4*max(n1,n2,n3)) < 1) then
    1858              :    write(std_out,*) &
    1859            0 : &    'ncache has to be enlarged to be able to hold at', &
    1860            0 : &    'least one 1-d FFT of each size even though this will', &
    1861            0 : &    'reduce the performance for shorter transform lengths'
    1862            0 :    ABI_ERROR("Aborting now")
    1863              :  end if
    1864              : 
    1865              :  ! Effective m1 and m2 (complex-to-complex or real-to-complex)
    1866          680 :  n1eff=n1; m2ieff=m2i; m2oeff=m2o; m1zt=n1
    1867          680 :  if (icplexwf==1) then
    1868            0 :    n1eff=(n1+1)/2; m2ieff=m2i/2+1; m2oeff=m2o/2+1; m1zt=2*(n1/2+1)
    1869              :  end if
    1870              : 
    1871          680 :  m2eff=max(m2ieff,m2oeff)
    1872          680 :  lzt=m2eff
    1873          680 :  if (mod(m2eff,2) == 0) lzt=lzt+1
    1874          336 :  if (mod(m2eff,4) == 0) lzt=lzt+1
    1875              : 
    1876              :  ! maximal number of big box 3rd dim slices for all procs
    1877          680 :  nnd3=nd3proc*nproc_fft
    1878              : 
    1879         2040 :  ABI_MALLOC(btrig1,(2,n1))
    1880         1360 :  ABI_MALLOC(ftrig1,(2,n1))
    1881          680 :  ABI_MALLOC(after1,(mdata))
    1882          680 :  ABI_MALLOC(now1,(mdata))
    1883          680 :  ABI_MALLOC(before1,(mdata))
    1884         2040 :  ABI_MALLOC(btrig2,(2,n2))
    1885         1360 :  ABI_MALLOC(ftrig2,(2,n2))
    1886          680 :  ABI_MALLOC(after2,(mdata))
    1887          680 :  ABI_MALLOC(now2,(mdata))
    1888          680 :  ABI_MALLOC(before2,(mdata))
    1889         2040 :  ABI_MALLOC(btrig3,(2,n3))
    1890         1360 :  ABI_MALLOC(ftrig3,(2,n3))
    1891          680 :  ABI_MALLOC(after3,(mdata))
    1892          680 :  ABI_MALLOC(now3,(mdata))
    1893          680 :  ABI_MALLOC(before3,(mdata))
    1894              : 
    1895         2720 :  ABI_MALLOC(zw,(2,ncache/4,2))
    1896         2720 :  ABI_MALLOC(zt,(2,lzt,m1zt))
    1897         4080 :  ABI_MALLOC(zmpi2,(2,md1,md2proc,nnd3,ndat))
    1898          680 :  if (nproc_fft > 1)  then
    1899         1680 :    ABI_MALLOC(zmpi1,(2,md1,md2proc,nnd3,ndat))
    1900              :  end if
    1901              : 
    1902          680 :  call ctrig(n3,btrig3,after3,before3,now3,1,ic3)
    1903          680 :  call ctrig(n1,btrig1,after1,before1,now1,1,ic1)
    1904          680 :  call ctrig(n2,btrig2,after2,before2,now2,1,ic2)
    1905              : 
    1906        13656 :  do j=1,n1
    1907        12976 :    ftrig1(1,j)= btrig1(1,j)
    1908        13656 :    ftrig1(2,j)=-btrig1(2,j)
    1909              :  end do
    1910        13656 :  do j=1,n2
    1911        12976 :    ftrig2(1,j)= btrig2(1,j)
    1912        13656 :    ftrig2(2,j)=-btrig2(2,j)
    1913              :  end do
    1914        13656 :  do j=1,n3
    1915        12976 :    ftrig3(1,j)= btrig3(1,j)
    1916        13656 :    ftrig3(2,j)=-btrig3(2,j)
    1917              :  end do
    1918              : 
    1919              :  ! Here we take advantage of non-blocking IALLTOALL:
    1920              :  ! Perform the first step of MPI-FFT for ndat wavefunctions.
    1921         3732 :  do idat=1,ndat
    1922              : 
    1923              :    !
    1924              :    ! transform along z axis
    1925              :    ! input: G1,G3,G2,(Gp2)
    1926         3052 :    lot=ncache/(4*n3)
    1927        23672 :    do j2=1,md2proc
    1928        23672 :      if (me_fft*md2proc+j2 <= m2ieff) then
    1929        49164 :        do i1=1,m1i,lot
    1930        28544 :          ma=i1
    1931        28544 :          mb=min(i1+(lot-1),m1i)
    1932        28544 :          n1dfft=mb-ma+1
    1933              : 
    1934              :          ! zero-pad n1dfft G_z lines
    1935              :          ! input: G1,G3,G2,(Gp2)
    1936        28544 :          call fill_cent(md1,md3,lot,n1dfft,max3i,m3i,n3,zf(1,i1,1,j2,idat),zw(1,1,1))
    1937              : 
    1938        28544 :          inzee=1
    1939        95024 :          do i=1,ic3
    1940              :            call fftstp(lot,n1dfft,n3,lot,n3,zw(1,1,inzee),zw(1,1,3-inzee), &
    1941        66480 : &                      btrig3,after3(i),now3(i),before3(i),1)
    1942        95024 :            inzee=3-inzee
    1943              :          end do
    1944              : 
    1945              :          ! Local rotation.
    1946              :          ! input:  G1,R3,G2,(Gp2)
    1947              :          ! output: G1,G2,R3,(Gp2)
    1948        49164 :          call scramble(i1,j2,lot,n1dfft,md1,n3,md2proc,nnd3,zw(1,1,inzee),zmpi2(:,:,:,:,idat))
    1949              :        end do
    1950              :      end if
    1951              :    end do
    1952              : 
    1953              :    ! Interprocessor data transposition
    1954              :    ! input:  G1,G2,R3,Rp3,(Gp2)
    1955              :    ! output: G1,G2,R3,Gp2,(Rp3)
    1956         3732 :    if (nproc_fft > 1) then
    1957         2016 :       call timab(543,1,tsec)
    1958              :       call xmpi_ialltoall(zmpi2(:,:,:,:,idat),2*md1*md2proc*nd3proc,&
    1959         2016 : &                         zmpi1(:,:,:,:,idat),2*md1*md2proc*nd3proc,comm_fft,requests(idat))
    1960         2016 :       call timab(543,2,tsec)
    1961              :    end if
    1962              :  end do ! idat
    1963              : 
    1964              :  ! The second step of MPI-FFT
    1965         3732 :  do idat=1,ndat
    1966              :     ! Make sure communication is completed.
    1967         3052 :     if (nproc_fft>1) call xmpi_wait(requests(idat),ierr)
    1968              : 
    1969        42380 :    do j3=1,nd3proc
    1970        39328 :      j3glob = j3 + me_fft*nd3proc
    1971              : 
    1972        42380 :      if (me_fft*nd3proc+j3 <= n3) then
    1973        39328 :        Jp2stb=1; J2stb=1
    1974        39328 :        Jp2stf=1; J2stf=1
    1975              : 
    1976              :        ! transform along x axis
    1977        39328 :        lot=ncache/(4*n1)
    1978              : 
    1979        95136 :        do j=1,m2ieff,lot
    1980        55808 :          ma=j
    1981        55808 :          mb=min(j+(lot-1),m2ieff)
    1982        55808 :          n1dfft=mb-ma+1
    1983              : 
    1984              :          ! Zero-pad input.
    1985              :          ! input:  G1,G2,R3,G2,(Rp3)
    1986              :          ! output: G2,G1,R3,G2,(Rp3)
    1987        55808 :          if (nproc_fft == 1) then
    1988              :            call mpiswitch_cent(j3,n1dfft,Jp2stb,J2stb,lot,max1i,md1,m1i,n1,&
    1989        37664 : &           md2proc,nd3proc,nproc_fft,ioption,zmpi2(:,:,:,:,idat),zw(1,1,1), unused0, unused0, unused0)
    1990              :          else
    1991              :            call mpiswitch_cent(j3,n1dfft,Jp2stb,J2stb,lot,max1i,md1,m1i,n1,&
    1992        18144 : &           md2proc,nd3proc,nproc_fft,ioption,zmpi1(:,:,:,:,idat),zw(1,1,1), unused0, unused0, unused0)
    1993              :          end if
    1994              : 
    1995              :          ! Transform along x
    1996              :          ! input:  G2,G1,R3,(Rp3)
    1997              :          ! output: G2,R1,R3,(Rp3)
    1998        55808 :          inzee=1
    1999       131136 :          do i=1,ic1-1
    2000              :            call fftstp(lot,n1dfft,n1,lot,n1,zw(1,1,inzee),zw(1,1,3-inzee), &
    2001        75328 : &                     btrig1,after1(i),now1(i),before1(i),1)
    2002       131136 :            inzee=3-inzee
    2003              :          end do
    2004              : 
    2005        55808 :          i=ic1
    2006              :          call fftstp(lot,n1dfft,n1,lzt,m1zt,zw(1,1,inzee),zt(1,j,1), &
    2007        95136 : &                    btrig1,after1(i),now1(i),before1(i),1)
    2008              :        end do
    2009              : 
    2010              :        ! Transform along y axis (take into account c2c or c2r case).
    2011              :        ! Must loop over the full box.
    2012        39328 :        lot=ncache/(4*n2)
    2013              : 
    2014        39328 :        if (icplexwf==1) then
    2015            0 :          if(mod(lot,2).ne.0)lot=lot-1 ! needed to introduce jeff
    2016              :        end if
    2017              : 
    2018       113216 :        do j=1,n1eff,lot
    2019        73888 :          ma=j
    2020        73888 :          mb=min(j+(lot-1),n1eff)
    2021        73888 :          n1dfft=mb-ma+1
    2022        73888 :          jeff=j
    2023        73888 :          includelast=1
    2024              : 
    2025        73888 :          if (icplexwf==1) then
    2026            0 :            jeff=2*j-1
    2027              :            includelast=1
    2028            0 :            if (mb==n1eff .and. n1eff*2/=n1) includelast=0
    2029              :          end if
    2030              : 
    2031              :          ! Zero-pad the input.
    2032              :          !  input: G2,R1,R3,(Rp3)
    2033              :          ! output: R1,G2,R3,(Rp3)
    2034        73888 :          if (icplexwf==2) then
    2035        73888 :            call switch_cent(n1dfft,max2i,m2i,n2,lot,n1,lzt,zt(1,1,jeff),zw(1,1,1))
    2036              :          else
    2037            0 :            call switchreal_cent(includelast,n1dfft,max2i,n2,lot,m1zt,lzt,zt(1,1,jeff),zw(1,1,1))
    2038              :          end if
    2039              : 
    2040              :          ! input:  R1,G2,R3,(Rp3)
    2041              :          ! output: R1,R2,R3,(Rp3)
    2042        73888 :          inzee=1
    2043       259264 :          do i=1,ic2
    2044              :            call fftstp(lot,n1dfft,n2,lot,n2,zw(1,1,inzee),zw(1,1,3-inzee), &
    2045       185376 : &                       btrig2,after2(i),now2(i),before2(i),1)
    2046       259264 :             inzee=3-inzee
    2047              :          end do
    2048              :          ! output: R1,R2,R3,(Rp3)
    2049              : 
    2050              :          ! Multiply with potential in real space
    2051        73888 :          jx=cplex*(jeff-1)+1
    2052        73888 :          call multpot(icplexwf,cplex,includelast,nd1,nd2,n2,lot,n1dfft,pot(jx,1,j3glob),zw(1,1,inzee))
    2053              : 
    2054              :          ! TRANSFORM BACK IN FOURIER SPACE
    2055              :          ! transform along y axis
    2056              :          ! input: R1,R2,R3,(Rp3)
    2057       259264 :          do i=1,ic2
    2058              :            call fftstp(lot,n1dfft,n2,lot,n2,zw(1,1,inzee),zw(1,1,3-inzee), &
    2059       185376 : &                       ftrig2,after2(i),now2(i),before2(i),-1)
    2060       259264 :            inzee=3-inzee
    2061              :          end do
    2062              : 
    2063              :          !  input: R1,G2,R3,(Rp3)
    2064              :          ! output: G2,R1,R3,(Rp3)
    2065       113216 :          if (icplexwf==2) then
    2066        73888 :            call unswitch_cent(n1dfft,max2o,m2o,n2,lot,n1,lzt,zw(1,1,inzee),zt(1,1,jeff))
    2067              :          else
    2068            0 :            call unswitchreal_cent(n1dfft,max2o,n2,lot,n1,lzt,zw(1,1,inzee),zt(1,1,jeff))
    2069              :          end if
    2070              : 
    2071              :        end do ! j
    2072              : 
    2073              :        ! transform along x axis
    2074              :        ! input:  R2,R1,R3,(Rp3)
    2075              :        ! output: R2,G1,R3,(Rp3)
    2076        39328 :        lot=ncache/(4*n1)
    2077              : 
    2078        95136 :        do j=1,m2oeff,lot
    2079        55808 :          ma=j
    2080        55808 :          mb=min(j+(lot-1),m2oeff)
    2081        55808 :          n1dfft=mb-ma+1
    2082        55808 :          i=1
    2083              :          call fftstp(lzt,n1dfft,m1zt,lot,n1,zt(1,j,1),zw(1,1,1), &
    2084        55808 : &                    ftrig1,after1(i),now1(i),before1(i),-1)
    2085              : 
    2086        55808 :          inzee=1
    2087       131136 :          do i=2,ic1
    2088              :            call fftstp(lot,n1dfft,n1,lot,n1,zw(1,1,inzee),zw(1,1,3-inzee), &
    2089        75328 : &                       ftrig1,after1(i),now1(i),before1(i),-1)
    2090       131136 :            inzee=3-inzee
    2091              :          end do
    2092              : 
    2093              :          ! input:  G2,G1,R3,Gp2,(Rp3)
    2094              :          ! output: G1,G2,R3,Gp2,(Rp3)
    2095        95136 :          if (nproc_fft == 1) then
    2096              :            call unmpiswitch_cent(j3,n1dfft,Jp2stf,J2stf,lot,max1o,md1,m1o,n1,&
    2097        37664 : &           md2proc,nd3proc,nproc_fft,ioption,zw(1,1,inzee),zmpi2(:,:,:,:,idat))
    2098              :          else
    2099              :            call unmpiswitch_cent(j3,n1dfft,Jp2stf,J2stf,lot,max1o,md1,m1o,n1,&
    2100        18144 : &           md2proc,nd3proc,nproc_fft,ioption,zw(1,1,inzee),zmpi1(:,:,:,:,idat))
    2101              :          end if
    2102              :        end do ! j
    2103              :      end if
    2104              :    end do
    2105              : 
    2106              :    ! Interprocessor data transposition
    2107              :    ! input:  G1,G2,R3,Gp2,(Rp3)
    2108              :    ! output: G1,G2,R3,Rp3,(Gp2)
    2109         3732 :    if (nproc_fft > 1) then
    2110         2016 :      call timab(544,1,tsec)
    2111              :      call xmpi_ialltoall(zmpi1(:,:,:,:,idat),2*md1*md2proc*nd3proc, &
    2112         2016 : &                        zmpi2(:,:,:,:,idat),2*md1*md2proc*nd3proc,comm_fft,requests(idat))
    2113         2016 :      call timab(544,2,tsec)
    2114              :    end if
    2115              :  end do ! idat
    2116              : 
    2117         3732 :  do idat=1,ndat
    2118         3052 :    if (nproc_fft>1) call xmpi_wait(requests(idat),ierr)
    2119              : 
    2120              :    ! transform along z axis
    2121              :    ! input: G1,G2,R3,(Gp2)
    2122         3052 :    lot=ncache/(4*n3)
    2123        23672 :    do j2=1,md2proc
    2124        23672 :      if (me_fft*md2proc+j2 <= m2oeff) then
    2125        49164 :        do i1=1,m1o,lot
    2126        28544 :          ma=i1
    2127        28544 :          mb=min(i1+(lot-1),m1o)
    2128        28544 :          n1dfft=mb-ma+1
    2129              : 
    2130              :          ! input:  G1,G2,R3,(Gp2)
    2131              :          ! output: G1,R3,G2,(Gp2)
    2132        28544 :          call unscramble(i1,j2,lot,n1dfft,md1,n3,md2proc,nnd3,zmpi2(:,:,:,:,idat),zw(1,1,1))
    2133              : 
    2134        28544 :          inzee=1
    2135        95024 :          do i=1,ic3
    2136              :            call fftstp(lot,n1dfft,n3,lot,n3,zw(1,1,inzee),zw(1,1,3-inzee), &
    2137        66480 : &           ftrig3,after3(i),now3(i),before3(i),-1)
    2138        95024 :            inzee=3-inzee
    2139              :          end do
    2140              : 
    2141        49164 :          call unfill_cent(md1,md3,lot,n1dfft,max3o,m3o,n3,zw(1,1,inzee),zf(1,i1,1,j2,idat))
    2142              :          ! output: G1,G3,G2,(Gp2)
    2143              :        end do
    2144              :      end if
    2145              :    end do
    2146              : 
    2147              :    ! Complete missing values with complex conjugate
    2148              :    ! Inverse of ix is located at nx+2-ix , except for ix=1, for which it is 1.
    2149         3732 :    if (icplexwf==1) then
    2150            0 :      do i3=1,m3o
    2151            0 :        i3inv=m3o+2-i3
    2152            0 :        if (i3==1) i3inv=1
    2153            0 :        if (m2oeff>1)then
    2154            0 :          do i2=2,m2oeff
    2155            0 :            i2inv=m2o+2-i2
    2156            0 :            zf(1,1,i3inv,i2inv,idat)= zf(1,1,i3,i2,idat)
    2157            0 :            zf(2,1,i3inv,i2inv,idat)=-zf(2,1,i3,i2,idat)
    2158            0 :            do i1=2,m1o
    2159            0 :              i1inv=m1o+2-i1
    2160            0 :              zf(1,i1inv,i3inv,i2inv,idat)= zf(1,i1,i3,i2,idat)
    2161            0 :              zf(2,i1inv,i3inv,i2inv,idat)=-zf(2,i1,i3,i2,idat)
    2162              :            end do
    2163              :          end do
    2164              :        end if
    2165              :      end do
    2166              :    end if
    2167              : 
    2168              :  end do ! idat
    2169              : 
    2170          680 :  ABI_FREE(btrig1)
    2171          680 :  ABI_FREE(ftrig1)
    2172          680 :  ABI_FREE(after1)
    2173          680 :  ABI_FREE(now1)
    2174          680 :  ABI_FREE(before1)
    2175          680 :  ABI_FREE(btrig2)
    2176          680 :  ABI_FREE(ftrig2)
    2177          680 :  ABI_FREE(after2)
    2178          680 :  ABI_FREE(now2)
    2179          680 :  ABI_FREE(before2)
    2180          680 :  ABI_FREE(btrig3)
    2181          680 :  ABI_FREE(ftrig3)
    2182          680 :  ABI_FREE(after3)
    2183          680 :  ABI_FREE(now3)
    2184          680 :  ABI_FREE(before3)
    2185              : 
    2186          680 :  ABI_FREE(zmpi2)
    2187          680 :  ABI_FREE(zw)
    2188          680 :  ABI_FREE(zt)
    2189          680 :  if (nproc_fft > 1)  then
    2190          336 :    ABI_FREE(zmpi1)
    2191              :  end if
    2192              : 
    2193          680 : end subroutine sg2002_applypot_many
    2194              : !!***
    2195              : 
    2196              : !----------------------------------------------------------------------
    2197              : 
    2198              : !!****f* m_sg2002/sg2002_accrho
    2199              : !! NAME
    2200              : !! sg2002_accrho
    2201              : !!
    2202              : !! FUNCTION
    2203              : !! Accumulates the real space density rho from the ndat wavefunctions zf
    2204              : !! by transforming zf into real space and adding all the amplitudes squared
    2205              : !!
    2206              : !! INPUTS:
    2207              : !!   ZF: input array (note the switch of i2 and i3)
    2208              : !!         real(F(i1,i3,i2,idat))=ZF(1,i1,i3,i2,idat)
    2209              : !!         imag(F(i1,i3,i2,idat))=ZF(2,i1,i3,i2,idat)
    2210              : !!   max1 is positive or zero ; m1 >=max1+1
    2211              : !!   i1= 1... max1+1 corresponds to positive and zero wavevectors 0 ... max1
    2212              : !!   then, if m1 > max1+1, one has min1=max1-m1+1 and
    2213              : !!   i1= max1+2 ... m1 corresponds to negative wavevectors min1 ... -1
    2214              : !!   i2 and i3 have a similar definition of range
    2215              : !!   idat=1,ndat
    2216              : !!   md1,md2,md3: Dimension of ZF
    2217              : !!   md2proc=((md2-1)/nproc_fft)+1 ! maximal number of small box 2nd dim slices for one proc
    2218              : !!   weight(ndat)= weight for the density accumulation
    2219              : !!
    2220              : !! OUTPUTS:
    2221              : !!    RHOoutput(i1,i2,i3) = RHOinput(i1,i2,i3) + sum on idat of (Re(FFT(ZF))**2 *weight_r + weight_i*Im(FFT(ZF))**2
    2222              : !!        i1=1,n1 , i2=1,n2 , i3=1,n3
    2223              : !!   comm_fft: MPI communicator
    2224              : !!   nproc_fft: number of processors used as returned by MPI_COMM_SIZE
    2225              : !!   me_fft: [0:nproc_fft-1] number of processor as returned by MPI_COMM_RANK
    2226              : !!    n1,n2,n3: logical dimension of the transform. As transform lengths
    2227              : !!              most products of the prime factors 2,3,5 are allowed.
    2228              : !!             The detailed table with allowed transform lengths can
    2229              : !!             be found in subroutine CTRIG
    2230              : !!    nd1,nd2,nd3: Dimension of RHO
    2231              : !!   nd3proc=((nd3-1)/nproc_fft)+1 ! maximal number of big box 3rd dim slices for one proc
    2232              : !!
    2233              : !! NOTES:
    2234              : !!   PERFORMANCE CONSIDERATIONS:
    2235              : !!   The maximum number of processors that can reasonably be used is max(n2/2,n3/2)
    2236              : !!
    2237              : !!   It is very important to find the optimal
    2238              : !!   value of NCACHE. NCACHE determines the size of the work array ZW, that
    2239              : !!   has to fit into cache. It has therefore to be chosen to equal roughly
    2240              : !!    half the size of the physical cache in units of real*8 numbers.
    2241              : !!   The optimal value of ncache can easily be determined by numerical
    2242              : !!   experimentation. A too large value of ncache leads to a dramatic
    2243              : !!   and sudden decrease of performance, a too small value to a to a
    2244              : !!   slow and less dramatic decrease of performance. If NCACHE is set
    2245              : !!   to a value so small, that not even a single one dimensional transform
    2246              : !!   can be done in the workarray zw, the program stops with an error message.
    2247              : !!
    2248              : !! SOURCE
    2249              : 
    2250          214 : subroutine sg2002_accrho(icplexwf,ndat,n1,n2,n3,nd1,nd2,nd3,nd3proc,&
    2251          214 : &  max1,max2,max3,m1,m2,m3,md1,md2proc,md3,comm_fft,nproc_fft,me_fft,zf,rho,weight_r,weight_i)
    2252              : 
    2253              : !Arguments ------------------------------------
    2254              :  integer,intent(in) :: icplexwf,ndat,n1,n2,n3,nd1,nd2,nd3,nd3proc
    2255              :  integer,intent(in) :: max1,max2,max3,m1,m2,m3,md1,md2proc,md3,comm_fft,nproc_fft,me_fft
    2256              :  real(dp),intent(in) :: zf(2,md1,md3,md2proc,ndat)
    2257              :  real(dp),intent(in) :: weight_r(ndat), weight_i(ndat)
    2258              :  real(dp),intent(inout) :: rho(nd1,nd2,nd3)
    2259              : 
    2260              : !Local variables-------------------------------
    2261              : !scalars
    2262              :  integer,parameter :: unused0=0
    2263              :  integer :: i,j,i1,ic1,ic2,ic3,idat,ierr,inzee,j3glob
    2264              :  integer :: ioption,j2,j3,j2st,jp2st,lot,lzt,m1zt,ma,mb,n1dfft,nnd3
    2265              :  integer :: m2eff,ncache,n1eff,jeff,includelast
    2266              : !arrays
    2267          214 :  real(dp), allocatable :: zmpi1(:,:,:,:),zmpi2(:,:,:,:) ! work arrays for MPI
    2268          214 :  real(dp), allocatable :: zt(:,:,:)  ! work arrays for transpositions
    2269          214 :  real(dp), allocatable :: zw(:,:,:) ! cache work array
    2270              :  real(dp) :: tsec(2)
    2271              : ! FFT work arrays
    2272          214 :  real(dp), allocatable, dimension(:,:) :: trig1,trig2,trig3
    2273          214 :  integer, allocatable, dimension(:) :: after1,now1,before1, after2,now2,before2,after3,now3,before3
    2274              : 
    2275              : ! *************************************************************************
    2276              : 
    2277              :  !ioption=0 ! This was in the old version.
    2278          214 :  ioption=1 ! This one is needed to be compatible with paral_kgb
    2279              : 
    2280              :  !nproc_fft = xmpi_comm_size(comm_fft); me_fft = xmpi_comm_rank(comm_fft)
    2281              : 
    2282              : ! find cache size that gives optimal performance on machine
    2283          214 :  ncache=4*max(n1,n2,n3,1024)
    2284          214 :  if (ncache/(4*max(n1,n2,n3)) < 1) then
    2285              :     write(std_out,*) &
    2286            0 : &     'ncache has to be enlarged to be able to hold at', &
    2287            0 : &     'least one 1-d FFT of each size even though this will', &
    2288            0 : &     'reduce the performance for shorter transform lengths'
    2289            0 :     ABI_ERROR("Aborting now")
    2290              :  end if
    2291              : 
    2292              : !Effective m1 and m2 (complex-to-complex or real-to-complex)
    2293          214 :  n1eff=n1; m2eff=m2 ; m1zt=n1
    2294          214 :  if (icplexwf==1) then
    2295           16 :    n1eff=(n1+1)/2; m2eff=m2/2+1; m1zt=2*(n1/2+1)
    2296              :  end if
    2297              : 
    2298          214 :  lzt=m2eff
    2299          214 :  if (mod(m2eff,2) == 0) lzt=lzt+1
    2300          106 :  if (mod(m2eff,4) == 0) lzt=lzt+1
    2301              : 
    2302              :  ! maximal number of big box 3rd dim slices for all procs
    2303          214 :  nnd3=nd3proc*nproc_fft
    2304              : 
    2305          642 :  ABI_MALLOC(trig1,(2,n1))
    2306          214 :  ABI_MALLOC(after1,(mdata))
    2307          214 :  ABI_MALLOC(now1,(mdata))
    2308          214 :  ABI_MALLOC(before1,(mdata))
    2309          642 :  ABI_MALLOC(trig2,(2,n2))
    2310          214 :  ABI_MALLOC(after2,(mdata))
    2311          214 :  ABI_MALLOC(now2,(mdata))
    2312          214 :  ABI_MALLOC(before2,(mdata))
    2313          642 :  ABI_MALLOC(trig3,(2,n3))
    2314          214 :  ABI_MALLOC(after3,(mdata))
    2315          214 :  ABI_MALLOC(now3,(mdata))
    2316          214 :  ABI_MALLOC(before3,(mdata))
    2317              : 
    2318          856 :  ABI_MALLOC(zw,(2,ncache/4,2))
    2319          856 :  ABI_MALLOC(zt,(2,lzt,m1zt))
    2320         1070 :  ABI_MALLOC(zmpi2,(2,md1,md2proc,nnd3))
    2321          214 :  if (nproc_fft > 1)  then
    2322          256 :    ABI_MALLOC(zmpi1,(2,md1,md2proc,nnd3))
    2323              :  end if
    2324              : 
    2325          214 :  call ctrig(n3,trig3,after3,before3,now3,1,ic3)
    2326          214 :  call ctrig(n1,trig1,after1,before1,now1,1,ic1)
    2327          214 :  call ctrig(n2,trig2,after2,before2,now2,1,ic2)
    2328              : 
    2329          438 :  do idat=1,ndat
    2330              :    ! transform along z axis
    2331              :    ! input: I1,I3,J2,(Jp2)
    2332          224 :    lot=ncache/(4*n3)
    2333              : 
    2334              :    ! Loop over the y planes treated by this node and trasform n1ddft G_z lines.
    2335         4548 :    do j2=1,md2proc
    2336         4548 :      if (me_fft*md2proc+j2 <= m2eff) then ! MG REMOVED TO BE COSISTENT WITH BACK_WF
    2337        17538 :        do i1=1,m1,lot
    2338        13444 :          ma=i1
    2339        13444 :          mb=min(i1+(lot-1),m1)
    2340        13444 :          n1dfft=mb-ma+1
    2341              : 
    2342              :          ! zero-pad n1dfft G_z lines
    2343              :          !  input: G1,G3,G2,(Gp2)
    2344              :          ! output: G1,R3,G2,(Gp2)
    2345        13444 :          call fill_cent(md1,md3,lot,n1dfft,max3,m3,n3,zf(1,i1,1,j2,idat),zw(1,1,1))
    2346              : 
    2347              :          ! Transform along z.
    2348        13444 :          inzee=1
    2349        52886 :          do i=1,ic3
    2350              :            call fftstp(lot,n1dfft,n3,lot,n3,zw(1,1,inzee),zw(1,1,3-inzee), &
    2351        39442 : &                       trig3,after3(i),now3(i),before3(i),1)
    2352        52886 :            inzee=3-inzee
    2353              :          end do
    2354              : 
    2355              :          ! Local rotation.
    2356              :          ! input:  G1,R3,G2,(Gp2)
    2357              :          ! output: G1,G2,R3,(Gp2)
    2358        17538 :          call scramble(i1,j2,lot,n1dfft,md1,n3,md2proc,nnd3,zw(1,1,inzee),zmpi2)
    2359              :        end do
    2360              :      end if
    2361              :    end do
    2362              : 
    2363              :    ! Interprocessor data transposition
    2364              :    ! input:  G1,G2,R3,Rp3,(Gp2)
    2365              :    ! output: G1,G2,R3,Gp2,(Rp3)
    2366          224 :    if (nproc_fft > 1) then
    2367           64 :      call timab(543,1,tsec)
    2368              :      call xmpi_alltoall(zmpi2,2*md1*md2proc*nd3proc, &
    2369           64 : &                       zmpi1,2*md1*md2proc*nd3proc,comm_fft,ierr)
    2370           64 :      call timab(543,2,tsec)
    2371              :    end if
    2372              : 
    2373              :    ! Loop over the z treated by this node.
    2374         9074 :    do j3=1,nd3proc
    2375         8636 :      j3glob = j3 + me_fft*nd3proc
    2376              :      !ABI_CHECK(j3glob <= n3, "j3glob")
    2377              : 
    2378         8860 :      if (me_fft*nd3proc+j3 <= n3) then
    2379         8636 :        Jp2st=1; J2st=1
    2380              : 
    2381         8636 :        lot=ncache/(4*n1)
    2382              : 
    2383              :        ! Loop over G_y in the small box.
    2384        36984 :        do j=1,m2eff,lot
    2385        28348 :          ma=j
    2386        28348 :          mb=min(j+(lot-1),m2eff)
    2387        28348 :          n1dfft=mb-ma+1
    2388              : 
    2389              :          ! Zero-pad input.
    2390              :          ! input:  G1,G2,R3,JG2,(Rp3)
    2391              :          ! output: G2,G1,R3,JG2,(Rp3)
    2392              : 
    2393        28348 :          if (nproc_fft == 1) then
    2394              :           call mpiswitch_cent(j3,n1dfft,Jp2st,J2st,lot,max1,md1,m1,n1,&
    2395        27772 : &           md2proc,nd3proc,nproc_fft,ioption,zmpi2,zw(1,1,1),unused0, unused0,unused0)
    2396              :          else
    2397              :           call mpiswitch_cent(j3,n1dfft,Jp2st,J2st,lot,max1,md1,m1,n1,&
    2398          576 : &           md2proc,nd3proc,nproc_fft,ioption,zmpi1,zw(1,1,1), unused0,unused0,unused0)
    2399              :          end if
    2400              : 
    2401              :          ! Transform along x
    2402              :          ! input:  G2,G1,R3,(Rp3)
    2403              :          ! output: G2,R1,R3,(Rp3)
    2404        28348 :          inzee=1
    2405        83160 :          do i=1,ic1-1
    2406              :            call fftstp(lot,n1dfft,n1,lot,n1,zw(1,1,inzee),zw(1,1,3-inzee), &
    2407        54812 : &                    trig1,after1(i),now1(i),before1(i),1)
    2408        83160 :            inzee=3-inzee
    2409              :          end do
    2410              : 
    2411        28348 :          i=ic1
    2412              :          call fftstp(lot,n1dfft,n1,lzt,m1zt,zw(1,1,inzee),zt(1,j,1), &
    2413        36984 : &                    trig1,after1(i),now1(i),before1(i),1)
    2414              :        end do
    2415              : 
    2416              :        ! Transform along y axis (take into account c2c or c2r case).
    2417              :        ! Must loop over the full box.
    2418         8636 :        lot=ncache/(4*n2)
    2419         8636 :        if (icplexwf==1) then
    2420         1056 :          if (mod(lot,2).ne.0) lot=lot-1 ! needed to introduce jeff
    2421              :        end if
    2422              : 
    2423        62380 :        do j=1,n1eff,lot
    2424        53744 :          ma=j
    2425        53744 :          mb=min(j+(lot-1),n1eff)
    2426        53744 :          n1dfft=mb-ma+1
    2427        53744 :          jeff=j
    2428        53744 :          includelast=1
    2429              : 
    2430        53744 :          if (icplexwf==1) then
    2431         3856 :            jeff=2*j-1
    2432              :            includelast=1
    2433         3856 :            if (mb==n1eff .and. n1eff*2/=n1) includelast=0
    2434              :          end if
    2435              : 
    2436              :          ! Zero-pad the input.
    2437              :          ! input:  G2,R1,R3,(Rp3)
    2438              :          ! output: R1,G2,R3,(Rp3)
    2439        53744 :          if (icplexwf==2) then
    2440        49888 :            call switch_cent(n1dfft,max2,m2,n2,lot,n1,lzt,zt(1,1,j),zw(1,1,1))
    2441              :          else
    2442         3856 :            call switchreal_cent(includelast,n1dfft,max2,n2,lot,m1zt,lzt,zt(1,1,jeff),zw(1,1,1))
    2443              :          end if
    2444              : 
    2445        53744 :          inzee=1
    2446       213092 :          do i=1,ic2
    2447              :            call fftstp(lot,n1dfft,n2,lot,n2,zw(1,1,inzee),zw(1,1,3-inzee), &
    2448       159348 : &                       trig2,after2(i),now2(i),before2(i),1)
    2449       213092 :            inzee=3-inzee
    2450              :          end do
    2451              : 
    2452              :          ! Accumulate
    2453              :          call addrho(icplexwf,includelast,nd1,nd2,n2,lot,n1dfft,&
    2454        62380 : &          zw(1,1,inzee),rho(jeff,1,j3glob),weight_r(idat),weight_i(idat))
    2455              :        end do
    2456              :        ! output: i1,i2,j3,(jp3)
    2457              : 
    2458              :       end if
    2459              :     end do ! j3
    2460              :  end do ! idat
    2461              : 
    2462          214 :  ABI_FREE(trig1)
    2463          214 :  ABI_FREE(after1)
    2464          214 :  ABI_FREE(now1)
    2465          214 :  ABI_FREE(before1)
    2466          214 :  ABI_FREE(trig2)
    2467          214 :  ABI_FREE(after2)
    2468          214 :  ABI_FREE(now2)
    2469          214 :  ABI_FREE(before2)
    2470          214 :  ABI_FREE(trig3)
    2471          214 :  ABI_FREE(after3)
    2472          214 :  ABI_FREE(now3)
    2473          214 :  ABI_FREE(before3)
    2474              : 
    2475          214 :  ABI_FREE(zmpi2)
    2476          214 :  ABI_FREE(zw)
    2477          214 :  ABI_FREE(zt)
    2478          214 :  if (nproc_fft > 1)  then
    2479           64 :    ABI_FREE(zmpi1)
    2480              :  end if
    2481              : 
    2482          214 : end subroutine sg2002_accrho
    2483              : !!***
    2484              : 
    2485              : !!****f* m_sg2002/ctrig
    2486              : !! NAME
    2487              : !!  ctrig
    2488              : !!
    2489              : !! FUNCTION
    2490              : !!
    2491              : !! INPUTS
    2492              : !!
    2493              : !! OUTPUT
    2494              : !!
    2495              : !! SOURCE
    2496              : 
    2497      5024478 : subroutine ctrig(n,trig,after,before,now,isign,ic)
    2498              : 
    2499              : !Arguments ------------------------------------
    2500              :  integer,intent(in) :: n,isign
    2501              :  integer,intent(inout) :: ic
    2502              :  integer,intent(inout) :: after(mdata),before(mdata),now(mdata)
    2503              :  real(dp),intent(inout) :: trig(2,n)
    2504              : 
    2505              : !Local variables-------------------------------
    2506              : !scalars
    2507              :  integer :: i,itt,j,nh
    2508              :  real(dp) :: angle,trigc,trigs
    2509              : 
    2510              : ! *************************************************************************
    2511              : 
    2512     58820902 :  do i=1,ndata
    2513     58820902 :    if (n.eq.ifftdata(1,i)) then
    2514      5024478 :      ic=0
    2515     15149135 :      do j=1,(mdata-1)
    2516     15149135 :        itt=ifftdata(1+j,i)
    2517     15149135 :        if (itt.gt.1) then
    2518     10124657 :          ic=ic+1
    2519     10124657 :          now(j)=ifftdata(1+j,i)
    2520              :        else
    2521              :          goto 1000
    2522              :        end if
    2523              :      end do
    2524              :      goto 1000
    2525              :    end if
    2526              :  end do
    2527              : 
    2528            0 :  write(std_out,*) 'VALUE OF',n,'NOT ALLOWED FOR FFT, ALLOWED VALUES ARE:'
    2529              : 37 format(15(i5))
    2530            0 :  write(std_out,37) (ifftdata(1,i),i=1,ndata)
    2531      5024478 :  ABI_ERROR("Aborting now")
    2532              : 
    2533              : 1000 continue
    2534      5024478 :  after(1)=1
    2535      5024478 :  before(ic)=1
    2536     10124657 :  do i=2,ic
    2537      5100179 :    after(i)=after(i-1)*now(i-1)
    2538     10124657 :    before(ic-i+1)=before(ic-i+2)*now(ic-i+2)
    2539              :  end do
    2540              : 
    2541      5024478 :  angle=isign*two_pi/n
    2542      5024478 :  if (mod(n,2).eq.0) then
    2543      4968979 :    nh=n/2
    2544      4968979 :    trig(1,1)=one
    2545      4968979 :    trig(2,1)=zero
    2546      4968979 :    trig(1,nh+1)=-one
    2547      4968979 :    trig(2,nh+1)=zero
    2548     50016357 :    do i=1,nh-1
    2549     45047378 :      trigc=cos(i*angle)
    2550     45047378 :      trigs=sin(i*angle)
    2551     45047378 :      trig(1,i+1)=trigc
    2552     45047378 :      trig(2,i+1)=trigs
    2553     45047378 :      trig(1,n-i+1)=trigc
    2554     50016357 :      trig(2,n-i+1)=-trigs
    2555              :    end do
    2556              :  else
    2557        55499 :    nh=(n-1)/2
    2558        55499 :    trig(1,1)=one
    2559        55499 :    trig(2,1)=zero
    2560       667156 :    do i=1,nh
    2561       611657 :      trigc=cos(i*angle)
    2562       611657 :      trigs=sin(i*angle)
    2563       611657 :      trig(1,i+1)=trigc
    2564       611657 :      trig(2,i+1)=trigs
    2565       611657 :      trig(1,n-i+1)=trigc
    2566       667156 :      trig(2,n-i+1)=-trigs
    2567              :    end do
    2568              :  end if
    2569              : 
    2570      5024478 : end subroutine ctrig
    2571              : !!***
    2572              : 
    2573              : !!****f* m_sg2002/fftstp
    2574              : !! NAME
    2575              : !!  fftstp
    2576              : !!
    2577              : !! FUNCTION
    2578              : !!
    2579              : !! INPUTS
    2580              : !!   mm
    2581              : !!   n1dfft
    2582              : !!   m
    2583              : !!   nn
    2584              : !!   n
    2585              : !!   zin
    2586              : !!   trig
    2587              : !!   after
    2588              : !!   now
    2589              : !!   before
    2590              : !!   isign
    2591              : !!
    2592              : !! OUTPUT
    2593              : !!   zout
    2594              : !!
    2595              : !! SOURCE
    2596              : 
    2597    117986786 : subroutine fftstp(mm,n1dfft,m,nn,n,zin,zout,trig,after,now,before,isign)
    2598              : 
    2599              : !Arguments ------------------------------------
    2600              :  integer,intent(in) :: after,before,mm,n1dfft,m,nn,n,now,isign
    2601              :  real(dp),intent(in) :: trig(2,n),zin(2,mm,m)
    2602              :  real(dp),intent(inout) :: zout(2,nn,n)
    2603              : 
    2604              : !Local variables-------------------------------
    2605              :  integer :: atn,atb,ia,ias,ib,itrig,itt,j,nin1,nin2,nin3,nin4,nin5,nin6,nin7,nin8
    2606              :  integer :: nout1,nout2,nout3,nout4,nout5,nout6,nout7,nout8
    2607              :  real(dp) :: am,ap,bm,bp,ci3,ci4,ci5,ci6,ci7,ci8,cm,cos2,cos4,cp,cr2,cr3,cr4,cr5,cr6,cr7,cr8
    2608              :  real(dp) :: dm,bb,ci2,dpp,r,r2,r25,r3,r34,r4,r5,r6,r7,r8,rt2i,s,r1,s1,s2,s3,s25,s34,s4,s5,s6,s7,s8
    2609              :  real(dp) :: sin2,ui1,ui2,ui3,ur1,ur2,ur3,sin4,vi1,vi2,vi3,vr1,vr2,vr3
    2610              : 
    2611              : ! *************************************************************************
    2612    117986786 :         atn=after*now
    2613    117986786 :         atb=after*before
    2614              : 
    2615              : !         sqrt(.5d0)
    2616    117986786 :         rt2i=half_sqrt2
    2617              :         if (now.eq.2) then
    2618       496368 :         ia=1
    2619       496368 :         nin1=ia-after
    2620       496368 :         nout1=ia-atn
    2621       992736 :         do ib=1,before
    2622       496368 :           nin1=nin1+after
    2623       496368 :           nin2=nin1+atb
    2624       496368 :           nout1=nout1+atn
    2625       496368 :           nout2=nout1+after
    2626      6517536 :             do j=1,n1dfft
    2627      5524800 :             r1=zin(1,j,nin1)
    2628      5524800 :             s1=zin(2,j,nin1)
    2629      5524800 :             r2=zin(1,j,nin2)
    2630      5524800 :             s2=zin(2,j,nin2)
    2631      5524800 :             zout(1,j,nout1)= r2 + r1
    2632      5524800 :             zout(2,j,nout1)= s2 + s1
    2633      5524800 :             zout(1,j,nout2)= r1 - r2
    2634      6021168 :             zout(2,j,nout2)= s1 - s2
    2635              :           enddo
    2636              :         enddo
    2637     11864880 :         do 2000,ia=2,after
    2638     11368512 :         ias=ia-1
    2639     11368512 :         if (2*ias.eq.after) then
    2640            0 :                 if (isign.eq.1) then
    2641            0 :                         nin1=ia-after
    2642            0 :                         nout1=ia-atn
    2643            0 :                         do ib=1,before
    2644            0 :                           nin1=nin1+after
    2645            0 :                           nin2=nin1+atb
    2646            0 :                           nout1=nout1+atn
    2647            0 :                           nout2=nout1+after
    2648            0 :                           do j=1,n1dfft
    2649            0 :                             r1=zin(1,j,nin1)
    2650            0 :                             s1=zin(2,j,nin1)
    2651            0 :                             r2=zin(2,j,nin2)
    2652            0 :                             s2=zin(1,j,nin2)
    2653            0 :                             zout(1,j,nout1)= r1 - r2
    2654            0 :                             zout(2,j,nout1)= s2 + s1
    2655            0 :                             zout(1,j,nout2)= r2 + r1
    2656            0 :                             zout(2,j,nout2)= s1 - s2
    2657              :                           enddo
    2658              :                         enddo
    2659              :                 else
    2660            0 :                         nin1=ia-after
    2661            0 :                         nout1=ia-atn
    2662            0 :                         do ib=1,before
    2663            0 :                           nin1=nin1+after
    2664            0 :                           nin2=nin1+atb
    2665            0 :                           nout1=nout1+atn
    2666            0 :                           nout2=nout1+after
    2667            0 :                             do j=1,n1dfft
    2668            0 :                             r1=zin(1,j,nin1)
    2669            0 :                             s1=zin(2,j,nin1)
    2670            0 :                             r2=zin(2,j,nin2)
    2671            0 :                             s2=zin(1,j,nin2)
    2672            0 :                             zout(1,j,nout1)= r2 + r1
    2673            0 :                             zout(2,j,nout1)= s1 - s2
    2674            0 :                             zout(1,j,nout2)= r1 - r2
    2675            0 :                             zout(2,j,nout2)= s2 + s1
    2676              :                           enddo
    2677              :                         enddo
    2678              :                 end if
    2679     11368512 :         else if (4*ias.eq.after) then
    2680            0 :                 if (isign.eq.1) then
    2681            0 :                         nin1=ia-after
    2682            0 :                         nout1=ia-atn
    2683            0 :                         do ib=1,before
    2684            0 :                         nin1=nin1+after
    2685            0 :                         nin2=nin1+atb
    2686            0 :                         nout1=nout1+atn
    2687            0 :                         nout2=nout1+after
    2688            0 :                         do j=1,n1dfft
    2689            0 :                         r1=zin(1,j,nin1)
    2690            0 :                         s1=zin(2,j,nin1)
    2691            0 :                         r=zin(1,j,nin2)
    2692            0 :                         s=zin(2,j,nin2)
    2693            0 :                         r2=(r - s)*rt2i
    2694            0 :                         s2=(r + s)*rt2i
    2695            0 :                         zout(1,j,nout1)= r2 + r1
    2696            0 :                         zout(2,j,nout1)= s2 + s1
    2697            0 :                         zout(1,j,nout2)= r1 - r2
    2698            0 :                         zout(2,j,nout2)= s1 - s2
    2699              :                         enddo
    2700              :                         enddo
    2701              :                 else
    2702            0 :                         nin1=ia-after
    2703            0 :                         nout1=ia-atn
    2704            0 :                         do ib=1,before
    2705            0 :                         nin1=nin1+after
    2706            0 :                         nin2=nin1+atb
    2707            0 :                         nout1=nout1+atn
    2708            0 :                         nout2=nout1+after
    2709            0 :                         do j=1,n1dfft
    2710            0 :                         r1=zin(1,j,nin1)
    2711            0 :                         s1=zin(2,j,nin1)
    2712            0 :                         r=zin(1,j,nin2)
    2713            0 :                         s=zin(2,j,nin2)
    2714            0 :                         r2=(r + s)*rt2i
    2715            0 :                         s2=(s - r)*rt2i
    2716            0 :                         zout(1,j,nout1)= r2 + r1
    2717            0 :                         zout(2,j,nout1)= s2 + s1
    2718            0 :                         zout(1,j,nout2)= r1 - r2
    2719            0 :                         zout(2,j,nout2)= s1 - s2
    2720              :                         enddo
    2721              :                         enddo
    2722              :                 end if
    2723     11368512 :         else if (4*ias.eq.3*after) then
    2724            0 :                 if (isign.eq.1) then
    2725            0 :                         nin1=ia-after
    2726            0 :                         nout1=ia-atn
    2727            0 :                         do ib=1,before
    2728            0 :                         nin1=nin1+after
    2729            0 :                         nin2=nin1+atb
    2730            0 :                         nout1=nout1+atn
    2731            0 :                         nout2=nout1+after
    2732            0 :                         do j=1,n1dfft
    2733            0 :                         r1=zin(1,j,nin1)
    2734            0 :                         s1=zin(2,j,nin1)
    2735            0 :                         r=zin(1,j,nin2)
    2736            0 :                         s=zin(2,j,nin2)
    2737            0 :                         r2=(r + s)*rt2i
    2738            0 :                         s2=(r - s)*rt2i
    2739            0 :                         zout(1,j,nout1)= r1 - r2
    2740            0 :                         zout(2,j,nout1)= s2 + s1
    2741            0 :                         zout(1,j,nout2)= r2 + r1
    2742            0 :                         zout(2,j,nout2)= s1 - s2
    2743              :                         enddo
    2744              :                         enddo
    2745              :                 else
    2746            0 :                         nin1=ia-after
    2747            0 :                         nout1=ia-atn
    2748            0 :                         do ib=1,before
    2749            0 :                         nin1=nin1+after
    2750            0 :                         nin2=nin1+atb
    2751            0 :                         nout1=nout1+atn
    2752            0 :                         nout2=nout1+after
    2753            0 :                         do j=1,n1dfft
    2754            0 :                         r1=zin(1,j,nin1)
    2755            0 :                         s1=zin(2,j,nin1)
    2756            0 :                         r=zin(1,j,nin2)
    2757            0 :                         s=zin(2,j,nin2)
    2758            0 :                         r2=(s - r)*rt2i
    2759            0 :                         s2=(r + s)*rt2i
    2760            0 :                         zout(1,j,nout1)= r2 + r1
    2761            0 :                         zout(2,j,nout1)= s1 - s2
    2762            0 :                         zout(1,j,nout2)= r1 - r2
    2763            0 :                         zout(2,j,nout2)= s2 + s1
    2764              :                         enddo
    2765              :                         enddo
    2766              :                 end if
    2767              :         else
    2768     11368512 :                 itrig=ias*before+1
    2769     11368512 :                 cr2=trig(1,itrig)
    2770     11368512 :                 ci2=trig(2,itrig)
    2771     11368512 :                 nin1=ia-after
    2772     11368512 :                 nout1=ia-atn
    2773     22737024 :                 do ib=1,before
    2774     11368512 :                 nin1=nin1+after
    2775     11368512 :                 nin2=nin1+atb
    2776     11368512 :                 nout1=nout1+atn
    2777     11368512 :                 nout2=nout1+after
    2778    150977664 :                 do j=1,n1dfft
    2779    128240640 :                 r1=zin(1,j,nin1)
    2780    128240640 :                 s1=zin(2,j,nin1)
    2781    128240640 :                 r=zin(1,j,nin2)
    2782    128240640 :                 s=zin(2,j,nin2)
    2783    128240640 :                 r2=r*cr2 - s*ci2
    2784    128240640 :                 s2=r*ci2 + s*cr2
    2785    128240640 :                 zout(1,j,nout1)= r2 + r1
    2786    128240640 :                 zout(2,j,nout1)= s2 + s1
    2787    128240640 :                 zout(1,j,nout2)= r1 - r2
    2788    139609152 :                 zout(2,j,nout2)= s1 - s2
    2789              :                 enddo
    2790              :                 enddo
    2791              :         end if
    2792       496368 : 2000        continue
    2793              :         else if (now.eq.4) then
    2794     31458863 :         if (isign.eq.1) then
    2795     16507258 :                 ia=1
    2796     16507258 :                 nin1=ia-after
    2797     16507258 :                 nout1=ia-atn
    2798     68071554 :                 do ib=1,before
    2799     51564296 :                 nin1=nin1+after
    2800     51564296 :                 nin2=nin1+atb
    2801     51564296 :                 nin3=nin2+atb
    2802     51564296 :                 nin4=nin3+atb
    2803     51564296 :                 nout1=nout1+atn
    2804     51564296 :                 nout2=nout1+after
    2805     51564296 :                 nout3=nout2+after
    2806     51564296 :                 nout4=nout3+after
    2807    772519455 :                 do j=1,n1dfft
    2808    704447901 :                 r1=zin(1,j,nin1)
    2809    704447901 :                 s1=zin(2,j,nin1)
    2810    704447901 :                 r2=zin(1,j,nin2)
    2811    704447901 :                 s2=zin(2,j,nin2)
    2812    704447901 :                 r3=zin(1,j,nin3)
    2813    704447901 :                 s3=zin(2,j,nin3)
    2814    704447901 :                 r4=zin(1,j,nin4)
    2815    704447901 :                 s4=zin(2,j,nin4)
    2816    704447901 :                 r=r1 + r3
    2817    704447901 :                 s=r2 + r4
    2818    704447901 :                 zout(1,j,nout1) = r + s
    2819    704447901 :                 zout(1,j,nout3) = r - s
    2820    704447901 :                 r=r1 - r3
    2821    704447901 :                 s=s2 - s4
    2822    704447901 :                 zout(1,j,nout2) = r - s
    2823    704447901 :                 zout(1,j,nout4) = r + s
    2824    704447901 :                 r=s1 + s3
    2825    704447901 :                 s=s2 + s4
    2826    704447901 :                 zout(2,j,nout1) = r + s
    2827    704447901 :                 zout(2,j,nout3) = r - s
    2828    704447901 :                 r=s1 - s3
    2829    704447901 :                 s=r2 - r4
    2830    704447901 :                 zout(2,j,nout2) = r + s
    2831    756012197 :                 zout(2,j,nout4) = r - s
    2832              :                 enddo
    2833              :                 enddo
    2834     63304048 :                 do 4000,ia=2,after
    2835     46796790 :                 ias=ia-1
    2836     46796790 :                 if (2*ias.eq.after) then
    2837      4838434 :                         nin1=ia-after
    2838      4838434 :                         nout1=ia-atn
    2839     12276516 :                         do ib=1,before
    2840      7438082 :                         nin1=nin1+after
    2841      7438082 :                         nin2=nin1+atb
    2842      7438082 :                         nin3=nin2+atb
    2843      7438082 :                         nin4=nin3+atb
    2844      7438082 :                         nout1=nout1+atn
    2845      7438082 :                         nout2=nout1+after
    2846      7438082 :                         nout3=nout2+after
    2847      7438082 :                         nout4=nout3+after
    2848    114174315 :                         do j=1,n1dfft
    2849    101897799 :                         r1=zin(1,j,nin1)
    2850    101897799 :                         s1=zin(2,j,nin1)
    2851    101897799 :                         r=zin(1,j,nin2)
    2852    101897799 :                         s=zin(2,j,nin2)
    2853    101897799 :                         r2=(r-s)*rt2i
    2854    101897799 :                         s2=(r+s)*rt2i
    2855    101897799 :                         r3=zin(2,j,nin3)
    2856    101897799 :                         s3=zin(1,j,nin3)
    2857    101897799 :                         r=zin(1,j,nin4)
    2858    101897799 :                         s=zin(2,j,nin4)
    2859    101897799 :                         r4=(r + s)*rt2i
    2860    101897799 :                         s4=(r - s)*rt2i
    2861    101897799 :                         r=r1 - r3
    2862    101897799 :                         s=r2 - r4
    2863    101897799 :                         zout(1,j,nout1) = r + s
    2864    101897799 :                         zout(1,j,nout3) = r - s
    2865    101897799 :                         r=r1 + r3
    2866    101897799 :                         s=s2 - s4
    2867    101897799 :                         zout(1,j,nout2) = r - s
    2868    101897799 :                         zout(1,j,nout4) = r + s
    2869    101897799 :                         r=s1 + s3
    2870    101897799 :                         s=s2 + s4
    2871    101897799 :                         zout(2,j,nout1) = r + s
    2872    101897799 :                         zout(2,j,nout3) = r - s
    2873    101897799 :                         r=s1 - s3
    2874    101897799 :                         s=r2 + r4
    2875    101897799 :                         zout(2,j,nout2) = r + s
    2876    109335881 :                         zout(2,j,nout4) = r - s
    2877              :                         enddo
    2878              :                         enddo
    2879              :                 else
    2880     41958356 :                         itt=ias*before
    2881     41958356 :                         itrig=itt+1
    2882     41958356 :                         cr2=trig(1,itrig)
    2883     41958356 :                         ci2=trig(2,itrig)
    2884     41958356 :                         itrig=itrig+itt
    2885     41958356 :                         cr3=trig(1,itrig)
    2886     41958356 :                         ci3=trig(2,itrig)
    2887     41958356 :                         itrig=itrig+itt
    2888     41958356 :                         cr4=trig(1,itrig)
    2889     41958356 :                         ci4=trig(2,itrig)
    2890     41958356 :                         nin1=ia-after
    2891     41958356 :                         nout1=ia-atn
    2892     90228240 :                         do ib=1,before
    2893     48269884 :                         nin1=nin1+after
    2894     48269884 :                         nin2=nin1+atb
    2895     48269884 :                         nin3=nin2+atb
    2896     48269884 :                         nin4=nin3+atb
    2897     48269884 :                         nout1=nout1+atn
    2898     48269884 :                         nout2=nout1+after
    2899     48269884 :                         nout3=nout2+after
    2900     48269884 :                         nout4=nout3+after
    2901    718969902 :                         do j=1,n1dfft
    2902    628741662 :                         r1=zin(1,j,nin1)
    2903    628741662 :                         s1=zin(2,j,nin1)
    2904    628741662 :                         r=zin(1,j,nin2)
    2905    628741662 :                         s=zin(2,j,nin2)
    2906    628741662 :                         r2=r*cr2 - s*ci2
    2907    628741662 :                         s2=r*ci2 + s*cr2
    2908    628741662 :                         r=zin(1,j,nin3)
    2909    628741662 :                         s=zin(2,j,nin3)
    2910    628741662 :                         r3=r*cr3 - s*ci3
    2911    628741662 :                         s3=r*ci3 + s*cr3
    2912    628741662 :                         r=zin(1,j,nin4)
    2913    628741662 :                         s=zin(2,j,nin4)
    2914    628741662 :                         r4=r*cr4 - s*ci4
    2915    628741662 :                         s4=r*ci4 + s*cr4
    2916    628741662 :                         r=r1 + r3
    2917    628741662 :                         s=r2 + r4
    2918    628741662 :                         zout(1,j,nout1) = r + s
    2919    628741662 :                         zout(1,j,nout3) = r - s
    2920    628741662 :                         r=r1 - r3
    2921    628741662 :                         s=s2 - s4
    2922    628741662 :                         zout(1,j,nout2) = r - s
    2923    628741662 :                         zout(1,j,nout4) = r + s
    2924    628741662 :                         r=s1 + s3
    2925    628741662 :                         s=s2 + s4
    2926    628741662 :                         zout(2,j,nout1) = r + s
    2927    628741662 :                         zout(2,j,nout3) = r - s
    2928    628741662 :                         r=s1 - s3
    2929    628741662 :                         s=r2 - r4
    2930    628741662 :                         zout(2,j,nout2) = r + s
    2931    677011546 :                         zout(2,j,nout4) = r - s
    2932              :                         enddo
    2933              :                         enddo
    2934              :                 end if
    2935     16507258 : 4000                continue
    2936              :         else
    2937     14951605 :                 ia=1
    2938     14951605 :                 nin1=ia-after
    2939     14951605 :                 nout1=ia-atn
    2940     64139150 :                 do ib=1,before
    2941     49187545 :                 nin1=nin1+after
    2942     49187545 :                 nin2=nin1+atb
    2943     49187545 :                 nin3=nin2+atb
    2944     49187545 :                 nin4=nin3+atb
    2945     49187545 :                 nout1=nout1+atn
    2946     49187545 :                 nout2=nout1+after
    2947     49187545 :                 nout3=nout2+after
    2948     49187545 :                 nout4=nout3+after
    2949    751673250 :                 do j=1,n1dfft
    2950    687534100 :                 r1=zin(1,j,nin1)
    2951    687534100 :                 s1=zin(2,j,nin1)
    2952    687534100 :                 r2=zin(1,j,nin2)
    2953    687534100 :                 s2=zin(2,j,nin2)
    2954    687534100 :                 r3=zin(1,j,nin3)
    2955    687534100 :                 s3=zin(2,j,nin3)
    2956    687534100 :                 r4=zin(1,j,nin4)
    2957    687534100 :                 s4=zin(2,j,nin4)
    2958    687534100 :                 r=r1 + r3
    2959    687534100 :                 s=r2 + r4
    2960    687534100 :                 zout(1,j,nout1) = r + s
    2961    687534100 :                 zout(1,j,nout3) = r - s
    2962    687534100 :                 r=r1 - r3
    2963    687534100 :                 s=s2 - s4
    2964    687534100 :                 zout(1,j,nout2) = r + s
    2965    687534100 :                 zout(1,j,nout4) = r - s
    2966    687534100 :                 r=s1 + s3
    2967    687534100 :                 s=s2 + s4
    2968    687534100 :                 zout(2,j,nout1) = r + s
    2969    687534100 :                 zout(2,j,nout3) = r - s
    2970    687534100 :                 r=s1 - s3
    2971    687534100 :                 s=r2 - r4
    2972    687534100 :                 zout(2,j,nout2) = r - s
    2973    736721645 :                 zout(2,j,nout4) = r + s
    2974              :                 enddo
    2975              :                 enddo
    2976     55030785 :                 do 4100,ia=2,after
    2977     40079180 :                 ias=ia-1
    2978     40079180 :                 if (2*ias.eq.after) then
    2979      4244980 :                         nin1=ia-after
    2980      4244980 :                         nout1=ia-atn
    2981     10782712 :                         do ib=1,before
    2982      6537732 :                         nin1=nin1+after
    2983      6537732 :                         nin2=nin1+atb
    2984      6537732 :                         nin3=nin2+atb
    2985      6537732 :                         nin4=nin3+atb
    2986      6537732 :                         nout1=nout1+atn
    2987      6537732 :                         nout2=nout1+after
    2988      6537732 :                         nout3=nout2+after
    2989      6537732 :                         nout4=nout3+after
    2990    100812550 :                         do j=1,n1dfft
    2991     90029838 :                         r1=zin(1,j,nin1)
    2992     90029838 :                         s1=zin(2,j,nin1)
    2993     90029838 :                         r=zin(1,j,nin2)
    2994     90029838 :                         s=zin(2,j,nin2)
    2995     90029838 :                         r2=(r + s)*rt2i
    2996     90029838 :                         s2=(s - r)*rt2i
    2997     90029838 :                         r3=zin(2,j,nin3)
    2998     90029838 :                         s3=zin(1,j,nin3)
    2999     90029838 :                         r=zin(1,j,nin4)
    3000     90029838 :                         s=zin(2,j,nin4)
    3001     90029838 :                         r4=(s - r)*rt2i
    3002     90029838 :                         s4=(r + s)*rt2i
    3003     90029838 :                         r=r1 + r3
    3004     90029838 :                         s=r2 + r4
    3005     90029838 :                         zout(1,j,nout1) = r + s
    3006     90029838 :                         zout(1,j,nout3) = r - s
    3007     90029838 :                         r=r1 - r3
    3008     90029838 :                         s=s2 + s4
    3009     90029838 :                         zout(1,j,nout2) = r + s
    3010     90029838 :                         zout(1,j,nout4) = r - s
    3011     90029838 :                         r=s1 - s3
    3012     90029838 :                         s=s2 - s4
    3013     90029838 :                         zout(2,j,nout1) = r + s
    3014     90029838 :                         zout(2,j,nout3) = r - s
    3015     90029838 :                         r=s1 + s3
    3016     90029838 :                         s=r2 - r4
    3017     90029838 :                         zout(2,j,nout2) = r - s
    3018     96567570 :                         zout(2,j,nout4) = r + s
    3019              :                         enddo
    3020              :                         enddo
    3021              :                 else
    3022     35834200 :                         itt=ias*before
    3023     35834200 :                         itrig=itt+1
    3024     35834200 :                         cr2=trig(1,itrig)
    3025     35834200 :                         ci2=trig(2,itrig)
    3026     35834200 :                         itrig=itrig+itt
    3027     35834200 :                         cr3=trig(1,itrig)
    3028     35834200 :                         ci3=trig(2,itrig)
    3029     35834200 :                         itrig=itrig+itt
    3030     35834200 :                         cr4=trig(1,itrig)
    3031     35834200 :                         ci4=trig(2,itrig)
    3032     35834200 :                         nin1=ia-after
    3033     35834200 :                         nout1=ia-atn
    3034     76940352 :                         do ib=1,before
    3035     41106152 :                         nin1=nin1+after
    3036     41106152 :                         nin2=nin1+atb
    3037     41106152 :                         nin3=nin2+atb
    3038     41106152 :                         nin4=nin3+atb
    3039     41106152 :                         nout1=nout1+atn
    3040     41106152 :                         nout2=nout1+after
    3041     41106152 :                         nout3=nout2+after
    3042     41106152 :                         nout4=nout3+after
    3043    617734268 :                         do j=1,n1dfft
    3044    540793916 :                         r1=zin(1,j,nin1)
    3045    540793916 :                         s1=zin(2,j,nin1)
    3046    540793916 :                         r=zin(1,j,nin2)
    3047    540793916 :                         s=zin(2,j,nin2)
    3048    540793916 :                         r2=r*cr2 - s*ci2
    3049    540793916 :                         s2=r*ci2 + s*cr2
    3050    540793916 :                         r=zin(1,j,nin3)
    3051    540793916 :                         s=zin(2,j,nin3)
    3052    540793916 :                         r3=r*cr3 - s*ci3
    3053    540793916 :                         s3=r*ci3 + s*cr3
    3054    540793916 :                         r=zin(1,j,nin4)
    3055    540793916 :                         s=zin(2,j,nin4)
    3056    540793916 :                         r4=r*cr4 - s*ci4
    3057    540793916 :                         s4=r*ci4 + s*cr4
    3058    540793916 :                         r=r1 + r3
    3059    540793916 :                         s=r2 + r4
    3060    540793916 :                         zout(1,j,nout1) = r + s
    3061    540793916 :                         zout(1,j,nout3) = r - s
    3062    540793916 :                         r=r1 - r3
    3063    540793916 :                         s=s2 - s4
    3064    540793916 :                         zout(1,j,nout2) = r + s
    3065    540793916 :                         zout(1,j,nout4) = r - s
    3066    540793916 :                         r=s1 + s3
    3067    540793916 :                         s=s2 + s4
    3068    540793916 :                         zout(2,j,nout1) = r + s
    3069    540793916 :                         zout(2,j,nout3) = r - s
    3070    540793916 :                         r=s1 - s3
    3071    540793916 :                         s=r2 - r4
    3072    540793916 :                         zout(2,j,nout2) = r - s
    3073    581900068 :                         zout(2,j,nout4) = r + s
    3074              :                         enddo
    3075              :                         enddo
    3076              :                 end if
    3077     14951605 : 4100                continue
    3078              :         end if
    3079              :         else if (now.eq.8) then
    3080     14955278 :         if (isign.eq.-1) then
    3081      7207400 :                 ia=1
    3082      7207400 :                         nin1=ia-after
    3083      7207400 :                         nout1=ia-atn
    3084     31827600 :                         do ib=1,before
    3085     24620200 :                         nin1=nin1+after
    3086     24620200 :                         nin2=nin1+atb
    3087     24620200 :                         nin3=nin2+atb
    3088     24620200 :                         nin4=nin3+atb
    3089     24620200 :                         nin5=nin4+atb
    3090     24620200 :                         nin6=nin5+atb
    3091     24620200 :                         nin7=nin6+atb
    3092     24620200 :                         nin8=nin7+atb
    3093     24620200 :                         nout1=nout1+atn
    3094     24620200 :                         nout2=nout1+after
    3095     24620200 :                         nout3=nout2+after
    3096     24620200 :                         nout4=nout3+after
    3097     24620200 :                         nout5=nout4+after
    3098     24620200 :                         nout6=nout5+after
    3099     24620200 :                         nout7=nout6+after
    3100     24620200 :                         nout8=nout7+after
    3101    417878672 :                         do j=1,n1dfft
    3102    386051072 :                         r1=zin(1,j,nin1)
    3103    386051072 :                         s1=zin(2,j,nin1)
    3104    386051072 :                         r2=zin(1,j,nin2)
    3105    386051072 :                         s2=zin(2,j,nin2)
    3106    386051072 :                         r3=zin(1,j,nin3)
    3107    386051072 :                         s3=zin(2,j,nin3)
    3108    386051072 :                         r4=zin(1,j,nin4)
    3109    386051072 :                         s4=zin(2,j,nin4)
    3110    386051072 :                         r5=zin(1,j,nin5)
    3111    386051072 :                         s5=zin(2,j,nin5)
    3112    386051072 :                         r6=zin(1,j,nin6)
    3113    386051072 :                         s6=zin(2,j,nin6)
    3114    386051072 :                         r7=zin(1,j,nin7)
    3115    386051072 :                         s7=zin(2,j,nin7)
    3116    386051072 :                         r8=zin(1,j,nin8)
    3117    386051072 :                         s8=zin(2,j,nin8)
    3118    386051072 :                         r=r1 + r5
    3119    386051072 :                         s=r3 + r7
    3120    386051072 :                         ap=r + s
    3121    386051072 :                         am=r - s
    3122    386051072 :                         r=r2 + r6
    3123    386051072 :                         s=r4 + r8
    3124    386051072 :                         bp=r + s
    3125    386051072 :                         bm=r - s
    3126    386051072 :                         r=s1 + s5
    3127    386051072 :                         s=s3 + s7
    3128    386051072 :                         cp=r + s
    3129    386051072 :                         cm=r - s
    3130    386051072 :                         r=s2 + s6
    3131    386051072 :                         s=s4 + s8
    3132    386051072 :                         dpp=r + s
    3133    386051072 :                         dm=r - s
    3134    386051072 :                         zout(1,j,nout1) = ap + bp
    3135    386051072 :                         zout(2,j,nout1) = cp + dpp
    3136    386051072 :                         zout(1,j,nout5) = ap - bp
    3137    386051072 :                         zout(2,j,nout5) = cp - dpp
    3138    386051072 :                         zout(1,j,nout3) = am + dm
    3139    386051072 :                         zout(2,j,nout3) = cm - bm
    3140    386051072 :                         zout(1,j,nout7) = am - dm
    3141    386051072 :                         zout(2,j,nout7) = cm + bm
    3142    386051072 :                         r=r1 - r5
    3143    386051072 :                         s=s3 - s7
    3144    386051072 :                         ap=r + s
    3145    386051072 :                         am=r - s
    3146    386051072 :                         r=s1 - s5
    3147    386051072 :                         s=r3 - r7
    3148    386051072 :                         bp=r + s
    3149    386051072 :                         bm=r - s
    3150    386051072 :                         r=s4 - s8
    3151    386051072 :                         s=r2 - r6
    3152    386051072 :                         cp=r + s
    3153    386051072 :                         cm=r - s
    3154    386051072 :                         r=s2 - s6
    3155    386051072 :                         s=r4 - r8
    3156    386051072 :                         dpp=r + s
    3157    386051072 :                         dm=r - s
    3158    386051072 :                         r = ( cp + dm)*rt2i
    3159    386051072 :                         s = ( dm - cp)*rt2i
    3160    386051072 :                         cp= ( cm + dpp)*rt2i
    3161    386051072 :                         dpp = ( cm - dpp)*rt2i
    3162    386051072 :                         zout(1,j,nout2) = ap + r
    3163    386051072 :                         zout(2,j,nout2) = bm + s
    3164    386051072 :                         zout(1,j,nout6) = ap - r
    3165    386051072 :                         zout(2,j,nout6) = bm - s
    3166    386051072 :                         zout(1,j,nout4) = am + cp
    3167    386051072 :                         zout(2,j,nout4) = bp + dpp
    3168    386051072 :                         zout(1,j,nout8) = am - cp
    3169    410671272 :                         zout(2,j,nout8) = bp - dpp
    3170              :                         enddo
    3171              :                         enddo
    3172      7207400 :                 do 8000,ia=2,after
    3173            0 :                 ias=ia-1
    3174            0 :                         itt=ias*before
    3175            0 :                         itrig=itt+1
    3176            0 :                         cr2=trig(1,itrig)
    3177            0 :                         ci2=trig(2,itrig)
    3178            0 :                         itrig=itrig+itt
    3179            0 :                         cr3=trig(1,itrig)
    3180            0 :                         ci3=trig(2,itrig)
    3181            0 :                         itrig=itrig+itt
    3182            0 :                         cr4=trig(1,itrig)
    3183            0 :                         ci4=trig(2,itrig)
    3184            0 :                         itrig=itrig+itt
    3185            0 :                         cr5=trig(1,itrig)
    3186            0 :                         ci5=trig(2,itrig)
    3187            0 :                         itrig=itrig+itt
    3188            0 :                         cr6=trig(1,itrig)
    3189            0 :                         ci6=trig(2,itrig)
    3190            0 :                         itrig=itrig+itt
    3191            0 :                         cr7=trig(1,itrig)
    3192            0 :                         ci7=trig(2,itrig)
    3193            0 :                         itrig=itrig+itt
    3194            0 :                         cr8=trig(1,itrig)
    3195            0 :                         ci8=trig(2,itrig)
    3196            0 :                         nin1=ia-after
    3197            0 :                         nout1=ia-atn
    3198            0 :                         do ib=1,before
    3199            0 :                         nin1=nin1+after
    3200            0 :                         nin2=nin1+atb
    3201            0 :                         nin3=nin2+atb
    3202            0 :                         nin4=nin3+atb
    3203            0 :                         nin5=nin4+atb
    3204            0 :                         nin6=nin5+atb
    3205            0 :                         nin7=nin6+atb
    3206            0 :                         nin8=nin7+atb
    3207            0 :                         nout1=nout1+atn
    3208            0 :                         nout2=nout1+after
    3209            0 :                         nout3=nout2+after
    3210            0 :                         nout4=nout3+after
    3211            0 :                         nout5=nout4+after
    3212            0 :                         nout6=nout5+after
    3213            0 :                         nout7=nout6+after
    3214            0 :                         nout8=nout7+after
    3215            0 :                         do j=1,n1dfft
    3216            0 :                         r1=zin(1,j,nin1)
    3217            0 :                         s1=zin(2,j,nin1)
    3218            0 :                         r=zin(1,j,nin2)
    3219            0 :                         s=zin(2,j,nin2)
    3220            0 :                         r2=r*cr2 - s*ci2
    3221            0 :                         s2=r*ci2 + s*cr2
    3222            0 :                         r=zin(1,j,nin3)
    3223            0 :                         s=zin(2,j,nin3)
    3224            0 :                         r3=r*cr3 - s*ci3
    3225            0 :                         s3=r*ci3 + s*cr3
    3226            0 :                         r=zin(1,j,nin4)
    3227            0 :                         s=zin(2,j,nin4)
    3228            0 :                         r4=r*cr4 - s*ci4
    3229            0 :                         s4=r*ci4 + s*cr4
    3230            0 :                         r=zin(1,j,nin5)
    3231            0 :                         s=zin(2,j,nin5)
    3232            0 :                         r5=r*cr5 - s*ci5
    3233            0 :                         s5=r*ci5 + s*cr5
    3234            0 :                         r=zin(1,j,nin6)
    3235            0 :                         s=zin(2,j,nin6)
    3236            0 :                         r6=r*cr6 - s*ci6
    3237            0 :                         s6=r*ci6 + s*cr6
    3238            0 :                         r=zin(1,j,nin7)
    3239            0 :                         s=zin(2,j,nin7)
    3240            0 :                         r7=r*cr7 - s*ci7
    3241            0 :                         s7=r*ci7 + s*cr7
    3242            0 :                         r=zin(1,j,nin8)
    3243            0 :                         s=zin(2,j,nin8)
    3244            0 :                         r8=r*cr8 - s*ci8
    3245            0 :                         s8=r*ci8 + s*cr8
    3246            0 :                         r=r1 + r5
    3247            0 :                         s=r3 + r7
    3248            0 :                         ap=r + s
    3249            0 :                         am=r - s
    3250            0 :                         r=r2 + r6
    3251            0 :                         s=r4 + r8
    3252            0 :                         bp=r + s
    3253            0 :                         bm=r - s
    3254            0 :                         r=s1 + s5
    3255            0 :                         s=s3 + s7
    3256            0 :                         cp=r + s
    3257            0 :                         cm=r - s
    3258            0 :                         r=s2 + s6
    3259            0 :                         s=s4 + s8
    3260            0 :                         dpp=r + s
    3261            0 :                         dm=r - s
    3262            0 :                         zout(1,j,nout1) = ap + bp
    3263            0 :                         zout(2,j,nout1) = cp + dpp
    3264            0 :                         zout(1,j,nout5) = ap - bp
    3265            0 :                         zout(2,j,nout5) = cp - dpp
    3266            0 :                         zout(1,j,nout3) = am + dm
    3267            0 :                         zout(2,j,nout3) = cm - bm
    3268            0 :                         zout(1,j,nout7) = am - dm
    3269            0 :                         zout(2,j,nout7) = cm + bm
    3270            0 :                         r=r1 - r5
    3271            0 :                         s=s3 - s7
    3272            0 :                         ap=r + s
    3273            0 :                         am=r - s
    3274            0 :                         r=s1 - s5
    3275            0 :                         s=r3 - r7
    3276            0 :                         bp=r + s
    3277            0 :                         bm=r - s
    3278            0 :                         r=s4 - s8
    3279            0 :                         s=r2 - r6
    3280            0 :                         cp=r + s
    3281            0 :                         cm=r - s
    3282            0 :                         r=s2 - s6
    3283            0 :                         s=r4 - r8
    3284            0 :                         dpp=r + s
    3285            0 :                         dm=r - s
    3286            0 :                         r = ( cp + dm)*rt2i
    3287            0 :                         s = ( dm - cp)*rt2i
    3288            0 :                         cp= ( cm + dpp)*rt2i
    3289            0 :                         dpp = ( cm - dpp)*rt2i
    3290            0 :                         zout(1,j,nout2) = ap + r
    3291            0 :                         zout(2,j,nout2) = bm + s
    3292            0 :                         zout(1,j,nout6) = ap - r
    3293            0 :                         zout(2,j,nout6) = bm - s
    3294            0 :                         zout(1,j,nout4) = am + cp
    3295            0 :                         zout(2,j,nout4) = bp + dpp
    3296            0 :                         zout(1,j,nout8) = am - cp
    3297            0 :                         zout(2,j,nout8) = bp - dpp
    3298              :                         enddo
    3299              :                         enddo
    3300      7207400 : 8000                continue
    3301              : 
    3302              :         else
    3303      7747878 :                 ia=1
    3304      7747878 :                         nin1=ia-after
    3305      7747878 :                         nout1=ia-atn
    3306     35093008 :                         do ib=1,before
    3307     27345130 :                         nin1=nin1+after
    3308     27345130 :                         nin2=nin1+atb
    3309     27345130 :                         nin3=nin2+atb
    3310     27345130 :                         nin4=nin3+atb
    3311     27345130 :                         nin5=nin4+atb
    3312     27345130 :                         nin6=nin5+atb
    3313     27345130 :                         nin7=nin6+atb
    3314     27345130 :                         nin8=nin7+atb
    3315     27345130 :                         nout1=nout1+atn
    3316     27345130 :                         nout2=nout1+after
    3317     27345130 :                         nout3=nout2+after
    3318     27345130 :                         nout4=nout3+after
    3319     27345130 :                         nout5=nout4+after
    3320     27345130 :                         nout6=nout5+after
    3321     27345130 :                         nout7=nout6+after
    3322     27345130 :                         nout8=nout7+after
    3323    457251574 :                         do j=1,n1dfft
    3324    422158566 :                         r1=zin(1,j,nin1)
    3325    422158566 :                         s1=zin(2,j,nin1)
    3326    422158566 :                         r2=zin(1,j,nin2)
    3327    422158566 :                         s2=zin(2,j,nin2)
    3328    422158566 :                         r3=zin(1,j,nin3)
    3329    422158566 :                         s3=zin(2,j,nin3)
    3330    422158566 :                         r4=zin(1,j,nin4)
    3331    422158566 :                         s4=zin(2,j,nin4)
    3332    422158566 :                         r5=zin(1,j,nin5)
    3333    422158566 :                         s5=zin(2,j,nin5)
    3334    422158566 :                         r6=zin(1,j,nin6)
    3335    422158566 :                         s6=zin(2,j,nin6)
    3336    422158566 :                         r7=zin(1,j,nin7)
    3337    422158566 :                         s7=zin(2,j,nin7)
    3338    422158566 :                         r8=zin(1,j,nin8)
    3339    422158566 :                         s8=zin(2,j,nin8)
    3340    422158566 :                         r=r1 + r5
    3341    422158566 :                         s=r3 + r7
    3342    422158566 :                         ap=r + s
    3343    422158566 :                         am=r - s
    3344    422158566 :                         r=r2 + r6
    3345    422158566 :                         s=r4 + r8
    3346    422158566 :                         bp=r + s
    3347    422158566 :                         bm=r - s
    3348    422158566 :                         r=s1 + s5
    3349    422158566 :                         s=s3 + s7
    3350    422158566 :                         cp=r + s
    3351    422158566 :                         cm=r - s
    3352    422158566 :                         r=s2 + s6
    3353    422158566 :                         s=s4 + s8
    3354    422158566 :                         dpp=r + s
    3355    422158566 :                         dm=r - s
    3356    422158566 :                         zout(1,j,nout1) = ap + bp
    3357    422158566 :                         zout(2,j,nout1) = cp + dpp
    3358    422158566 :                         zout(1,j,nout5) = ap - bp
    3359    422158566 :                         zout(2,j,nout5) = cp - dpp
    3360    422158566 :                         zout(1,j,nout3) = am - dm
    3361    422158566 :                         zout(2,j,nout3) = cm + bm
    3362    422158566 :                         zout(1,j,nout7) = am + dm
    3363    422158566 :                         zout(2,j,nout7) = cm - bm
    3364    422158566 :                         r= r1 - r5
    3365    422158566 :                         s=-s3 + s7
    3366    422158566 :                         ap=r + s
    3367    422158566 :                         am=r - s
    3368    422158566 :                         r=s1 - s5
    3369    422158566 :                         s=r7 - r3
    3370    422158566 :                         bp=r + s
    3371    422158566 :                         bm=r - s
    3372    422158566 :                         r=-s4 + s8
    3373    422158566 :                         s= r2 - r6
    3374    422158566 :                         cp=r + s
    3375    422158566 :                         cm=r - s
    3376    422158566 :                         r=-s2 + s6
    3377    422158566 :                         s= r4 - r8
    3378    422158566 :                         dpp=r + s
    3379    422158566 :                         dm=r - s
    3380    422158566 :                         r = ( cp + dm)*rt2i
    3381    422158566 :                         s = ( cp - dm)*rt2i
    3382    422158566 :                         cp= ( cm + dpp)*rt2i
    3383    422158566 :                         dpp= ( dpp - cm)*rt2i
    3384    422158566 :                         zout(1,j,nout2) = ap + r
    3385    422158566 :                         zout(2,j,nout2) = bm + s
    3386    422158566 :                         zout(1,j,nout6) = ap - r
    3387    422158566 :                         zout(2,j,nout6) = bm - s
    3388    422158566 :                         zout(1,j,nout4) = am + cp
    3389    422158566 :                         zout(2,j,nout4) = bp + dpp
    3390    422158566 :                         zout(1,j,nout8) = am - cp
    3391    449503696 :                         zout(2,j,nout8) = bp - dpp
    3392              :                         enddo
    3393              :                         enddo
    3394              : 
    3395      7747878 :                 do 8001,ia=2,after
    3396            0 :                 ias=ia-1
    3397            0 :                         itt=ias*before
    3398            0 :                         itrig=itt+1
    3399            0 :                         cr2=trig(1,itrig)
    3400            0 :                         ci2=trig(2,itrig)
    3401            0 :                         itrig=itrig+itt
    3402            0 :                         cr3=trig(1,itrig)
    3403            0 :                         ci3=trig(2,itrig)
    3404            0 :                         itrig=itrig+itt
    3405            0 :                         cr4=trig(1,itrig)
    3406            0 :                         ci4=trig(2,itrig)
    3407            0 :                         itrig=itrig+itt
    3408            0 :                         cr5=trig(1,itrig)
    3409            0 :                         ci5=trig(2,itrig)
    3410            0 :                         itrig=itrig+itt
    3411            0 :                         cr6=trig(1,itrig)
    3412            0 :                         ci6=trig(2,itrig)
    3413            0 :                         itrig=itrig+itt
    3414            0 :                         cr7=trig(1,itrig)
    3415            0 :                         ci7=trig(2,itrig)
    3416            0 :                         itrig=itrig+itt
    3417            0 :                         cr8=trig(1,itrig)
    3418            0 :                         ci8=trig(2,itrig)
    3419            0 :                         nin1=ia-after
    3420            0 :                         nout1=ia-atn
    3421            0 :                         do ib=1,before
    3422            0 :                         nin1=nin1+after
    3423            0 :                         nin2=nin1+atb
    3424            0 :                         nin3=nin2+atb
    3425            0 :                         nin4=nin3+atb
    3426            0 :                         nin5=nin4+atb
    3427            0 :                         nin6=nin5+atb
    3428            0 :                         nin7=nin6+atb
    3429            0 :                         nin8=nin7+atb
    3430            0 :                         nout1=nout1+atn
    3431            0 :                         nout2=nout1+after
    3432            0 :                         nout3=nout2+after
    3433            0 :                         nout4=nout3+after
    3434            0 :                         nout5=nout4+after
    3435            0 :                         nout6=nout5+after
    3436            0 :                         nout7=nout6+after
    3437            0 :                         nout8=nout7+after
    3438            0 :                         do j=1,n1dfft
    3439            0 :                         r1=zin(1,j,nin1)
    3440            0 :                         s1=zin(2,j,nin1)
    3441            0 :                         r=zin(1,j,nin2)
    3442            0 :                         s=zin(2,j,nin2)
    3443            0 :                         r2=r*cr2 - s*ci2
    3444            0 :                         s2=r*ci2 + s*cr2
    3445            0 :                         r=zin(1,j,nin3)
    3446            0 :                         s=zin(2,j,nin3)
    3447            0 :                         r3=r*cr3 - s*ci3
    3448            0 :                         s3=r*ci3 + s*cr3
    3449            0 :                         r=zin(1,j,nin4)
    3450            0 :                         s=zin(2,j,nin4)
    3451            0 :                         r4=r*cr4 - s*ci4
    3452            0 :                         s4=r*ci4 + s*cr4
    3453            0 :                         r=zin(1,j,nin5)
    3454            0 :                         s=zin(2,j,nin5)
    3455            0 :                         r5=r*cr5 - s*ci5
    3456            0 :                         s5=r*ci5 + s*cr5
    3457            0 :                         r=zin(1,j,nin6)
    3458            0 :                         s=zin(2,j,nin6)
    3459            0 :                         r6=r*cr6 - s*ci6
    3460            0 :                         s6=r*ci6 + s*cr6
    3461            0 :                         r=zin(1,j,nin7)
    3462            0 :                         s=zin(2,j,nin7)
    3463            0 :                         r7=r*cr7 - s*ci7
    3464            0 :                         s7=r*ci7 + s*cr7
    3465            0 :                         r=zin(1,j,nin8)
    3466            0 :                         s=zin(2,j,nin8)
    3467            0 :                         r8=r*cr8 - s*ci8
    3468            0 :                         s8=r*ci8 + s*cr8
    3469            0 :                         r=r1 + r5
    3470            0 :                         s=r3 + r7
    3471            0 :                         ap=r + s
    3472            0 :                         am=r - s
    3473            0 :                         r=r2 + r6
    3474            0 :                         s=r4 + r8
    3475            0 :                         bp=r + s
    3476            0 :                         bm=r - s
    3477            0 :                         r=s1 + s5
    3478            0 :                         s=s3 + s7
    3479            0 :                         cp=r + s
    3480            0 :                         cm=r - s
    3481            0 :                         r=s2 + s6
    3482            0 :                         s=s4 + s8
    3483            0 :                         dpp=r + s
    3484            0 :                         dm=r - s
    3485            0 :                         zout(1,j,nout1) = ap + bp
    3486            0 :                         zout(2,j,nout1) = cp + dpp
    3487            0 :                         zout(1,j,nout5) = ap - bp
    3488            0 :                         zout(2,j,nout5) = cp - dpp
    3489            0 :                         zout(1,j,nout3) = am - dm
    3490            0 :                         zout(2,j,nout3) = cm + bm
    3491            0 :                         zout(1,j,nout7) = am + dm
    3492            0 :                         zout(2,j,nout7) = cm - bm
    3493            0 :                         r= r1 - r5
    3494            0 :                         s=-s3 + s7
    3495            0 :                         ap=r + s
    3496            0 :                         am=r - s
    3497            0 :                         r=s1 - s5
    3498            0 :                         s=r7 - r3
    3499            0 :                         bp=r + s
    3500            0 :                         bm=r - s
    3501            0 :                         r=-s4 + s8
    3502            0 :                         s= r2 - r6
    3503            0 :                         cp=r + s
    3504            0 :                         cm=r - s
    3505            0 :                         r=-s2 + s6
    3506            0 :                         s= r4 - r8
    3507            0 :                         dpp=r + s
    3508            0 :                         dm=r - s
    3509            0 :                         r = ( cp + dm)*rt2i
    3510            0 :                         s = ( cp - dm)*rt2i
    3511            0 :                         cp= ( cm + dpp)*rt2i
    3512            0 :                         dpp= ( dpp - cm)*rt2i
    3513            0 :                         zout(1,j,nout2) = ap + r
    3514            0 :                         zout(2,j,nout2) = bm + s
    3515            0 :                         zout(1,j,nout6) = ap - r
    3516            0 :                         zout(2,j,nout6) = bm - s
    3517            0 :                         zout(1,j,nout4) = am + cp
    3518            0 :                         zout(2,j,nout4) = bp + dpp
    3519            0 :                         zout(1,j,nout8) = am - cp
    3520            0 :                         zout(2,j,nout8) = bp - dpp
    3521              :                         enddo
    3522              :                         enddo
    3523      7747878 : 8001                continue
    3524              : 
    3525              :         end if
    3526              :         else if (now.eq.3) then
    3527              : !         .5d0*sqrt(3.d0)
    3528     41736144 :         bb=isign*0.8660254037844387d0
    3529     41736144 :         ia=1
    3530     41736144 :         nin1=ia-after
    3531     41736144 :         nout1=ia-atn
    3532     93270558 :         do ib=1,before
    3533     51534414 :         nin1=nin1+after
    3534     51534414 :         nin2=nin1+atb
    3535     51534414 :         nin3=nin2+atb
    3536     51534414 :         nout1=nout1+atn
    3537     51534414 :         nout2=nout1+after
    3538     51534414 :         nout3=nout2+after
    3539    846438502 :         do j=1,n1dfft
    3540    753167944 :         r1=zin(1,j,nin1)
    3541    753167944 :         s1=zin(2,j,nin1)
    3542    753167944 :         r2=zin(1,j,nin2)
    3543    753167944 :         s2=zin(2,j,nin2)
    3544    753167944 :         r3=zin(1,j,nin3)
    3545    753167944 :         s3=zin(2,j,nin3)
    3546    753167944 :         r=r2 + r3
    3547    753167944 :         s=s2 + s3
    3548    753167944 :         zout(1,j,nout1) = r + r1
    3549    753167944 :         zout(2,j,nout1) = s + s1
    3550    753167944 :         r1=r1 - .5d0*r
    3551    753167944 :         s1=s1 - .5d0*s
    3552    753167944 :         r2=bb*(r2-r3)
    3553    753167944 :         s2=bb*(s2-s3)
    3554    753167944 :         zout(1,j,nout2) = r1 - s2
    3555    753167944 :         zout(2,j,nout2) = s1 + r2
    3556    753167944 :         zout(1,j,nout3) = r1 + s2
    3557    804702358 :         zout(2,j,nout3) = s1 - r2
    3558              :         enddo
    3559              :         enddo
    3560    318630604 :         do 3000,ia=2,after
    3561    276894460 :         ias=ia-1
    3562    276894460 :         if (4*ias.eq.3*after) then
    3563     23549312 :         if (isign.eq.1) then
    3564     11848850 :                 nin1=ia-after
    3565     11848850 :                 nout1=ia-atn
    3566     25484104 :                 do ib=1,before
    3567     13635254 :                 nin1=nin1+after
    3568     13635254 :                 nin2=nin1+atb
    3569     13635254 :                 nin3=nin2+atb
    3570     13635254 :                 nout1=nout1+atn
    3571     13635254 :                 nout2=nout1+after
    3572     13635254 :                 nout3=nout2+after
    3573    237245078 :                 do j=1,n1dfft
    3574    211760974 :                 r1=zin(1,j,nin1)
    3575    211760974 :                 s1=zin(2,j,nin1)
    3576    211760974 :                 r2=zin(2,j,nin2)
    3577    211760974 :                 s2=zin(1,j,nin2)
    3578    211760974 :                 r3=zin(1,j,nin3)
    3579    211760974 :                 s3=zin(2,j,nin3)
    3580    211760974 :                 r=r3 + r2
    3581    211760974 :                 s=s2 - s3
    3582    211760974 :                 zout(1,j,nout1) = r1 - r
    3583    211760974 :                 zout(2,j,nout1) = s + s1
    3584    211760974 :                 r1=r1 + .5d0*r
    3585    211760974 :                 s1=s1 - .5d0*s
    3586    211760974 :                 r2=bb*(r2-r3)
    3587    211760974 :                 s2=bb*(s2+s3)
    3588    211760974 :                 zout(1,j,nout2) = r1 - s2
    3589    211760974 :                 zout(2,j,nout2) = s1 - r2
    3590    211760974 :                 zout(1,j,nout3) = r1 + s2
    3591    225396228 :                 zout(2,j,nout3) = s1 + r2
    3592              :                 enddo
    3593              :                 enddo
    3594              :         else
    3595     11700462 :                 nin1=ia-after
    3596     11700462 :                 nout1=ia-atn
    3597     25645650 :                 do ib=1,before
    3598     13945188 :                 nin1=nin1+after
    3599     13945188 :                 nin2=nin1+atb
    3600     13945188 :                 nin3=nin2+atb
    3601     13945188 :                 nout1=nout1+atn
    3602     13945188 :                 nout2=nout1+after
    3603     13945188 :                 nout3=nout2+after
    3604    246406450 :                 do j=1,n1dfft
    3605    220760800 :                 r1=zin(1,j,nin1)
    3606    220760800 :                 s1=zin(2,j,nin1)
    3607    220760800 :                 r2=zin(2,j,nin2)
    3608    220760800 :                 s2=zin(1,j,nin2)
    3609    220760800 :                 r3=zin(1,j,nin3)
    3610    220760800 :                 s3=zin(2,j,nin3)
    3611    220760800 :                 r=r2 - r3
    3612    220760800 :                 s=s2 + s3
    3613    220760800 :                 zout(1,j,nout1) = r + r1
    3614    220760800 :                 zout(2,j,nout1) = s1 - s
    3615    220760800 :                 r1=r1 - .5d0*r
    3616    220760800 :                 s1=s1 + .5d0*s
    3617    220760800 :                 r2=bb*(r2+r3)
    3618    220760800 :                 s2=bb*(s2-s3)
    3619    220760800 :                 zout(1,j,nout2) = r1 + s2
    3620    220760800 :                 zout(2,j,nout2) = s1 + r2
    3621    220760800 :                 zout(1,j,nout3) = r1 - s2
    3622    234705988 :                 zout(2,j,nout3) = s1 - r2
    3623              :                 enddo
    3624              :                 enddo
    3625              :         end if
    3626    253345148 :         else if (8*ias.eq.3*after) then
    3627     16373586 :         if (isign.eq.1) then
    3628      8553538 :                 nin1=ia-after
    3629      8553538 :                 nout1=ia-atn
    3630     17462420 :                 do ib=1,before
    3631      8908882 :                 nin1=nin1+after
    3632      8908882 :                 nin2=nin1+atb
    3633      8908882 :                 nin3=nin2+atb
    3634      8908882 :                 nout1=nout1+atn
    3635      8908882 :                 nout2=nout1+after
    3636      8908882 :                 nout3=nout2+after
    3637    155425926 :                 do j=1,n1dfft
    3638    137963506 :                 r1=zin(1,j,nin1)
    3639    137963506 :                 s1=zin(2,j,nin1)
    3640    137963506 :                 r=zin(1,j,nin2)
    3641    137963506 :                 s=zin(2,j,nin2)
    3642    137963506 :                 r2=(r - s)*rt2i
    3643    137963506 :                 s2=(r + s)*rt2i
    3644    137963506 :                 r3=zin(2,j,nin3)
    3645    137963506 :                 s3=zin(1,j,nin3)
    3646    137963506 :                 r=r2 - r3
    3647    137963506 :                 s=s2 + s3
    3648    137963506 :                 zout(1,j,nout1) = r + r1
    3649    137963506 :                 zout(2,j,nout1) = s + s1
    3650    137963506 :                 r1=r1 - .5d0*r
    3651    137963506 :                 s1=s1 - .5d0*s
    3652    137963506 :                 r2=bb*(r2+r3)
    3653    137963506 :                 s2=bb*(s2-s3)
    3654    137963506 :                 zout(1,j,nout2) = r1 - s2
    3655    137963506 :                 zout(2,j,nout2) = s1 + r2
    3656    137963506 :                 zout(1,j,nout3) = r1 + s2
    3657    146872388 :                 zout(2,j,nout3) = s1 - r2
    3658              :                 enddo
    3659              :                 enddo
    3660              :         else
    3661      7820048 :                 nin1=ia-after
    3662      7820048 :                 nout1=ia-atn
    3663     15842872 :                 do ib=1,before
    3664      8022824 :                 nin1=nin1+after
    3665      8022824 :                 nin2=nin1+atb
    3666      8022824 :                 nin3=nin2+atb
    3667      8022824 :                 nout1=nout1+atn
    3668      8022824 :                 nout2=nout1+after
    3669      8022824 :                 nout3=nout2+after
    3670    141109328 :                 do j=1,n1dfft
    3671    125266456 :                 r1=zin(1,j,nin1)
    3672    125266456 :                 s1=zin(2,j,nin1)
    3673    125266456 :                 r=zin(1,j,nin2)
    3674    125266456 :                 s=zin(2,j,nin2)
    3675    125266456 :                 r2=(r + s)*rt2i
    3676    125266456 :                 s2=(s - r)*rt2i
    3677    125266456 :                 r3=zin(2,j,nin3)
    3678    125266456 :                 s3=zin(1,j,nin3)
    3679    125266456 :                 r=r2 + r3
    3680    125266456 :                 s=s2 - s3
    3681    125266456 :                 zout(1,j,nout1) = r + r1
    3682    125266456 :                 zout(2,j,nout1) = s + s1
    3683    125266456 :                 r1=r1 - .5d0*r
    3684    125266456 :                 s1=s1 - .5d0*s
    3685    125266456 :                 r2=bb*(r2-r3)
    3686    125266456 :                 s2=bb*(s2+s3)
    3687    125266456 :                 zout(1,j,nout2) = r1 - s2
    3688    125266456 :                 zout(2,j,nout2) = s1 + r2
    3689    125266456 :                 zout(1,j,nout3) = r1 + s2
    3690    133289280 :                 zout(2,j,nout3) = s1 - r2
    3691              :                 enddo
    3692              :                 enddo
    3693              :         end if
    3694              :         else
    3695    236971562 :         itt=ias*before
    3696    236971562 :         itrig=itt+1
    3697    236971562 :         cr2=trig(1,itrig)
    3698    236971562 :         ci2=trig(2,itrig)
    3699    236971562 :         itrig=itrig+itt
    3700    236971562 :         cr3=trig(1,itrig)
    3701    236971562 :         ci3=trig(2,itrig)
    3702    236971562 :         nin1=ia-after
    3703    236971562 :         nout1=ia-atn
    3704    485986600 :         do ib=1,before
    3705    249015038 :         nin1=nin1+after
    3706    249015038 :         nin2=nin1+atb
    3707    249015038 :         nin3=nin2+atb
    3708    249015038 :         nout1=nout1+atn
    3709    249015038 :         nout2=nout1+after
    3710    249015038 :         nout3=nout2+after
    3711   4029364594 :         do j=1,n1dfft
    3712   3543377994 :         r1=zin(1,j,nin1)
    3713   3543377994 :         s1=zin(2,j,nin1)
    3714   3543377994 :         r=zin(1,j,nin2)
    3715   3543377994 :         s=zin(2,j,nin2)
    3716   3543377994 :         r2=r*cr2 - s*ci2
    3717   3543377994 :         s2=r*ci2 + s*cr2
    3718   3543377994 :         r=zin(1,j,nin3)
    3719   3543377994 :         s=zin(2,j,nin3)
    3720   3543377994 :         r3=r*cr3 - s*ci3
    3721   3543377994 :         s3=r*ci3 + s*cr3
    3722   3543377994 :         r=r2 + r3
    3723   3543377994 :         s=s2 + s3
    3724   3543377994 :         zout(1,j,nout1) = r + r1
    3725   3543377994 :         zout(2,j,nout1) = s + s1
    3726   3543377994 :         r1=r1 - .5d0*r
    3727   3543377994 :         s1=s1 - .5d0*s
    3728   3543377994 :         r2=bb*(r2-r3)
    3729   3543377994 :         s2=bb*(s2-s3)
    3730   3543377994 :         zout(1,j,nout2) = r1 - s2
    3731   3543377994 :         zout(2,j,nout2) = s1 + r2
    3732   3543377994 :         zout(1,j,nout3) = r1 + s2
    3733   3792393032 :         zout(2,j,nout3) = s1 - r2
    3734              :         enddo
    3735              :         enddo
    3736              :         end if
    3737     41736144 : 3000        continue
    3738              :         else if (now==5) then
    3739              : !         cos(2.d0*pi/5.d0)
    3740     13497133 :         cos2=0.3090169943749474d0
    3741              : !         cos(4.d0*pi/5.d0)
    3742     13497133 :         cos4=-0.8090169943749474d0
    3743              : !        sin(2.d0*pi/5.d0)
    3744     13497133 :         sin2=isign*0.9510565162951536d0
    3745              : !         sin(4.d0*pi/5.d0)
    3746     13497133 :         sin4=isign*0.5877852522924731d0
    3747     13497133 :         ia=1
    3748     13497133 :         nin1=ia-after
    3749     13497133 :         nout1=ia-atn
    3750     81676684 :         do ib=1,before
    3751     68179551 :         nin1=nin1+after
    3752     68179551 :         nin2=nin1+atb
    3753     68179551 :         nin3=nin2+atb
    3754     68179551 :         nin4=nin3+atb
    3755     68179551 :         nin5=nin4+atb
    3756     68179551 :         nout1=nout1+atn
    3757     68179551 :         nout2=nout1+after
    3758     68179551 :         nout3=nout2+after
    3759     68179551 :         nout4=nout3+after
    3760     68179551 :         nout5=nout4+after
    3761    902509152 :         do j=1,n1dfft
    3762    820832468 :         r1=zin(1,j,nin1)
    3763    820832468 :         s1=zin(2,j,nin1)
    3764    820832468 :         r2=zin(1,j,nin2)
    3765    820832468 :         s2=zin(2,j,nin2)
    3766    820832468 :         r3=zin(1,j,nin3)
    3767    820832468 :         s3=zin(2,j,nin3)
    3768    820832468 :         r4=zin(1,j,nin4)
    3769    820832468 :         s4=zin(2,j,nin4)
    3770    820832468 :         r5=zin(1,j,nin5)
    3771    820832468 :         s5=zin(2,j,nin5)
    3772    820832468 :         r25 = r2 + r5
    3773    820832468 :         r34 = r3 + r4
    3774    820832468 :         s25 = s2 - s5
    3775    820832468 :         s34 = s3 - s4
    3776    820832468 :         zout(1,j,nout1) = r1 + r25 + r34
    3777    820832468 :         r = r1 + cos2*r25 + cos4*r34
    3778    820832468 :         s = sin2*s25 + sin4*s34
    3779    820832468 :         zout(1,j,nout2) = r - s
    3780    820832468 :         zout(1,j,nout5) = r + s
    3781    820832468 :         r = r1 + cos4*r25 + cos2*r34
    3782    820832468 :         s = sin4*s25 - sin2*s34
    3783    820832468 :         zout(1,j,nout3) = r - s
    3784    820832468 :         zout(1,j,nout4) = r + s
    3785    820832468 :         r25 = r2 - r5
    3786    820832468 :         r34 = r3 - r4
    3787    820832468 :         s25 = s2 + s5
    3788    820832468 :         s34 = s3 + s4
    3789    820832468 :         zout(2,j,nout1) = s1 + s25 + s34
    3790    820832468 :         r = s1 + cos2*s25 + cos4*s34
    3791    820832468 :         s = sin2*r25 + sin4*r34
    3792    820832468 :         zout(2,j,nout2) = r + s
    3793    820832468 :         zout(2,j,nout5) = r - s
    3794    820832468 :         r = s1 + cos4*s25 + cos2*s34
    3795    820832468 :         s = sin4*r25 - sin2*r34
    3796    820832468 :         zout(2,j,nout3) = r + s
    3797    889012019 :         zout(2,j,nout4) = r - s
    3798              :         enddo
    3799              :         enddo
    3800     25223105 :         do 5000,ia=2,after
    3801     11725972 :         ias=ia-1
    3802     11725972 :         if (8*ias.eq.5*after) then
    3803       360192 :                 if (isign.eq.1) then
    3804       205824 :                         nin1=ia-after
    3805       205824 :                         nout1=ia-atn
    3806       823296 :                         do ib=1,before
    3807       617472 :                         nin1=nin1+after
    3808       617472 :                         nin2=nin1+atb
    3809       617472 :                         nin3=nin2+atb
    3810       617472 :                         nin4=nin3+atb
    3811       617472 :                         nin5=nin4+atb
    3812       617472 :                         nout1=nout1+atn
    3813       617472 :                         nout2=nout1+after
    3814       617472 :                         nout3=nout2+after
    3815       617472 :                         nout4=nout3+after
    3816       617472 :                         nout5=nout4+after
    3817      5525184 :                         do j=1,n1dfft
    3818      4701888 :                         r1=zin(1,j,nin1)
    3819      4701888 :                         s1=zin(2,j,nin1)
    3820      4701888 :                         r=zin(1,j,nin2)
    3821      4701888 :                         s=zin(2,j,nin2)
    3822      4701888 :                         r2=(r - s)*rt2i
    3823      4701888 :                         s2=(r + s)*rt2i
    3824      4701888 :                         r3=zin(2,j,nin3)
    3825      4701888 :                         s3=zin(1,j,nin3)
    3826      4701888 :                         r=zin(1,j,nin4)
    3827      4701888 :                         s=zin(2,j,nin4)
    3828      4701888 :                         r4=(r + s)*rt2i
    3829      4701888 :                         s4=(r - s)*rt2i
    3830      4701888 :                         r5=zin(1,j,nin5)
    3831      4701888 :                         s5=zin(2,j,nin5)
    3832      4701888 :                         r25 = r2 - r5
    3833      4701888 :                         r34 = r3 + r4
    3834      4701888 :                         s25 = s2 + s5
    3835      4701888 :                         s34 = s3 - s4
    3836      4701888 :                         zout(1,j,nout1) = r1 + r25 - r34
    3837      4701888 :                         r = r1 + cos2*r25 - cos4*r34
    3838      4701888 :                         s = sin2*s25 + sin4*s34
    3839      4701888 :                         zout(1,j,nout2) = r - s
    3840      4701888 :                         zout(1,j,nout5) = r + s
    3841      4701888 :                         r = r1 + cos4*r25 - cos2*r34
    3842      4701888 :                         s = sin4*s25 - sin2*s34
    3843      4701888 :                         zout(1,j,nout3) = r - s
    3844      4701888 :                         zout(1,j,nout4) = r + s
    3845      4701888 :                         r25 = r2 + r5
    3846      4701888 :                         r34 = r4 - r3
    3847      4701888 :                         s25 = s2 - s5
    3848      4701888 :                         s34 = s3 + s4
    3849      4701888 :                         zout(2,j,nout1) = s1 + s25 + s34
    3850      4701888 :                         r = s1 + cos2*s25 + cos4*s34
    3851      4701888 :                         s = sin2*r25 + sin4*r34
    3852      4701888 :                         zout(2,j,nout2) = r + s
    3853      4701888 :                         zout(2,j,nout5) = r - s
    3854      4701888 :                         r = s1 + cos4*s25 + cos2*s34
    3855      4701888 :                         s = sin4*r25 - sin2*r34
    3856      4701888 :                         zout(2,j,nout3) = r + s
    3857      5319360 :                         zout(2,j,nout4) = r - s
    3858              :                         enddo
    3859              :                         enddo
    3860              :                 else
    3861       154368 :                         nin1=ia-after
    3862       154368 :                         nout1=ia-atn
    3863       617472 :                         do ib=1,before
    3864       463104 :                         nin1=nin1+after
    3865       463104 :                         nin2=nin1+atb
    3866       463104 :                         nin3=nin2+atb
    3867       463104 :                         nin4=nin3+atb
    3868       463104 :                         nin5=nin4+atb
    3869       463104 :                         nout1=nout1+atn
    3870       463104 :                         nout2=nout1+after
    3871       463104 :                         nout3=nout2+after
    3872       463104 :                         nout4=nout3+after
    3873       463104 :                         nout5=nout4+after
    3874      4143888 :                         do j=1,n1dfft
    3875      3526416 :                         r1=zin(1,j,nin1)
    3876      3526416 :                         s1=zin(2,j,nin1)
    3877      3526416 :                         r=zin(1,j,nin2)
    3878      3526416 :                         s=zin(2,j,nin2)
    3879      3526416 :                         r2=(r + s)*rt2i
    3880      3526416 :                         s2=(s - r)*rt2i
    3881      3526416 :                         r3=zin(2,j,nin3)
    3882      3526416 :                         s3=zin(1,j,nin3)
    3883      3526416 :                         r=zin(1,j,nin4)
    3884      3526416 :                         s=zin(2,j,nin4)
    3885      3526416 :                         r4=(s - r)*rt2i
    3886      3526416 :                         s4=(r + s)*rt2i
    3887      3526416 :                         r5=zin(1,j,nin5)
    3888      3526416 :                         s5=zin(2,j,nin5)
    3889      3526416 :                         r25 = r2 - r5
    3890      3526416 :                         r34 = r3 + r4
    3891      3526416 :                         s25 = s2 + s5
    3892      3526416 :                         s34 = s4 - s3
    3893      3526416 :                         zout(1,j,nout1) = r1 + r25 + r34
    3894      3526416 :                         r = r1 + cos2*r25 + cos4*r34
    3895      3526416 :                         s = sin2*s25 + sin4*s34
    3896      3526416 :                         zout(1,j,nout2) = r - s
    3897      3526416 :                         zout(1,j,nout5) = r + s
    3898      3526416 :                         r = r1 + cos4*r25 + cos2*r34
    3899      3526416 :                         s = sin4*s25 - sin2*s34
    3900      3526416 :                         zout(1,j,nout3) = r - s
    3901      3526416 :                         zout(1,j,nout4) = r + s
    3902      3526416 :                         r25 = r2 + r5
    3903      3526416 :                         r34 = r3 - r4
    3904      3526416 :                         s25 = s2 - s5
    3905      3526416 :                         s34 = s3 + s4
    3906      3526416 :                         zout(2,j,nout1) = s1 + s25 - s34
    3907      3526416 :                         r = s1 + cos2*s25 - cos4*s34
    3908      3526416 :                         s = sin2*r25 + sin4*r34
    3909      3526416 :                         zout(2,j,nout2) = r + s
    3910      3526416 :                         zout(2,j,nout5) = r - s
    3911      3526416 :                         r = s1 + cos4*s25 - cos2*s34
    3912      3526416 :                         s = sin4*r25 - sin2*r34
    3913      3526416 :                         zout(2,j,nout3) = r + s
    3914      3989520 :                         zout(2,j,nout4) = r - s
    3915              :                         enddo
    3916              :                         enddo
    3917              :                 end if
    3918              :         else
    3919     11365780 :                 ias=ia-1
    3920     11365780 :                 itt=ias*before
    3921     11365780 :                 itrig=itt+1
    3922     11365780 :                 cr2=trig(1,itrig)
    3923     11365780 :                 ci2=trig(2,itrig)
    3924     11365780 :                 itrig=itrig+itt
    3925     11365780 :                 cr3=trig(1,itrig)
    3926     11365780 :                 ci3=trig(2,itrig)
    3927     11365780 :                 itrig=itrig+itt
    3928     11365780 :                 cr4=trig(1,itrig)
    3929     11365780 :                 ci4=trig(2,itrig)
    3930     11365780 :                 itrig=itrig+itt
    3931     11365780 :                 cr5=trig(1,itrig)
    3932     11365780 :                 ci5=trig(2,itrig)
    3933     11365780 :                 nin1=ia-after
    3934     11365780 :                 nout1=ia-atn
    3935     39970152 :                 do ib=1,before
    3936     28604372 :                 nin1=nin1+after
    3937     28604372 :                 nin2=nin1+atb
    3938     28604372 :                 nin3=nin2+atb
    3939     28604372 :                 nin4=nin3+atb
    3940     28604372 :                 nin5=nin4+atb
    3941     28604372 :                 nout1=nout1+atn
    3942     28604372 :                 nout2=nout1+after
    3943     28604372 :                 nout3=nout2+after
    3944     28604372 :                 nout4=nout3+after
    3945     28604372 :                 nout5=nout4+after
    3946    360313019 :                 do j=1,n1dfft
    3947    320342867 :                 r1=zin(1,j,nin1)
    3948    320342867 :                 s1=zin(2,j,nin1)
    3949    320342867 :                 r=zin(1,j,nin2)
    3950    320342867 :                 s=zin(2,j,nin2)
    3951    320342867 :                 r2=r*cr2 - s*ci2
    3952    320342867 :                 s2=r*ci2 + s*cr2
    3953    320342867 :                 r=zin(1,j,nin3)
    3954    320342867 :                 s=zin(2,j,nin3)
    3955    320342867 :                 r3=r*cr3 - s*ci3
    3956    320342867 :                 s3=r*ci3 + s*cr3
    3957    320342867 :                 r=zin(1,j,nin4)
    3958    320342867 :                 s=zin(2,j,nin4)
    3959    320342867 :                 r4=r*cr4 - s*ci4
    3960    320342867 :                 s4=r*ci4 + s*cr4
    3961    320342867 :                 r=zin(1,j,nin5)
    3962    320342867 :                 s=zin(2,j,nin5)
    3963    320342867 :                 r5=r*cr5 - s*ci5
    3964    320342867 :                 s5=r*ci5 + s*cr5
    3965    320342867 :                 r25 = r2 + r5
    3966    320342867 :                 r34 = r3 + r4
    3967    320342867 :                 s25 = s2 - s5
    3968    320342867 :                 s34 = s3 - s4
    3969    320342867 :                 zout(1,j,nout1) = r1 + r25 + r34
    3970    320342867 :                 r = r1 + cos2*r25 + cos4*r34
    3971    320342867 :                 s = sin2*s25 + sin4*s34
    3972    320342867 :                 zout(1,j,nout2) = r - s
    3973    320342867 :                 zout(1,j,nout5) = r + s
    3974    320342867 :                 r = r1 + cos4*r25 + cos2*r34
    3975    320342867 :                 s = sin4*s25 - sin2*s34
    3976    320342867 :                 zout(1,j,nout3) = r - s
    3977    320342867 :                 zout(1,j,nout4) = r + s
    3978    320342867 :                 r25 = r2 - r5
    3979    320342867 :                 r34 = r3 - r4
    3980    320342867 :                 s25 = s2 + s5
    3981    320342867 :                 s34 = s3 + s4
    3982    320342867 :                 zout(2,j,nout1) = s1 + s25 + s34
    3983    320342867 :                 r = s1 + cos2*s25 + cos4*s34
    3984    320342867 :                 s = sin2*r25 + sin4*r34
    3985    320342867 :                 zout(2,j,nout2) = r + s
    3986    320342867 :                 zout(2,j,nout5) = r - s
    3987    320342867 :                 r = s1 + cos4*s25 + cos2*s34
    3988    320342867 :                 s = sin4*r25 - sin2*r34
    3989    320342867 :                 zout(2,j,nout3) = r + s
    3990    348947239 :                 zout(2,j,nout4) = r - s
    3991              :                 enddo
    3992              :                 enddo
    3993              :         end if
    3994     13497133 : 5000        continue
    3995              :        else if (now.eq.6) then
    3996              : !         .5d0*sqrt(3.d0)
    3997     15843000 :         bb=isign*0.8660254037844387d0
    3998              : 
    3999     15843000 :         ia=1
    4000     15843000 :         nin1=ia-after
    4001     15843000 :         nout1=ia-atn
    4002     65168744 :         do ib=1,before
    4003     49325744 :         nin1=nin1+after
    4004     49325744 :         nin2=nin1+atb
    4005     49325744 :         nin3=nin2+atb
    4006     49325744 :         nin4=nin3+atb
    4007     49325744 :         nin5=nin4+atb
    4008     49325744 :         nin6=nin5+atb
    4009     49325744 :         nout1=nout1+atn
    4010     49325744 :         nout2=nout1+after
    4011     49325744 :         nout3=nout2+after
    4012     49325744 :         nout4=nout3+after
    4013     49325744 :         nout5=nout4+after
    4014     49325744 :         nout6=nout5+after
    4015    737408051 :         do j=1,n1dfft
    4016    672239307 :         r2=zin(1,j,nin3)
    4017    672239307 :         s2=zin(2,j,nin3)
    4018    672239307 :         r3=zin(1,j,nin5)
    4019    672239307 :         s3=zin(2,j,nin5)
    4020    672239307 :         r=r2 + r3
    4021    672239307 :         s=s2 + s3
    4022    672239307 :         r1=zin(1,j,nin1)
    4023    672239307 :         s1=zin(2,j,nin1)
    4024    672239307 :         ur1 = r + r1
    4025    672239307 :         ui1 = s + s1
    4026    672239307 :         r1=r1 - .5d0*r
    4027    672239307 :         s1=s1 - .5d0*s
    4028    672239307 :         r=r2-r3
    4029    672239307 :         s=s2-s3
    4030    672239307 :         ur2 = r1 - s*bb
    4031    672239307 :         ui2 = s1 + r*bb
    4032    672239307 :         ur3 = r1 + s*bb
    4033    672239307 :         ui3 = s1 - r*bb
    4034              : 
    4035    672239307 :         r2=zin(1,j,nin6)
    4036    672239307 :         s2=zin(2,j,nin6)
    4037    672239307 :         r3=zin(1,j,nin2)
    4038    672239307 :         s3=zin(2,j,nin2)
    4039    672239307 :         r=r2 + r3
    4040    672239307 :         s=s2 + s3
    4041    672239307 :         r1=zin(1,j,nin4)
    4042    672239307 :         s1=zin(2,j,nin4)
    4043    672239307 :         vr1 = r + r1
    4044    672239307 :         vi1 = s + s1
    4045    672239307 :         r1=r1 - .5d0*r
    4046    672239307 :         s1=s1 - .5d0*s
    4047    672239307 :         r=r2-r3
    4048    672239307 :         s=s2-s3
    4049    672239307 :         vr2 = r1 - s*bb
    4050    672239307 :         vi2 = s1 + r*bb
    4051    672239307 :         vr3 = r1 + s*bb
    4052    672239307 :         vi3 = s1 - r*bb
    4053              : 
    4054    672239307 :         zout(1,j,nout1)=ur1+vr1
    4055    672239307 :         zout(2,j,nout1)=ui1+vi1
    4056    672239307 :         zout(1,j,nout5)=ur2+vr2
    4057    672239307 :         zout(2,j,nout5)=ui2+vi2
    4058    672239307 :         zout(1,j,nout3)=ur3+vr3
    4059    672239307 :         zout(2,j,nout3)=ui3+vi3
    4060    672239307 :         zout(1,j,nout4)=ur1-vr1
    4061    672239307 :         zout(2,j,nout4)=ui1-vi1
    4062    672239307 :         zout(1,j,nout2)=ur2-vr2
    4063    672239307 :         zout(2,j,nout2)=ui2-vi2
    4064    672239307 :         zout(1,j,nout6)=ur3-vr3
    4065    721565051 :         zout(2,j,nout6)=ui3-vi3
    4066              :         enddo
    4067              :         enddo
    4068              : 
    4069              :         else
    4070            0 :           ABI_ERROR('error fftstp')
    4071              :         end if
    4072              : 
    4073    117986786 : end subroutine fftstp
    4074              : !!***
    4075              : 
    4076              : end module m_sg2002
    4077              : !!***
        

Generated by: LCOV version 2.3-1