!----------------------------------------------------------------------
!     Copyright (c) 2019--2020 Shin-ichi Takehiro. All rights reserved.
!----------------------------------------------------------------------
!
!表題  ut_mpi_module テストプログラム
!
!      ポロイダルポテンシャルの境界値問題
!
!履歴  2019/06/29  竹広真一
!      2020/11/11  竹広真一  セクター計算オプション導入
!
program ut_mpi_module_polvelbc_grid_mint_test

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

  implicit none

!!$  integer,parameter  :: im=32, jm=16, km=16  ! 格子点の設定(経度, 緯度, 動径)
!!$  integer,parameter  :: mint=1               ! 経度方向対称性
  integer,parameter  :: im=16, jm=16, km=16  ! 格子点の設定(経度, 緯度, 動径)
  integer,parameter  :: mint=2               ! 経度方向対称性
  integer,parameter  :: nm=10, lm=16         ! 切断波数の設定(水平, 動径)
  real(8),parameter  :: ri=0.5, ro=1.5       ! 内外半径

  integer :: npv = 2
  integer :: iproc, np, ierr

  real(8), allocatable :: xvh_Polvel(:,:,:)

  real(8), allocatable :: ut_Polvel(:,:)
  real(8), allocatable :: ut_LaplaPol(:,:)
  real(8), allocatable :: ut_LaplaPol0(:,:)
  real(8), allocatable :: uz_Polvel(:,:)
  real(8), allocatable :: uz_True(:,:)
  real(8), allocatable :: uz_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

  !---------------- MPI スタート ---------------------
  ! call get_ENV_INT('NPV',npv)
  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','ut_mpi_module_polvelbc_mint_grid', &
       'ut_mpi_module_mint Polvelbc(Grid) function tests')

  call ut_mpi_initial(im,jm,km,nm,lm,ri,ro,npv=npv,mint=mint)

  allocate(xvh_Polvel(0:im-1,jc,kc))

  allocate(ut_Polvel(nmc,0:lm))
  allocate(ut_LaplaPol(nmc,0:lm))
  allocate(ut_LaplaPol0(nmc,0:lm))
  allocate(uz_Polvel(nmc,0:km))
  allocate(uz_True(nmc,0:km))
  allocate(uz_Zero(nmc,0:km))

  do l=1,4

     ! P_10
     !xvh_Polvel = sin(xvh_Lat) * sin( pi*(xvh_Rad-ri)/(ro-ri) )
     !xvh_LaplaPol = xvh_ut(ut_Lapla_ut(ut_xvh(xvh_Polvel)))
     !xvh_LaplaPol = sin(xvh_Lat) * sin( pi*(xvh_Rad-ri)/(ro-ri) )
     ! P_2_2
     !xvh_LaplaPol = cos(xvh_Lat)**2*cos(2*xvh_Lon)* sin( pi*(xvh_Rad-ri)/(ro-ri) )
     !xvh_LaplaPol = 2*sin(xvh_Lat)**2 * sin( pi*(xvh_Rad-ri)/(ro-ri) )

     !xvh_Polvel = xvh_wz(wz_LaplaPol2pol_wz(wz_xvh(xvh_LaplaPol),BCond(l)))
     !xvh_Polvel = xvh_ut(ut_LaplaPol2PolGrid_ut(ut_xvh(xvh_LaplaPol),BCond(l)))
     select case (BCOND(l))
     case ('FF')
        xvh_Polvel = sin(xvh_Lat) * (xvh_Rad-ri)**3*(xvh_Rad-ro)**3
     case('FR')
        xvh_Polvel = cos(xvh_lat)**2*cos(2*xvh_lon) * (xvh_Rad-ri)**2*(xvh_Rad-ro)**3
     case('RF')
        xvh_Polvel = 2*sin(xvh_lat)**2 * (xvh_Rad-ri)**3*(xvh_Rad-ro)**2
     case('RR')
        xvh_Polvel = sin(xvh_Lat) * (xvh_Rad-ri)**2*(xvh_Rad-ro)**2
     end select

     ut_LaplaPol  = ut_Lapla_ut(ut_xvh(xvh_Polvel))
     ut_Polvel    = ut_LaplaPol2PolGrid_ut(ut_LaplaPol,BCond(l),new=.true.)
     ut_LaplaPol0 = ut_Lapla_ut(ut_Polvel)
     uz_Polvel    = uz_ut(ut_Polvel)

     uz_Zero = 0.0D0

     !---------------- 内部チェック -----------------------
     call AssertEqual(&
          message='ut_LaplaPol2polGrid_ut (intenal value)',           &
          answer = ut_Laplapol0(:,0:lm-4),                           &
          check = ut_LaplaPol(:,0:lm-4),                             &
          significant_digits = check_digits, ignore_digits = ignore  &
          )

     !--------- 上端境界チェック ----------
     !----- Φ=0 at the top ---------
     call AssertEqual(&
          message='ut_LaplaPol2polGrid_ut (Top B.C. Phi=0)',          &
          answer = uz_Zero(:,0),                                     &
          check = uz_Polvel(:,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
        uz_True = uz_ut(ut_DRad_ut(ut_DRad_ut(ut_Polvel)))
     else
        uz_True = uz_ut(ut_DRad_ut(ut_Polvel))
     endif

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

     !--------- 下端境界チェック ----------
     !----- Φ=0 at the bottom ---------
     call AssertEqual(&
          message='ut_LaplaPol2polGrid_ut (Bottom B.C. Phi=0)',       &
          answer = uz_Zero(:,km),                                    &
          check = uz_Polvel(:,km),                                 &
          significant_digits = check_digits, ignore_digits = ignore  &
          )

     !----- dΦ/dr=0, d^2Φ/dr^2 at the bottom ---------
     if( BCond(l)(2:2) == 'F' ) then
        uz_True = uz_ut(ut_DRad_ut(ut_DRad_ut(ut_Polvel)))
     else
        uz_True = uz_ut(ut_DRad_ut(ut_Polvel))
     endif

     call AssertEqual(&
          message='ut_LaplaPol2polGrid_ut ('//BCond(l)//'-Bottom B.C)',&
          answer = uz_Zero(:,km),                                     &
          check = uz_True(:,km),                                      &
          significant_digits = check_digits, ignore_digits = ignore   &
          )
  end do

  call MessageNotify('M','ut_mpi_module_polvelbc_grid_mint_test', &
       'ut_mpi_module_mint Polvelbc(Grid) function tests suceeded!')

  !------ MPIの終了 ------
  call MPI_FINALIZE(IERR)

end program ut_mpi_module_polvelbc_grid_mint_test
