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,pointer,private				:: plan3Fd(:),plan3Id(:)
!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(planF1s(i),1,size(tflds(:,1)),tflds(:,i),tflds(:,i),fftW_FORWARD,fftW_PATIENT)
      call sfftw_plan_dft(planI1s(i),1,size(tflds(:,1)),tflds(:,i),tflds(:,i),fftw_BACKWARD,fftW_PATIENT)
   end do
end subroutine
!----------------------------------------------------------------------------
subroutine owfftexes(tflds,inode)
complex				:: tflds(:)
integer				:: inode

call sfftw_execute(planF1s(inode))
tflds=tflds

end subroutine
!----------------------------------------------------------------------------
subroutine owifftexes(tflds,inode)
complex				:: tflds(:)
integer				:: inode

call sfftw_execute(planI1s(inode))
tflds=tflds
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(planF1r(i),1,size(tfldr(:,1)),tfldr(:,i),tfldr(:,i),fftW_FORWARD,fftW_PATIENT)
      call sfftw_plan_dft(planI1r(i),1,size(tfldr(:,1)),tfldr(:,i),tfldr(:,i),fftw_BACKWARD,fftW_PATIENT)
   end do

end subroutine
!----------------------------------------------------------------------------
subroutine owfftexer(tfldr,inode)
complex				:: tfldr(:)
integer				:: inode

call sfftw_execute(planF1r(inode))
tfldr=tfldr

end subroutine
!----------------------------------------------------------------------------
subroutine owifftexer(tfldr,inode)
complex				:: tfldr(:)
integer				:: inode

call sfftw_execute(planI1r(inode))
tfldr=tfldr

end subroutine
!-------------------------------------------------------------------------
subroutine owfftts(tfldst,nodes)
integer						:: nodes
complex						:: tfldst(:,:)
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(planI1st(nodes))
   do i=1,nodes
      call sfftw_plan_dft(planI1st(i),1,size(tfldst(:,1)),tfldst(:,i),tfldst(:,i),fftW_BACKWARD,fftW_PATIENT)
!      call sfftw_plan_dft(planI1st,1,size(tfldst),tfldst(:),tfldst(:),fftW_FORWARD,fftW_PATIENT)
   end do
end subroutine
!----------------------------------------------------------------------------
subroutine owfftexest(tfldst,inode)
complex				:: tfldst(:)
integer				:: inode

call sfftw_execute(planI1st(inode))
tfldst=tfldst

end subroutine
!-------------------------------------------------------------------------
subroutine owffttr(tfldrt,nodes)
integer						:: nodes
complex						:: tfldrt(:,:)
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(planI1rt(nodes))
   do i=1,nodes
      call sfftw_plan_dft(planI1rt(i),1,size(tfldrt(:,1)),tfldrt(:,i),tfldrt(:,i),fftW_BACKWARD,fftW_PATIENT)
!      call sfftw_plan_dft(planI1rt,1,size(tfldrt(:)),tfldrt(:),tfldrt(:),fftW_FORWARD,fftW_PATIENT)
   end do
end subroutine
!----------------------------------------------------------------------------
subroutine owfftexert(tfldrt,inode)
complex				:: tfldrt(:)
integer				:: inode

call sfftw_execute(planI1rt(inode))
tfldrt=tfldrt

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(4)
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),size(tfld3,4)/)
call sfftw_plan_dft(plan3F,4,ndim,tfld3,tfld3,fftW_FORWARD,fftW_PATIENT)
call sfftw_plan_dft(plan3I,4,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

!------------------------------------------------------------------------------
!------------------------------------------------------------------------------
subroutine owfftw3d(tfld3d,nodes)

complex						:: tfld3d(:,:,:,:,:)
integer						:: ndim(4),nodes,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

ndim=(/size(tfld3d,1),size(tfld3d,2),size(tfld3d,3),size(tfld3d,4)/)
allocate(plan3Fd(nodes),plan3Id(nodes))
do i=1,nodes
   call sfftw_plan_dft(plan3Fd(i),4,ndim,tfld3d(:,:,:,:,i),tfld3d(:,:,:,:,i),fftW_FORWARD,fftW_PATIENT)
   call sfftw_plan_dft(plan3Id(i),4,ndim,tfld3d(:,:,:,:,i),tfld3d(:,:,:,:,i),fftw_BACKWARD,fftW_PATIENT)
end do
end subroutine
!------------------------------------------------------------------------------
subroutine owfft3Fexed(inode)
integer                                 :: inode
call sfftw_execute(plan3Fd(inode))
end subroutine
!------------------------------------------------------------------------------
subroutine owfft3Iexed(inode)
integer                                 :: inode
call sfftw_execute(plan3Id(inode))
end subroutine
!-------------------------------------------------------------------------
subroutine owfftdestroy3d()
call sfftw_destroy_plan(plan3Fd)
call sfftw_destroy_plan(plan3Id)
end subroutine
!------------------------------------------------------------------------------




end module
