!----------------------------------------------------------------------
!     Copyright (c) 2010--2011 Shin-ichi Takehiro. All rights reserved.
!----------------------------------------------------------------------
!
!表題  wtq_mpi_module テストプログラム
!
!      ポロイダルポテンシャルの境界値問題
!
!履歴  2010/04/18  竹広真一   wt_module_sjpack_test_polvelbc.f90 より改造
!      2011/09/14  竹広真一   MPI 並列化
!      2011/09/14  竹広真一   wtq_mpi_module 用に改造
!
program wtq_mpi_module_polvelbc_wt_test

  use dc_message, only : MessageNotify
  use dc_test, only : AssertEqual
  use wtq_mpi_module
  use mpi

  implicit none

  integer,parameter  :: im=32, jm=16         ! 格子点の設定(経度, 緯度, 動径)
  integer,parameter  :: kmo=16, kmi=10       ! 格子点の設定(球殻動径, 球動径)
  integer,parameter  :: nm=10                ! 切断波数の設定(水平)
  integer,parameter  :: lmo=16, lmi=16       ! 切断波数の設定(球殻動径, 球動径)
  real(8),parameter  :: ri=0.5, ro=1.5       ! 内外半径

  real(8), dimension(0:im-1,1:jm,0:kmo)     :: xyz_Poloidal
  real(8), dimension(0:im-1,1:jm,0:kmo)     :: xyz_LaplaPol
  real(8), dimension(0:im-1,1:jm,0:kmo)     :: xyz_LaplaPol1
  real(8), dimension(0:im-1,1:jm,0:kmo)     :: xyz_True
  real(8), dimension(0:im-1,1:jm,0:kmo)     :: xyz_Zero
  character(len=2), dimension(4), parameter :: BCond=(/'FF','FR','RF','RR'/)

  ! 判定誤差設定
  integer, parameter :: check_digits = 9
  integer, parameter :: ignore = -10

  real(8), parameter  :: pi=3.1415926535897932385D0

  integer :: l
  integer :: iproc, np, ierr

 !---------------- MPI スタート ---------------------
  call MPI_INIT(IERR)
  call MPI_COMM_RANK(MPI_COMM_WORLD,IPROC,IERR)
  call MPI_COMM_SIZE(MPI_COMM_WORLD,NP,IERR)

  call MessageNotify('M','wtq_mpi_module_polvelbc_wt_test', &
       'wtq_mpi_module wt_LaplaPol2polGrid_wt function tests')

  call wtq_mpi_Initial(im,jm,kmi,kmo,nm,lmi,lmo,ri,ro)

  do l=1,4

     ! P_10
     xyz_Poloidal = sin(xyz_Lat) * sin( pi*(xyz_Rad-ri)/(ro-ri) )
     xyz_LaplaPol = xyz_wt(wt_Lapla_wt(wt_xyz(xyz_Poloidal)))
     !xyz_LaplaPol = sin(xyz_Lat) * sin( pi*(xyz_Rad-ri)/(ro-ri) )
     ! P_1_1
     !xyz_LaplaPol = cos(xyz_Lat)*cos(xyz_Lon)* sin( pi*(xyz_Rad-ri)/(ro-ri) )
     !xyz_LaplaPol = 2*sin(xyz_Lat)**2 * sin( pi*(xyz_Rad-ri)/(ro-ri) )

     !xyz_Poloidal = xyz_wz(wz_LaplaPol2pol_wz(wz_xyz(xyz_LaplaPol),BCond(l)))
     !xyz_Poloidal = xyz_wt(wt_LaplaPol2PolTau_wt(wt_xyz(xyz_LaplaPol),BCond(l)))

     xyz_Poloidal = xyz_wt(wt_LaplaPol2PolGrid_wt(wt_xyz(xyz_LaplaPol),BCond(l),new=.true.))

     xyz_LaplaPol1 = xyz_wt(wt_Lapla_wt(wt_xyz(xyz_Poloidal)))
     xyz_Zero = 0.0D0

     !---------------- 内部チェック -----------------------
     call AssertEqual(&
          message='wt_LaplaPol2polGrid_wt (intenal value)',             &
          answer = xyz_LaplaPol1(:,:,2:kmo-2),                           &
          check = xyz_LaplaPol(:,:,2:kmo-2),                             &
          significant_digits = check_digits, ignore_digits = ignore     &
          )

     !--------- 上端境界チェック ----------

     !----- Φ=0 at the top ---------
     call AssertEqual(&
          message='wt_LaplaPol2polGrid_wt (Top B.C. Φ=0)',             &
          answer = xyz_Zero(:,:,0),                                     &
          check = xyz_Poloidal(:,:,0),                                  &
          significant_digits = check_digits, ignore_digits = ignore     &
          )

     !----- dΦ/dr=0, d^2Φ/dr^2 at the top ---------
     if( BCond(l)(1:1) == 'F' ) then
        xyz_True = xyz_wt(wt_DRad_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal))))
     else
        xyz_True = xyz_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal)))
     endif

     call AssertEqual(&
          message='wt_LaplaPol2polGrid_wt ('//BCond(l)//'-Top B.C)',    &
          answer = xyz_Zero(:,:,0),                                     &
          check = xyz_True(:,:,0),                                      &
          significant_digits = check_digits, ignore_digits = ignore     &
          )

     !--------- 下端境界チェック ----------

     !----- Φ=0 at the bottom ---------
     call AssertEqual(&
          message='wt_LaplaPol2polGrid_wt (Bottom B.C. Φ=0)',          &
          answer = xyz_Zero(:,:,kmo),                                    &
          check = xyz_Poloidal(:,:,kmo),                                 &
          significant_digits = check_digits, ignore_digits = ignore     &
          )

     !----- dΦ/dr=0, d^2Φ/dr^2 at the bottom ---------
     if( BCond(l)(2:2) == 'F' ) then
        xyz_True = xyz_wt(wt_DRad_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal))))
     else
        xyz_True = xyz_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal)))
     endif

     call AssertEqual(&
          message='wt_LaplaPol2polGrid_wt ('//BCond(l)//'-Bottom B.C)', &
          answer = xyz_Zero(:,:,kmo),                                    &
          check = xyz_True(:,:,kmo),                                     &
          significant_digits = check_digits, ignore_digits = ignore     &
          )

  end do

  call MessageNotify('M','wtq_mpi_module_polvelbc_wt_test', &
       'wtq_mpi_module wt_LaplaPol2polGrid_wt function tests suceeded!')

 !------ MPIの終了 ------

  call MPI_FINALIZE(IERR)

end program wtq_mpi_module_polvelbc_wt_test
