module wei_bosc
  use wei_util
  use wei_pro
  use wei_fft
  use wei_cps
  !---------------
  implicit none 
contains
  !----------------------------------------------------------------
  integer function weibosc_init() result(st)
#ifdef DEBUG
    character(len=128), parameter :: unit='weibosc_init'
    if(wpro%dbg>0) call in(unit)
#endif

    call weicps_init()

#ifdef DEBUG
    if(wpro%dbg>0) call out(unit)
#endif
    st=weiOK
  end function weibosc_init
  !----------------------------------------------------------------
  !! ===============
  !! forward: dS->dW
  !! ===============
  integer function weibosc_s2w(bwfld,iws,ith,dslow,dwfld,kk,ko) result(st)
    integer, intent(in)                    :: iws,ith
    complex, dimension(:,:,:,:,:), pointer :: dslow,dwfld,bwfld
    real,    dimension(:,:,:,:),   pointer :: kk
    real,    intent(in)                    :: ko

    real    :: w
    complex :: iwdz
#ifdef DEBUG
    character(len=128), parameter :: unit='weibosc_s2w'
    if(wpro%dbg>9) call in(unit)
#endif
    w    = wpro%bw%o + (iws-1)*wpro%bw%d
    iwdz = (0,1)*wpro%opsign*w*wpro%az%d

    dwfld(:,:,:,:,ith) = iwdz * &
    dslow(:,:,:,:,ith)        * &
    bwfld(:,:,:,:,iws)

    call weifft(ith,ith,dwfld)      !!               FFT[W dS]
    call weicps(dwfld,ith,kk,ko)    !!      (dkz/ds) FFT[W dS]
    call weiift(ith,ith,dwfld)      !! IFT[ (dkz/ds) FFT[W dS]]

#ifdef DEBUG
    if(wpro%dbg>9) call out(unit)
#endif
    st=weiOK
  end function weibosc_s2w
  !----------------------------------------------------------------
  !! ================
  !! adjoint:  dS<-dW
  !! ================
  integer function weibosc_w2s(bwfld,iws,ith,dslow,dwfld,kk,ko) result(st)
    integer, intent(in)                    :: iws,ith
    complex, dimension(:,:,:,:,:), pointer :: dslow,dwfld,bwfld
    real,    dimension(:,:,:,:),   pointer :: kk
    real,    intent(in)                    :: ko

    real    :: w
    complex :: iwdz
#ifdef DEBUG
    character(len=128), parameter :: unit='weibosc_w2s'
    if(wpro%dbg>9) call in(unit)
#endif
    w    = wpro%bw%o + (iws-1)*wpro%bw%d
    iwdz = (0,1)*wpro%opsign*w*wpro%az%d

    call weiift(ith,ith,dwfld)      !!               IFT[ dW ]
    call weicps(dwfld,ith,kk,ko)    !!      (dkz/ds) IFT[ dW ]
    call weifft(ith,ith,dwfld)      !! FFT[ (dkz/ds) IFT[ dW ]]

    dslow(:,:,:,:,ith) = iwdz * &
    dwfld(:,:,:,:,ith) * conjg( &
    bwfld(:,:,:,:,iws))

#ifdef DEBUG
    if(wpro%dbg>9) call out(unit)
#endif
    st=weiOK
  end function weibosc_w2s
  !----------------------------------------------------------------
end module wei_bosc
















