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

  use dc_message, only : MessageNotify
  use dc_test, only : AssertEqual
  use wtq_module

  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_Poloidal_sol
  real(8), dimension(0:im-1,1:jm,0:kmo)     :: xyz_LaplaPol_sol
  real(8), dimension(0:im-1,1:jm,0:kmo)     :: xyz_dPoloidaldz
  real(8), dimension(0:im-1,1:jm,0:kmo)     :: xyz_d2Poloidaldz2
  real(8), dimension(0:im-1,1:jm)           :: xy_Zero=0.0D0

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

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

  call MessageNotify('M','wtq_module_polvelbc_grid_wt_test', &
       'wtq_module wt_LaplaPol2polGrid_wt function tests')

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

  !----- wt_LaplaPol2PolGrid (FF) ------

  ! P_10
  xyz_Poloidal_sol = sin(xyz_Lat) * sin( pi*(xyz_Rad-ri)/(ro-ri) )
  xyz_LaplaPol_sol = xyz_wt(wt_Lapla_wt(wt_xyz(xyz_Poloidal_sol)))
  !xyz_LaplaPol_sol = sin(xyz_Lat) * sin( pi*(xyz_Rad-ri)/(ro-ri) )
  ! P_1_1
  !xyz_LaplaPol_sol = cos(xyz_Lat)*cos(xyz_Lon)* sin( pi*(xyz_Rad-ri)/(ro-ri) )
  !xyz_LaplaPol_sol = 2*sin(xyz_Lat)**2 * sin( pi*(xyz_Rad-ri)/(ro-ri) )
  
  xyz_Poloidal = xyz_wt(wt_LaplaPol2PolGrid_wt(wt_xyz(xyz_LaplaPol_sol),&
                                                  cond='FF',new=.true.))

  xyz_LaplaPol = xyz_wt(wt_Lapla_wt(wt_xyz(xyz_Poloidal)))
  xyz_dPoloidaldz   = xyz_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal)))
  xyz_d2Poloidaldz2 = xyz_wt(wt_DRad_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal))))

  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (FF)',                        &
    answer =xyz_Poloidal_sol,                                     &
    check = xyz_Poloidal,                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (FF, LaplaPol)',              &
    answer =xyz_LaplaPol_sol(:,:,1:kmo),                          &
    check = xyz_LaplaPol(:,:,1:kmo),                              &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (FF, Top)',                   &
    answer =xy_Zero,                                              &
    check = xyz_d2Poloidaldz2(:,:,0),                             &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (FF, Bottom)',                 &
    answer =xy_Zero,                                              &
    check = xyz_d2Poloidaldz2(:,:,kmo),                           &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !----- wt_LaplaPol2PolGrid (RF) ------

  ! P_10
  xyz_Poloidal_sol = sin(xyz_Lat) * (xyz_Rad-ri)**3*(xyz_Rad-ro)**2
  xyz_LaplaPol_sol = xyz_wt(wt_Lapla_wt(wt_xyz(xyz_Poloidal_sol)))
  !xyz_LaplaPol_sol = sin(xyz_Lat) * sin( pi*(xyz_Rad-ri)/(ro-ri) )
  ! P_1_1
  !xyz_LaplaPol_sol = cos(xyz_Lat)*cos(xyz_Lon)* sin( pi*(xyz_Rad-ri)/(ro-ri) )
  !xyz_LaplaPol_sol = 2*sin(xyz_Lat)**2 * sin( pi*(xyz_Rad-ri)/(ro-ri) )
  
  xyz_Poloidal = xyz_wt(wt_LaplaPol2PolGrid_wt(wt_xyz(xyz_LaplaPol_sol),&
                                                  cond='RF',new=.true.))

  xyz_LaplaPol = xyz_wt(wt_Lapla_wt(wt_xyz(xyz_Poloidal)))
  xyz_dPoloidaldz   = xyz_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal)))
  xyz_d2Poloidaldz2 = xyz_wt(wt_DRad_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal))))

  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (RF)',                        &
    answer =xyz_Poloidal_sol,                                     &
    check = xyz_Poloidal,                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (RF, LaplaPol)',              &
    answer =xyz_LaplaPol_sol(:,:,1:kmo),                          &
    check = xyz_LaplaPol(:,:,1:kmo),                              &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (RF, Top)',                   &
    answer =xy_Zero,                                              &
    check = xyz_dPoloidaldz(:,:,0),                               &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (RF, Bottom)',                &
    answer =xy_Zero,                                              &
    check = xyz_d2Poloidaldz2(:,:,kmo),                           &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !----- wt_LaplaPol2PolGrid (FR) ------

  ! P_10
  xyz_Poloidal_sol = sin(xyz_Lat) * (xyz_Rad-ri)**2*(xyz_Rad-ro)**3
  xyz_LaplaPol_sol = xyz_wt(wt_Lapla_wt(wt_xyz(xyz_Poloidal_sol)))
  !xyz_LaplaPol_sol = sin(xyz_Lat) * sin( pi*(xyz_Rad-ri)/(ro-ri) )
  ! P_1_1
  !xyz_LaplaPol_sol = cos(xyz_Lat)*cos(xyz_Lon)* sin( pi*(xyz_Rad-ri)/(ro-ri) )
  !xyz_LaplaPol_sol = 2*sin(xyz_Lat)**2 * sin( pi*(xyz_Rad-ri)/(ro-ri) )
  
  xyz_Poloidal = xyz_wt(wt_LaplaPol2PolGrid_wt(wt_xyz(xyz_LaplaPol_sol),&
                                                  cond='FR',new=.true.))

  xyz_LaplaPol = xyz_wt(wt_Lapla_wt(wt_xyz(xyz_Poloidal)))
  xyz_dPoloidaldz   = xyz_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal)))
  xyz_d2Poloidaldz2 = xyz_wt(wt_DRad_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal))))

  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (FR)',                        &
    answer =xyz_Poloidal_sol,                                     &
    check = xyz_Poloidal,                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (FR, LaplaPol)',              &
    answer =xyz_LaplaPol_sol(:,:,1:kmo),                          &
    check = xyz_LaplaPol(:,:,1:kmo),                              &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (FR, Top)',                   &
    answer =xy_Zero,                                              &
    check = xyz_d2Poloidaldz2(:,:,0),                             &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (FR, Bottom)',                &
    answer =xy_Zero,                                              &
    check = xyz_dPoloidaldz(:,:,kmo),                             &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !----- wt_LaplaPol2PolGrid (RR) ------

  ! P_10
  xyz_Poloidal_sol = sin(xyz_Lat) * (xyz_Rad-ri)**2*(xyz_Rad-ro)**2
  xyz_LaplaPol_sol = xyz_wt(wt_Lapla_wt(wt_xyz(xyz_Poloidal_sol)))
  !xyz_LaplaPol_sol = sin(xyz_Lat) * sin( pi*(xyz_Rad-ri)/(ro-ri) )
  ! P_1_1
  !xyz_LaplaPol_sol = cos(xyz_Lat)*cos(xyz_Lon)* sin( pi*(xyz_Rad-ri)/(ro-ri) )
  !xyz_LaplaPol_sol = 2*sin(xyz_Lat)**2 * sin( pi*(xyz_Rad-ri)/(ro-ri) )
  
  xyz_Poloidal = xyz_wt(wt_LaplaPol2PolGrid_wt(wt_xyz(xyz_LaplaPol_sol),&
                                                  cond='RR',new=.true.))

  xyz_LaplaPol = xyz_wt(wt_Lapla_wt(wt_xyz(xyz_Poloidal)))
  xyz_dPoloidaldz   = xyz_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal)))
  xyz_d2Poloidaldz2 = xyz_wt(wt_DRad_wt(wt_DRad_wt(wt_xyz(xyz_Poloidal))))

  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (RR)',                        &
    answer =xyz_Poloidal_sol,                                     &
    check = xyz_Poloidal,                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (RR, LaplaPol)',              &
    answer =xyz_LaplaPol_sol(:,:,1:kmo),                          &
    check = xyz_LaplaPol(:,:,1:kmo),                              &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (RR, Top)',                   &
    answer =xy_Zero,                                              &
    check = xyz_dPoloidaldz(:,:,0),                               &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='wt_LaplaPol2PolGrid_wt (RR, Bottom)',                &
    answer =xy_Zero,                                              &
    check = xyz_dPoloidaldz(:,:,kmo),                             &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call MessageNotify('M','wtq_module_polvelbc_grid_wt_test', &
       'wtq_module wt_LaplaPol2polGrid_wt function tests suceeded!')

end program wtq_module_polvelbc_grid_wt
