module fft_fftw_mod

  implicit none
  integer, parameter   ::  FFTW_R2HC=0,FTW_HC2R=1,FFTW_DHT=2,FFTW_REDFT00=3,FFTW_REDFT01=4
  integer, parameter   ::  FFTW_REDFT10=5,FFTW_REDFT11=6,FFTW_RODFT00=7,FFTW_RODFT01=8,FFTW_RODFT10=9
  integer, parameter   ::  FFTW_RODFT11=10,FFTW_FORWARD=-1,FFTW_BACKWARD=+1,FFTW_DESTROY_INPUT=1
  integer, parameter   ::  FFTW_UNALIGNED=2,FFTW_CONSERVE_MEMORY=4,FFTW_EXHAUSTIVE=8,FTW_PRESERVE_INPUT=16
  integer, parameter   ::  FFTW_PATIENT=32,FFTW_ESTIMATE=64,FFTW_ESTIMATE_PATIENT=128
  integer, parameter   ::  FFTW_BELIEVE_PCOST=256,FFTW_DFT_R2HC_ICKY=512,FFTW_NONTHREADED_ICKY=1024
  integer, parameter   ::  FFTW_NO_BUFFERING=2048,FFTW_NO_INDIRECT_OP=4096,FFTW_ALLOW_LARGE_GENERIC=8192
  integer, parameter   ::  FFTW_NO_RANK_SPLITS=16384,FFTW_NO_VRANK_SPLITS=32768,FFTW_NO_VRECURSE=65536
  integer*8, pointer,private :: RplanF(:),RplanB(:),SplanF(:),SplanB(:)

contains
  !----------------------------------------------------------------

  subroutine fftw_init_ser(sax,rax)
    !! . . Subroutine to initialize the plans
    complex :: sax(:,:,:),rax(:,:,:)
    integer :: i,ith,n(3)

    n(1)=size(sax,1)
    n(2)=size(sax,2)
    n(3)=size(sax,3)
 
    allocate( RplanF( n(3) ) , RplanB( n(3) ) )
    allocate( SplanF( n(3) ) , SplanB( n(3) ) )

    do i=1,n(3)
       call sfftw_plan_dft(RplanB(i),2,n(1:2),rax(1,1,i),rax(1,1,i),&
                                FFTW_BACKWARD,FFTW_PATIENT)
       call sfftw_plan_dft(RplanF(i),2,n(1:2),rax(1,1,i),rax(1,1,i),&
                                FFTW_FORWARD, FFTW_PATIENT)
       call sfftw_plan_dft(SplanB(i),2,n(1:2),sax(1,1,i),sax(1,1,i),&
                                FFTW_BACKWARD,FFTW_PATIENT)
       call sfftw_plan_dft(SplanF(i),2,n(1:2),sax(1,1,i),sax(1,1,i),&
                                FFTW_FORWARD ,FFTW_PATIENT)
    end do

  end subroutine fftw_init_ser

 

  ! ########################################3
  ! . . 
  ! . . Individual calling plans for SAX&RAX
  
  subroutine RAX_F_fft(rax,id)
    complex, dimension(:,:,:) :: rax
    integer  :: id

    call sfftw_execute(RplanF(id))

  end subroutine RAX_F_fft

  ! ########################################3

  subroutine RAX_B_fft(rax,id)
    complex, dimension(:,:,:) :: rax
    integer  :: id

    call sfftw_execute(RplanB(id))

  end subroutine RAX_B_fft

  ! ########################################3

  subroutine SAX_F_fft(sax,id)
    complex, dimension(:,:,:) :: sax
    integer  :: id

    call sfftw_execute(SplanF(id))

  end subroutine SAX_F_fft

  ! ########################################3

  subroutine SAX_B_fft(sax,id)
    complex, dimension(:,:,:) :: sax
    integer  :: id

    call sfftw_execute(SplanB(id))

  end subroutine SAX_B_fft

end module fft_fftw_mod

