module OW_fftw_areal
!--------------------------------------------------
! Setting FFTW plans
!

use OW_type
use OW_parms_areal

implicit none

integer*8,public					:: planFs, planIs,planFr, planIr,planF, planI,plan3F,plan3I
integer*8,pointer,private	   			:: planF1s(:),planI1s(:),planF1r(:),planI1r(:)
integer*8,pointer,private				:: planF1st(:),planF1rt(:),planI1st(:),planI1rt(:)
!integer*8,private					:: planF1st,planF1rt,planI1st,planI1rt

contains
!-----------------------------------------------------------------------------
subroutine owfftw(tfld)

complex						:: tfld(:)

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

call sfftw_plan_dft(planF,1,size(tfld),tfld,tfld,fftW_FORWARD,fftW_PATIENT)
call sfftw_plan_dft(planI,1,size(tfld),tfld,tfld,fftw_BACKWARD,fftW_PATIENT)

end subroutine
!-------------------------------------------------------------------------
subroutine owfftws(tflds,nodes)
integer						:: nodes
complex						:: tflds(:,:,:)
integer						:: i

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

   allocate(planF1s(nodes),planI1s(nodes))
   do i=1,nodes
      call sfftw_plan_dft_2D(planF1s(i),size(tflds(:,1,1)),size(tflds(1,:,1)),tflds(:,:,i),tflds(:,:,i),fftW_FORWARD,fftW_PATIENT)
      call sfftw_plan_dft_2D(planI1s(i),size(tflds(:,1,1)),size(tflds(1,:,1)),tflds(:,:,i),tflds(:,:,i),fftw_BACKWARD,fftW_PATIENT)
   end do
end subroutine
!----------------------------------------------------------------------------
subroutine owfftexes(inode)
integer				:: inode

call sfftw_execute(planF1s(inode))

end subroutine
!----------------------------------------------------------------------------
subroutine owifftexes(inode)
integer				:: inode

call sfftw_execute(planI1s(inode))

end subroutine

!-------------------------------------------------------------------------
subroutine owfftwr(tfldr,nodes)
integer						:: nodes
complex						:: tfldr(:,:,:)
integer						:: i

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

   allocate(planF1r(nodes),planI1r(nodes))
   do i=1,nodes
      call sfftw_plan_dft_2D(planF1r(i),size(tfldr(:,1,1)),size(tfldr(1,:,1)),tfldr(:,:,i),tfldr(:,:,i),fftW_FORWARD,fftW_PATIENT)
      call sfftw_plan_dft_2D(planI1r(i),size(tfldr(:,1,1)),size(tfldr(1,:,1)),tfldr(:,:,i),tfldr(:,:,i),fftw_BACKWARD,fftW_PATIENT)
   end do
end subroutine
!----------------------------------------------------------------------------
subroutine owfftexer(inode)
integer				:: inode

call sfftw_execute(planF1r(inode))

end subroutine
!----------------------------------------------------------------------------
subroutine owifftexer(inode)
integer				:: inode

call sfftw_execute(planI1r(inode))

end subroutine

!----------------------------------------------------------------------------
subroutine owfftdestroy()

!call sfftw_destroy_plan(planF1r)
!call sfftw_destroy_plan(planI1r)
call sfftw_destroy_plan(planF1s)
call sfftw_destroy_plan(planI1s)

end subroutine

!------------------------------------------------------------------------------
subroutine owfftw3(tfld3)

complex						:: tfld3(:,:,:)
integer						:: ndim(3)
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

ndim=(/size(tfld3,1),size(tfld3,2),size(tfld3,3)/)
call sfftw_plan_dft(plan3F,3,ndim,tfld3,tfld3,fftW_FORWARD,fftW_PATIENT)
call sfftw_plan_dft(plan3I,3,ndim,tfld3,tfld3,fftw_BACKWARD,fftW_PATIENT)

end subroutine
!------------------------------------------------------------------------------
subroutine owfft3Fexe(tfld3)
complex				:: tfld3(:,:,:)

call sfftw_execute(plan3F)
tfld3=tfld3

end subroutine
!------------------------------------------------------------------------------
subroutine owfft3Iexe(tfld3)
complex				:: tfld3(:,:,:)

call sfftw_execute(plan3I)
tfld3=tfld3

end subroutine
!-------------------------------------------------------------------------
subroutine owfftdestroy3()

call sfftw_destroy_plan(plan3F)
call sfftw_destroy_plan(plan3I)

end subroutine

!------------------------------------------------------------------------------




end module
