!----------------------------------------------------------------------
!     Copyright (c) 2009--2011 Shin-ichi Takehiro. All rights reserved.
!----------------------------------------------------------------------
!
!表題  wtq_mpi_module テストプログラム
!
!      トロイダルポロイダル関係微分関数のテスト
!  
!履歴  2010/04/18  竹広真一   wt_module_sjpack_deriv_test2.f90 より改造
!      2011/09/13  竹広真一   MPI 並列化
!      2011/09/14  竹広真一   wtq_mpi_module 用に改造
!
program wtq_mpi_module_derivative_wt2

  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=21       ! 格子点の設定(球殻動径, 球動径)
  integer,parameter  :: nm=10                ! 切断波数の設定(水平)
  integer,parameter  :: lmo=10, lmi=32       ! 切断波数の設定(球殻動径, 球動径)
  real(8),parameter  :: ri=0.5, ro=1.5       ! 内外半径

  ! 判定誤差設定
  integer, parameter :: check_digits = 5
  integer, parameter :: ignore = -6

  real(8), dimension(0:im-1,jm,0:kmo)     :: xyz_DData
  real(8), dimension(0:im-1,jm,0:kmo)     :: xyz_Psi
  real(8), dimension((nm+1)**2,0:lmo)     :: wt_Psi
  real(8), dimension((nm+1)**2,0:lmo)     :: wt_Phi

  real(8), dimension(0:im-1,jm,0:kmo)     :: xyz_VLon
  real(8), dimension(0:im-1,jm,0:kmo)     :: xyz_VLat
  real(8), dimension(0:im-1,jm,0:kmo)     :: xyz_VRad
  real(8), dimension(0:im-1,jm,0:kmo)     :: xyz_RadRot
  real(8), dimension(0:im-1,jm,0:kmo)     :: xyz_RadRotRot

  real(8), allocatable     :: xvz_DData(:,:,:)
  real(8), allocatable     :: xvz_Psi(:,:,:)

  real(8), allocatable     :: xvz_VLon(:,:,:)
  real(8), allocatable     :: xvz_VLat(:,:,:)
  real(8), allocatable     :: xvz_VRad(:,:,:)
  real(8), allocatable     :: xvz_RadRot(:,:,:)
  real(8), allocatable     :: xvz_RadRotRot(:,:,:)

  integer, parameter :: n=2
  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_derivative_wt_test2', &
       'wtq_mpi_module wt-derivative function test #2')

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

  allocate(xvz_DData(0:im-1,1:jc,0:kmo))
  allocate(xvz_Psi(0:im-1,1:jc,0:kmo))

  allocate(xvz_VLon(0:im-1,1:jc,0:kmo))
  allocate(xvz_VLat(0:im-1,1:jc,0:kmo))
  allocate(xvz_VRad(0:im-1,1:jc,0:kmo))
  allocate(xvz_RadRot(0:im-1,1:jc,0:kmo))
  allocate(xvz_RadRotRot(0:im-1,1:jc,0:kmo))

  !========== wt_KxRGrad_wt, xyz_KGrad_wt, wt_QOperator_wt ==========

  ! ----------------- 例 1 --------------------
  xyz_Psi = xyz_rad**n * cos(xyz_lat)*sin(xyz_lon)   ! r**2 Y_1^-1
  xvz_Psi = xvz_rad**n * cos(xvz_lat)*sin(xvz_lon)   ! r**2 Y_1^-1

  xyz_DData = xyz_rad**n * cos(xyz_lat)*cos(xyz_lon)
  call AssertEqual(&
       message='wt_KxRGrad_wt with r^2 Y_1^-1',                      &
       answer = xyz_DData,                                           &
       check = xyz_wt(wt_KxRGrad_wt(wt_xyz(xyz_Psi))),               &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = xvz_rad**n * cos(xvz_lat)*cos(xvz_lon)
  call AssertEqual(&
       message='wt_KxRGrad_wt with r^2 Y_1^-1',                      &
       answer = xvz_DData,                                           &
       check = xvz_wt(wt_KxRGrad_wt(wt_xvz(xvz_Psi))),               &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  ! k ・▽ r**n Y_1^1 = (n-1)*r**(n-1)* Y_2^1
  xyz_DData = (n-1)*xyz_rad**(n-1)* cos(xyz_lat)*sin(xyz_lat)*sin(xyz_lon) 
  call AssertEqual(&
       message='xyz_KGrad_wt with r^2 Y_1^-1',                       &
       answer = xyz_DData,                                           &
       check = xyz_KGrad_wt(wt_xyz(xyz_Psi)),                        &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = (n-1)*xvz_rad**(n-1)* cos(xvz_lat)*sin(xvz_lat)*sin(xvz_lon) 
  call AssertEqual(&
       message='xvz_KGrad_wt with r^2 Y_1^-1',                       &
       answer = xvz_DData,                                           &
       check = xvz_KGrad_wt(wt_xvz(xvz_Psi)),                        &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  ! Q r**n Y_1^1 = -3*(n-1)*r**(n-1)* Y_2^1
  xyz_DData = - 3*(n-1)*xyz_rad**(n-1)* cos(xyz_lat)*sin(xyz_lat)*sin(xyz_lon) 
  call AssertEqual(&
       message='wt_QOperator_wt r^2 Y_1^-1',                         &
       answer = xyz_DData,                                           &
       check = xyz_wt(wt_QOperator_wt(wt_xyz(xyz_Psi))),             &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = - 3*(n-1)*xvz_rad**(n-1)* cos(xvz_lat)*sin(xvz_lat)*sin(xvz_lon) 
  call AssertEqual(&
       message='wt_QOperator_wt r^2 Y_1^-1',                         &
       answer = xvz_DData,                                           &
       check = xvz_wt(wt_QOperator_wt(wt_xvz(xvz_Psi))),             &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

! ----------------- 例 2 --------------------
  xyz_Psi = cos(xyz_lat)*sin(xyz_lat) * sin(xyz_lon) ! Y_2^1
  xvz_Psi = cos(xvz_lat)*sin(xvz_lat) * sin(xvz_lon) ! Y_2^1

  xyz_DData = cos(xyz_lat)*sin(xyz_lat) * cos(xyz_lon) ! Y_2^1
  call AssertEqual(&
       message='wt_KxRGrad_wt with Y_2^1',                           &
       answer = xyz_DData,                                           &
       check = xyz_wt(wt_KxRGrad_wt(wt_xyz(xyz_Psi))),               &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = cos(xvz_lat)*sin(xvz_lat) * cos(xvz_lon) ! Y_2^1
  call AssertEqual(&
       message='wt_KxRGrad_wt with Y_2^1',                           &
       answer = xvz_DData,                                           &
       check = xvz_wt(wt_KxRGrad_wt(wt_xvz(xvz_Psi))),               &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  ! k・▽ Y_2^1 = (- 4 Y_3^1 / 15 - Y_1^1 /5) 
  xyz_DData = cos(2*xyz_lat)*cos(xyz_lat)*sin(xyz_lon)/xyz_rad
  call AssertEqual(&
       message='xyz_KGrad_wt with Y_2^1',                            &
       answer = xyz_DData,                                           &
       check = xyz_KGrad_wt(wt_xyz(xyz_Psi)),                        &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = cos(2*xvz_lat)*cos(xvz_lat)*sin(xvz_lon)/xvz_rad
  call AssertEqual(&
       message='xvz_KGrad_wt with Y_2^1',                            &
       answer = xvz_DData,                                           &
       check = xvz_KGrad_wt(wt_xvz(xvz_Psi)),                        &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = (16*sin(xyz_Lat)**2 - 5)*cos(xyz_Lat)*sin(xyz_Lon)/xyz_Rad
  call AssertEqual(&
       message='wt_QOperator_wt Y_2^1',                              &
       answer = xyz_DData,                                           &
       check = xyz_wt(wt_QOperator_wt(wt_xyz(xyz_Psi))),             &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = (16*sin(xvz_Lat)**2 - 5)*cos(xvz_Lat)*sin(xvz_Lon)/xvz_Rad
  call AssertEqual(&
       message='wt_QOperator_wt Y_2^1',                              &
       answer = xvz_DData,                                           &
       check = xvz_wt(wt_QOperator_wt(wt_xvz(xvz_Psi))),             &
       significant_digits = check_digits, ignore_digits = ignore     &
       )


  !========== wt_RadRot_xyz_xyz, wt_RadRotRot_xyz_xyz_xyz ==========

  !---------- 単純流れ v_r=r ----------
  xyz_VLon = 0 ; xyz_VLat = 0 ; xyz_VRad = xyz_Rad
  xyz_RadRot = 0 ; xyz_RadRotRot = 0

  xvz_VLon = 0 ; xvz_VLat = 0 ; xvz_VRad = xvz_Rad
  xvz_RadRot = 0 ; xvz_RadRotRot = 0

  call AssertEqual(&
       message='wt_RadRot_xyz_xyz with v_r=r',                       &
       answer = xyz_RadRot,                                          &
       check = xyz_wt(wt_RadRot_xyz_xyz(xyz_VLon,xyz_VLat)),         &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRotRot_xyz_xyz with v_r=r',                    &
       answer = xyz_RadRotRot,                                       &
       check = xyz_wt(wt_RadRotRot_xyz_xyz_xyz(xyz_VLon,xyz_VLat,xyz_VRad)), &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRot_xvz_xvz with v_r=r',                       &
       answer = xvz_RadRot,                                          &
       check = xvz_wt(wt_RadRot_xvz_xvz(xvz_VLon,xvz_VLat)),         &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRotRot_xvz_xvz with v_r=r',                    &
       answer = xvz_RadRotRot,                                       &
       check = xvz_wt(wt_RadRotRot_xvz_xvz_xvz(xvz_VLon,xvz_VLat,xvz_VRad)), &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  !---------- 剛体回転解非線形項(東西流れ) ----------
  xyz_VLon = 0
  xyz_VLat = xyz_Rad*sin(xyz_Lat)*cos(xyz_Lat)
  xyz_VRad = -xyz_Rad*cos(xyz_Lat)**2

  xvz_VLon = 0
  xvz_VLat = xvz_Rad*sin(xvz_Lat)*cos(xvz_Lat)
  xvz_VRad = -xvz_Rad*cos(xvz_Lat)**2

  xyz_RadRot = 0 ; xyz_RadRotRot = 0
  xvz_RadRot = 0 ; xvz_RadRotRot = 0

  call AssertEqual(&
       message='wt_RadRot_xyz_xyz with rigid rotation(E-W)',         &
       answer = xyz_RadRot,                                          &
       check = xyz_wt(wt_RadRot_xyz_xyz(xyz_VLon,xyz_VLat)),         &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRotRot_xyz_xyz with rigid rotation(E-W)',      &
       answer = xyz_RadRotRot,                                       &
       check = xyz_wt(wt_RadRotRot_xyz_xyz_xyz(xyz_VLon,xyz_VLat,xyz_VRad)), &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRot_xvz_xvz with rigid rotation(E-W)',         &
       answer = xvz_RadRot,                                          &
       check = xvz_wt(wt_RadRot_xvz_xvz(xvz_VLon,xvz_VLat)),         &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRotRot_xvz_xvz with rigid rotation(E-W)',      &
       answer = xvz_RadRotRot,                                       &
       check = xvz_wt(wt_RadRotRot_xvz_xvz_xvz(xvz_VLon,xvz_VLat,xvz_VRad)), &
       significant_digits = check_digits, ignore_digits = ignore     &
       )


  !---------- 剛体回転解非線形項(南北流れ) ----------
  xyz_VLon = xyz_Rad*cos(xyz_Lat)*sin(xyz_Lon)*cos(xyz_Lon)
  xyz_VLat = -xyz_Rad*sin(xyz_Lat)*cos(xyz_Lat)*sin(xyz_Lon)**2
  xyz_VRad = -xyz_Rad*(sin(xyz_Lat)**2*sin(xyz_Lon)**2 + cos(xyz_Lon)**2)
  xyz_RadRot = 0 ; xyz_RadRotRot = 0

  xvz_VLon = xvz_Rad*cos(xvz_Lat)*sin(xvz_Lon)*cos(xvz_Lon)
  xvz_VLat = -xvz_Rad*sin(xvz_Lat)*cos(xvz_Lat)*sin(xvz_Lon)**2
  xvz_VRad = -xvz_Rad*(sin(xvz_Lat)**2*sin(xvz_Lon)**2 + cos(xvz_Lon)**2)
  xvz_RadRot = 0 ; xvz_RadRotRot = 0

  call AssertEqual(&
      message='wt_RadRot_xyz_xyz with rigid rotation(N-S)',          &
       answer = xyz_RadRot,                                          &
       check = xyz_wt(wt_RadRot_xyz_xyz(xyz_VLon,xyz_VLat)),         &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRotRot_xyz_xyz with rigid rotation(N-S)',      &
       answer = xyz_RadRotRot,                                       &
       check = xyz_wt(wt_RadRotRot_xyz_xyz_xyz(xyz_VLon,xyz_VLat,xyz_VRad)), &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
      message='wt_RadRot_xvz_xvz with rigid rotation(N-S)',          &
       answer = xvz_RadRot,                                          &
       check = xvz_wt(wt_RadRot_xvz_xvz(xvz_VLon,xvz_VLat)),         &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRotRot_xvz_xvz with rigid rotation(N-S)',      &
       answer = xvz_RadRotRot,                                       &
       check = xvz_wt(wt_RadRotRot_xvz_xvz_xvz(xvz_VLon,xvz_VLat,xvz_VRad)), &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  !--------- 鉛直渦度を伴うベクトル場 ----------
  xyz_Psi = xyz_Rad**2 * cos(xyz_Lat)*sin(xyz_Lon)   ! r**2 P_1^1
  xvz_Psi = xvz_Rad**2 * cos(xvz_Lat)*sin(xvz_Lon)   ! r**2 P_1^1
  !xyz_Psi = xyz_Rad**2 * cos(xyz_Lat)*sin(xyz_Lat)*sin(xyz_Lon)   ! r**2 P_2^1

  xyz_VLon =   xyz_gRadLat_wt(wt_xyz(xyz_Psi*xyz_Rad))
  xyz_VLat = - xyz_gRadLon_wt(wt_xyz(xyz_Psi*xyz_Rad))
  xyz_VRad = 0
  xyz_RadRot = 2 * xyz_Psi                           ! r・▽×▽×(ψr) = L_2ψ
  !xyz_RadRot = 6 * xyz_Psi                           ! r・▽×▽×(ψr) = L_2ψ
  xyz_RadRotRot = 0

  xvz_VLon =   xvz_gRadLat_wt(wt_xvz(xvz_Psi*xvz_Rad))
  xvz_VLat = - xvz_gRadLon_wt(wt_xvz(xvz_Psi*xvz_Rad))
  xvz_VRad = 0
  xvz_RadRot = 2 * xvz_Psi                           ! r・▽×▽×(ψr) = L_2ψ
  !xvz_RadRot = 6 * xvz_Psi                           ! r・▽×▽×(ψr) = L_2ψ
  xvz_RadRotRot = 0

  call AssertEqual(&
      message='wt_RadRot_xyz_xyz with r^2 Y_1^-1 toroidal field',    &
       answer = xyz_RadRot,                                          &
       check = xyz_wt(wt_RadRot_xyz_xyz(xyz_VLon,xyz_VLat)),         &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRotRot_xyz_xyz with r^2 Y_1^-1 toroidal field',&
       answer = xyz_RadRotRot,                                       &
       check = xyz_wt(wt_RadRotRot_xyz_xyz_xyz(xyz_VLon,xyz_VLat,xyz_VRad)), &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
      message='wt_RadRot_xvz_xvz with r^2 Y_1^-1 toroidal field',    &
       answer = xvz_RadRot,                                          &
       check = xvz_wt(wt_RadRot_xvz_xvz(xvz_VLon,xvz_VLat)),         &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRotRot_xvz_xvz with r^2 Y_1^-1 toroidal field',&
       answer = xvz_RadRotRot,                                       &
       check = xvz_wt(wt_RadRotRot_xvz_xvz_xvz(xvz_VLon,xvz_VLat,xvz_VRad)), &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  !---------- 鉛直速度を伴うベクトル場 -----------
  xyz_VRad = xyz_wt(wt_l2_wt(wt_xyz(xyz_Psi/xyz_Rad)))
  xyz_VLat = xyz_gRadLat_wt(wt_dRad_wt(wt_xyz(xyz_Psi*xyz_Rad)))
  xyz_VLon = xyz_gRadLon_wt(wt_dRad_wt(wt_xyz(xyz_Psi*xyz_Rad)))

  xyz_RadRot = 0
  xyz_RadRotRot = -xyz_wt(wt_l2_wt(wt_lapla_wt(wt_xyz(xyz_Psi))))
                 ! r・▽×▽×▽×▽×(ψr) = -L_2▽^2ψ

  xvz_VRad = xvz_wt(wt_l2_wt(wt_xvz(xvz_Psi/xvz_Rad)))
  xvz_VLat = xvz_gRadLat_wt(wt_dRad_wt(wt_xvz(xvz_Psi*xvz_Rad)))
  xvz_VLon = xvz_gRadLon_wt(wt_dRad_wt(wt_xvz(xvz_Psi*xvz_Rad)))

  xvz_RadRot = 0
  xvz_RadRotRot = -xvz_wt(wt_l2_wt(wt_lapla_wt(wt_xvz(xvz_Psi))))
                 ! r・▽×▽×▽×▽×(ψr) = -L_2▽^2ψ

  call AssertEqual(&
      message='wt_RadRot_xyz_xyz with non-vortical field',           &
       answer = xyz_RadRot,                                          &
       check = xyz_wt(wt_RadRot_xyz_xyz(xyz_VLon,xyz_VLat)),         &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRotRot_xyz_xyz with r^2 Y_1^-1 toroidal field',&
       answer = xyz_RadRotRot,                                       &
       check = xyz_wt(wt_RadRotRot_xyz_xyz_xyz(xyz_VLon,xyz_VLat,xyz_VRad)), &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
      message='wt_RadRot_xvz_xvz with non-vortical field',           &
       answer = xvz_RadRot,                                          &
       check = xvz_wt(wt_RadRot_xvz_xvz(xvz_VLon,xvz_VLat)),         &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call AssertEqual(&
       message='wt_RadRotRot_xvz_xvz with r^2 Y_1^-1 toroidal field',&
       answer = xvz_RadRotRot,                                       &
       check = xvz_wt(wt_RadRotRot_xvz_xvz_xvz(xvz_VLon,xvz_VLat,xvz_VRad)), &
       significant_digits = check_digits, ignore_digits = ignore     &
       )


  !========== wt_Potential2Vector, wt_Potential2Rotation ==========

  !----------------- 剛体回転場 --------------------
  ! 
  wt_Psi = wt_xyz(xyz_Rad * sin(xyz_Lat))
  wt_Phi = 0.0D0

  call wt_Potential2Vector(&
       xyz_VLon,xyz_VLat,xyz_VRad, wt_Psi, wt_Phi )

  call wt_Potential2VectorMPI(&
       xvz_VLon,xvz_VLat,xvz_VRad, wt_Psi, wt_Phi )

  xyz_DData = xyz_Rad * cos(xyz_Lat)
  call AssertEqual(&
      message='wt_Potential2Vector (Lon) with rigid rotation field(E-W)', &
       answer = xyz_VLon,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = xvz_Rad * cos(xvz_Lat)
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Lon) with rigid rotation field(E-W)', &
       answer = xvz_VLon,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2Vector (Lat) with rigid rotation field(E-W)', &
       answer = xyz_VLat,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Lat) with rigid rotation field(E-W)', &
       answer = xvz_VLat,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2Vector (Rad) with rigid rotation field(E-W)', &
       answer = xyz_VRad,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Rad) with rigid rotation field(E-W)', &
       answer = xvz_VRad,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call wt_Potential2Rotation(&
       xyz_VLon,xyz_VLat,xyz_VRad, wt_Psi, wt_Phi )
  call wt_Potential2RotationMPI(&
       xvz_VLon,xvz_VLat,xvz_VRad, wt_Psi, wt_Phi )

  xyz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2Rotation (Lon) with rigid rotation field(E-W)', &
       answer = xyz_VLon,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Lon) with rigid rotation field(E-W)', &
       answer = xvz_VLon,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 2*cos(xyz_LAT)
  call AssertEqual(&
      message='wt_Potential2Rotation (Lat) with rigid rotation field(E-W)', &
       answer = xyz_VLat,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 2*cos(xvz_LAT)
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Lat) with rigid rotation field(E-W)', &
       answer = xvz_VLat,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 2*sin(xyz_LAT)
  call AssertEqual(&
      message='wt_Potential2Rotation (Rad) with rigid rotation field(E-W)', &
       answer = xyz_VRad,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 2*sin(xvz_LAT)
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Rad) with rigid rotation field(E-W)', &
       answer = xvz_VRad,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  !----------------- 剛体回転場(南北流) --------------------
  ! 
  wt_Psi = wt_xyz(xyz_Rad * cos(xyz_Lat) * sin(xyz_Lon))
  wt_Phi = 0.0D0

  call wt_Potential2Vector(&
       xyz_VLon,xyz_VLat,xyz_VRad, wt_Psi, wt_Phi )
  call wt_Potential2VectorMPI(&
       xvz_VLon,xvz_VLat,xvz_VRad, wt_Psi, wt_Phi )

  xyz_DData = -xyz_Rad*sin(xyz_Lat)*sin(xyz_Lon)
  call AssertEqual(&
      message='wt_Potential2Vector (Lon) with rigid rotation field(N-S)', &
       answer = xyz_VLon,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = -xvz_Rad*sin(xvz_Lat)*sin(xvz_Lon)
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Lon) with rigid rotation field(N-S)', &
       answer = xvz_VLon,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = -xyz_Rad*cos(xyz_Lon)
  call AssertEqual(&
      message='wt_Potential2Vector (Lat) with rigid rotation field(N-S)', &
       answer = xyz_VLat,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = -xvz_Rad*cos(xvz_Lon)
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Lat) with rigid rotation field(N-S)', &
       answer = xvz_VLat,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Rad) with rigid rotation field(N-S)', &
       answer = xyz_VRad,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Rad) with rigid rotation field(N-S)', &
       answer = xvz_VRad,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call wt_Potential2Rotation(&
       xyz_VLon,xyz_VLat,xyz_VRad, wt_Psi, wt_Phi )
  call wt_Potential2RotationMPI(&
       xvz_VLon,xvz_VLat,xvz_VRad, wt_Psi, wt_Phi )

  xyz_DData = 2*cos(xyz_Lon)
  call AssertEqual(&
      message='wt_Potential2Rotation (Lon) with rigid rotation field(N-S)', &
       answer = xyz_VLon,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 2*cos(xvz_Lon)
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Lon) with rigid rotation field(N-S)', &
       answer = xvz_VLon,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = -2*sin(xyz_Lon)*sin(xyz_Lat)
  call AssertEqual(&
      message='wt_Potential2Rotation (Lat) with rigid rotation field(N-S)', &
       answer = xyz_VLat,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = -2*sin(xvz_Lon)*sin(xvz_Lat)
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Lat) with rigid rotation field(N-S)', &
       answer = xvz_VLat,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 2*sin(xyz_Lon)*cos(xyz_Lat)
  call AssertEqual(&
      message='wt_Potential2Rotation (Rad) with rigid rotation field(N-S)', &
       answer = xyz_VRad,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 2*sin(xvz_Lon)*cos(xvz_Lat)
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Rad) with rigid rotation field(N-S)', &
       answer = xvz_VRad,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  ! ----------------- 渦無し場 --------------------
  wt_Psi = 0.0D0
  wt_Phi = wt_xyz(xyz_Rad * sin(xyz_Lat))

  call wt_Potential2Vector(&
       xyz_VLon,xyz_VLat,xyz_VRad, wt_Psi, wt_Phi )
  call wt_Potential2VectorMPI(&
       xvz_VLon,xvz_VLat,xvz_VRad, wt_Psi, wt_Phi )

  xyz_DData = 0
  call AssertEqual(&
       message='wt_Potential2Vector (Lon) with non-vortical field',  &
       answer = xyz_VLon,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 0
  call AssertEqual(&
       message='wt_Potential2VectorMPI (Lon) with non-vortical field',  &
       answer = xvz_VLon,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 2 * cos(xyz_Lat)
  call AssertEqual(&
       message='wt_Potential2Vector (Lat) with non-vortical field',  &
       answer = xyz_VLat,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 2 * cos(xvz_Lat)
  call AssertEqual(&
       message='wt_Potential2VectorMPI (Lat) with non-vortical field',  &
       answer = xvz_VLat,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 2 * sin(xyz_Lat)
  call AssertEqual(&
      message='wt_Potential2Vector (Rad) with non-vortical field', &
       answer = xyz_VRad,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 2 * sin(xvz_Lat)
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Rad) with non-vortical field', &
       answer = xvz_VRad,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call wt_Potential2Rotation(&
       xyz_VLon,xyz_VLat,xyz_VRad, wt_Psi, wt_Phi )
  call wt_Potential2RotationMPI(&
       xvz_VLon,xvz_VLat,xvz_VRad, wt_Psi, wt_Phi )

  xyz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2Rotation (Lon) with non-vortical field', &
       answer = xyz_VLon,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Lon) with non-vortical field', &
       answer = xvz_VLon,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2Rotation (Lat) with non-vortical field', &
       answer = xyz_VLat,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Lat) with non-vortical field', &
       answer = xvz_VLat,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2Rotation (Rad) with non-vortical field', &
       answer = xyz_VRad,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Rad) with non-vortical field', &
       answer = xvz_VRad,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

! ----------------- 例 4 --------------------
 ! ポロイダル速度場

  wt_Psi = 0.0D0
  wt_Phi = wt_xyz(xyz_Rad**2 * cos(xyz_Lat)*sin(xyz_Lon))

  call wt_Potential2Vector(&
       xyz_VLon,xyz_VLat,xyz_VRad, wt_Psi, wt_Phi )
  call wt_Potential2VectorMPI(&
       xvz_VLon,xvz_VLat,xvz_VRad, wt_Psi, wt_Phi )

  xyz_DData = 3 * xyz_Rad * cos(xyz_Lon)
  call AssertEqual(&
      message='wt_Potential2Vector (Lon) with poloidal field',   &
       answer = xyz_VLon,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 3 * xvz_Rad * cos(xvz_Lon)
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Lon) with poloidal field',   &
       answer = xvz_VLon,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = - 3 * xyz_Rad * sin(xyz_Lat) * sin(xyz_Lon)
  call AssertEqual(&
      message='wt_Potential2Vector (Lat) with poloidal field', &
       answer = xyz_VLat,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = - 3 * xvz_Rad * sin(xvz_Lat) * sin(xvz_Lon)
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Lat) with poloidal field', &
       answer = xvz_VLat,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 2 * xyz_Rad * cos(xyz_Lat) * sin(xyz_Lon)
  call AssertEqual(&
      message='wt_Potential2Vector (Rad) with poloidal field', &
       answer = xyz_VRad,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 2 * xvz_Rad * cos(xvz_Lat) * sin(xvz_Lon)
  call AssertEqual(&
      message='wt_Potential2VectorMPI (Rad) with poloidal field', &
       answer = xvz_VRad,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call wt_Potential2Rotation(&
       xyz_VLon,xyz_VLat,xyz_VRad, wt_Psi, wt_Phi )
  call wt_Potential2RotationMPI(&
       xvz_VLon,xvz_VLat,xvz_VRad, wt_Psi, wt_Phi )

  xyz_DData = 4*sin(xyz_Lat)*sin(xyz_Lon)
  call AssertEqual(&
      message='wt_Potential2Rotation (Lon) with poloidal field', &
       answer = xyz_VLon,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 4*sin(xvz_Lat)*sin(xvz_Lon)
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Lon) with poloidal field', &
       answer = xvz_VLon,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 4*cos(xyz_Lon)
  call AssertEqual(&
      message='wt_Potential2Rotation (Lat) with poloidal field', &
       answer = xyz_VLat,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 4*cos(xvz_Lon)
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Lat) with poloidal field', &
       answer = xvz_VLat,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  xyz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2Rotation (Rad) with poloidal field', &
       answer = xyz_VRad,                                            &
       check = xyz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )
  xvz_DData = 0.0D0
  call AssertEqual(&
      message='wt_Potential2RotationMPI (Rad) with poloidal field', &
       answer = xvz_VRad,                                            &
       check = xvz_DData,                                            &
       significant_digits = check_digits, ignore_digits = ignore     &
       )

  call MessageNotify('M','wtq_mpi_module_derivative_wt_test2', &
       'wtq_mpi_module wt-derivative function test #2 succeeded!')

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

  call MPI_FINALIZE(IERR)

end program wtq_mpi_module_derivative_wt2
