!----------------------------------------------------------------------
!     Copyright (c) 2013 Shin-ichi Takehiro. All rights reserved.
!----------------------------------------------------------------------
!
!表題  w_base_module テストプログラム :: ベクトル用サブルーチンのテスト
!
!履歴  2013/02/11  竹広真一
!
program w_base_module_vector_test

  use dc_message, only : MessageNotify
  use dc_test, only : AssertEqual
  use w_module
  implicit none

  integer, parameter :: im=128, jm=64, nm=42

  real(8), dimension(0:im-1,1:jm)  ::  xy_U              ! 速度経度成分
  real(8), dimension(0:im-1,1:jm)  ::  xy_V              ! 速度緯度成分

  real(8), dimension(0:im-1,1:jm)  ::  xy_UCosLat        ! 速度経度成分
  real(8), dimension(0:im-1,1:jm)  ::  xy_VCosLat        ! 速度緯度成分

  real(8), dimension(0:im-1,1:jm)  ::  xy_Uans           ! 速度経度成分
  real(8), dimension(0:im-1,1:jm)  ::  xy_Vans           ! 速度緯度成分

  real(8), dimension(0:im-1,1:jm)  ::  xy_Psi            ! 流線関数
  real(8), dimension(0:im-1,1:jm)  ::  xy_Chi            ! 速度ポテンシャル

  real(8), dimension((nm+1)**2)    ::  w_Vor             ! 渦度
  real(8), dimension((nm+1)**2)    ::  w_Div             ! 発散

  real(8), dimension(0:im-1,1:jm)  ::  xy_Vorans         ! 渦度
  real(8), dimension(0:im-1,1:jm)  ::  xy_Divans         ! 発散


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

  call MessageNotify('M','w_base_module_vector_test', &
                         'w_base_module subroutine tests') 

  call w_Initial( nm, im, jm )

  !---- Y_1^{-1} のテスト ----
  xy_Psi = cos(xy_Lat)*sin(xy_Lon)       ! Y_1^{-1}
  xy_Chi = 0.0D0

  xy_Uans = sin(xy_Lat)*sin(xy_Lon)
  xy_Vans = cos(xy_Lon)

  xy_Vorans = -2*cos(xy_Lat)*sin(xy_Lon)
  xy_Divans = 0.0D0

  call w_StreamPotential2Vector( w_xy(xy_Psi), w_xy(xy_Chi), xy_U, xy_V )

  call AssertEqual(&
    message='Psi = Y_1^-1 test of w_StreamPotential2Vector(U)',   &
    answer = xy_Uans,                                             &
    check  = xy_U,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_1^-1 test of w_StreamPotential2Vector(V)',   &
    answer = xy_Vans,                                             &
    check  = xy_V,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call w_Vector2VorDiv( xy_U, xy_V, w_Vor, w_Div )

  call AssertEqual(&
    message='Psi = Y_1^-1 test of w_Vector2VorDiv(Vor)',          &
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_1^-1 test of w_Vector2VorDiv(Div)',          &
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_UCosLat = xy_U * cos(xy_Lat) ; xy_VCosLat = xy_V * cos(xy_Lat)

  call w_VectorCosLat2VorDiv( xy_UCosLat, xy_VCosLat, w_Vor, w_Div )

  call AssertEqual(&
    message='Psi = Y_1^-1 test of w_VectorCosLat2VorDiv(Vor)',    &
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_1^-1 test of w_VectorCosLat2VorDiv(Div)',    &
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_Psi = 0.0D0
  xy_Chi = cos(xy_Lat)*sin(xy_Lon)       ! Y_1^{-1}

  xy_Uans = cos(xy_Lon)
  xy_Vans = - sin(xy_Lat)*sin(xy_Lon)

  xy_Vorans = 0.0D0
  xy_Divans = -2*cos(xy_Lat)*sin(xy_Lon)

  call w_StreamPotential2Vector( w_xy(xy_Psi), w_xy(xy_Chi), xy_U, xy_V )

  call AssertEqual(&
    message='Chi = Y_1^-1 test of w_StreamPotential2Vector(U)',   &
    answer = xy_Uans,                                             &
    check  = xy_U,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Chi = Y_1^-1 test of w_StreamPotential2Vector(V)',   &
    answer = xy_Vans,                                             &
    check  = xy_V,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call w_Vector2VorDiv( xy_U, xy_V, w_Vor, w_Div )

  call AssertEqual(&
    message='Chi = Y_1^-1 test of w_Vector2VorDiv(Vor)',          &
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Chi = Y_1^-1 test of w_Vector2VorDiv(Div)',          &
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_UCosLat = xy_U * cos(xy_Lat) ; xy_VCosLat = xy_V * cos(xy_Lat)

  call w_VectorCosLat2VorDiv( xy_UCosLat, xy_VCosLat, w_Vor, w_Div )

  call AssertEqual(&
    message='Chi = Y_1^-1 test of w_VectorCosLat2VorDiv(Vor)',    &
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Chi = Y_1^-1 test of w_VectorCosLat2VorDiv(Div)',    &
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !---- Y_2^1 のテスト ----
  xy_Psi = sin(xy_Lat)*cos(xy_Lat) * cos(xy_Lon)       ! Y_2^1
  xy_Chi = 0.0D0

  xy_Uans = - cos(2*xy_Lat)*cos(xy_Lon)
  xy_Vans = - sin(xy_Lat)*sin(xy_Lon)

  xy_Vorans = -6*sin(xy_Lat)*cos(xy_Lat) * cos(xy_Lon)       ! Y_2^1
  xy_Divans = 0.0D0

  call w_StreamPotential2Vector( w_xy(xy_Psi), w_xy(xy_Chi), xy_U, xy_V )

  call AssertEqual(&
    message='Psi = Y_2^1 test of w_StreamPotential2Vector(U)',    &
    answer = xy_Uans,                                             &
    check  = xy_U,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_2^1 test of w_StreamPotential2Vector(V)',    &
    answer = xy_Vans,                                             &
    check  = xy_V,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call w_Vector2VorDiv( xy_U, xy_V, w_Vor, w_Div )

  call AssertEqual(&
    message='Psi = Y_2^1 test of w_Vector2VorDiv(Vor)',           &
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_2^1 test of w_Vector2VorDiv(Div)',           &
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_UCosLat = xy_U * cos(xy_Lat) ; xy_VCosLat = xy_V * cos(xy_Lat)

  call w_VectorCosLat2VorDiv( xy_UCosLat, xy_VCosLat, w_Vor, w_Div )

  call AssertEqual(&
    message='Psi = Y_2^1 test of w_VectorCosLat2VorDiv(Vor)',     &
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_2^1 test of w_VectorCosLat2VorDiv(Div)',     &
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_Psi = 0.0D0
  xy_Chi = sin(xy_Lat)*cos(xy_Lat) * cos(xy_Lon)       ! Y_2^1

  xy_Uans = - sin(xy_Lat)*sin(xy_Lon)
  xy_Vans =   cos(2*xy_Lat)*cos(xy_Lon)

  xy_Vorans = 0.0D0
  xy_Divans = -6*sin(xy_Lat)*cos(xy_Lat) * cos(xy_Lon)       ! Y_2^1

  call w_StreamPotential2Vector( w_xy(xy_Psi), w_xy(xy_Chi), xy_U, xy_V )

  call AssertEqual(&
    message='Chi = Y_2^1 test of w_StreamPotential2Vector(U)',    &
    answer = xy_Uans,                                             &
    check  = xy_U,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Chi = Y_2^1 test of w_StreamPotential2Vector(V)',    &
    answer = xy_Vans,                                             &
    check  = xy_V,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call w_Vector2VorDiv( xy_U, xy_V, w_Vor, w_Div )

  call AssertEqual(&
    message='Chi = Y_2^1 test of w_Vector2VorDiv(Vor)',           &
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Chi = Y_2^1 test of w_Vector2VorDiv(Div)',           &
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_UCosLat = xy_U * cos(xy_Lat) ; xy_VCosLat = xy_V * cos(xy_Lat)

  call w_VectorCosLat2VorDiv( xy_UCosLat, xy_VCosLat, w_Vor, w_Div )

  call AssertEqual(&
    message='Chi = Y_2^1 test of w_VectorCosLat2VorDiv(Vor)',     &
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Chi = Y_2^1 test of w_VectorCosLat2VorDiv(Div)',     &
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !---- Y_1^-1, Y_2^1 のテスト ----
  xy_Psi = sin(xy_Lat)*cos(xy_Lat) * cos(xy_Lon)       ! Y_2^1
  xy_Chi = cos(xy_Lat)*sin(xy_Lon)                     ! Y_1^{-1}

  xy_Uans = - cos(2*xy_Lat)*cos(xy_Lon) + cos(xy_Lon)
  xy_Vans = - sin(xy_Lat)*sin(xy_Lon) - sin(xy_Lat)*sin(xy_Lon)

  xy_Vorans = -6*sin(xy_Lat)*cos(xy_Lat) * cos(xy_Lon)       ! Y_2^1
  xy_Divans = -2*cos(xy_Lat)*sin(xy_Lon)                     ! Y_1^{-1}

  call w_StreamPotential2Vector( w_xy(xy_Psi), w_xy(xy_Chi), xy_U, xy_V )

  call AssertEqual(&
    message='Psi = Y_2^1, Chi = Y_1^-1 test of w_StreamPotential2Vector(U)',     &
    answer = xy_Uans,                                             &
    check  = xy_U,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_2^1, Chi = Y_1^-1 test of w_StreamPotential2Vector(V)',     &
    answer = xy_Vans,                                             &
    check  = xy_V,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call w_Vector2VorDiv( xy_U, xy_V, w_Vor, w_Div )

  call AssertEqual(&
    message='Psi = Y_2^1, Chi=Y_1^-1 test of w_Vector2VorDiv(Vor)',&
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_2^1, Chi=Y_1^-1 test of w_Vector2VorDiv(Div)',&
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_UCosLat = xy_U * cos(xy_Lat) ; xy_VCosLat = xy_V * cos(xy_Lat)

  call w_VectorCosLat2VorDiv( xy_UCosLat, xy_VCosLat, w_Vor, w_Div )

  call AssertEqual(&
    message='Psi = Y_2^1, Chi=Y_1^-1 test of w_VectorCosLat2VorDiv(Vor)',&
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_2^1, Chi=Y_1^-1 test of w_VectorCosLat2VorDiv(Div)',&
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_Psi = cos(xy_Lat)*sin(xy_Lon)                     ! Y_1^{-1}
  xy_Chi = sin(xy_Lat)*cos(xy_Lat) * cos(xy_Lon)       ! Y_2^1

  xy_Uans = 0.0D0
  xy_Vans = cos(2*xy_Lat)*cos(xy_Lon) + cos(xy_Lon)

  xy_Vorans = -2*cos(xy_Lat)*sin(xy_Lon)                     ! Y_1^{-1}
  xy_Divans = -6*sin(xy_Lat)*cos(xy_Lat) * cos(xy_Lon)       ! Y_2^1

  call w_StreamPotential2Vector( w_xy(xy_Psi), w_xy(xy_Chi), xy_U, xy_V )

  call AssertEqual(&
    message='Psi = Y_1^-1, Chi = Y_2^1 test of w_StreamPotential2Vector(U)',     &
    answer = xy_Uans,                                             &
    check  = xy_U,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_1^-1, Chi = Y_2^1 test of w_StreamPotential2Vector(V)',     &
    answer = xy_Vans,                                             &
    check  = xy_V,                                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call w_Vector2VorDiv( xy_U, xy_V, w_Vor, w_Div )

  call AssertEqual(&
    message='Psi = Y_1^-1, Chi=Y_2^1 test of w_Vector2VorDiv(Vor)',&
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_1^-1, Chi=Y_2^1 test of w_Vector2VorDiv(Div)',&
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_UCosLat = xy_U * cos(xy_Lat) ; xy_VCosLat = xy_V * cos(xy_Lat)

  call w_VectorCosLat2VorDiv( xy_UCosLat, xy_VCosLat, w_Vor, w_Div )

  call AssertEqual(&
    message='Psi = Y_1^-1, Chi=Y_2^1 test of w_VectorCosLat2VorDiv(Vor)',&
    answer = xy_Vorans,                                           &
    check  = xy_w(w_Vor),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )
  call AssertEqual(&
    message='Psi = Y_1^-1, Chi=Y_2^1 test of w_VectorCosLat2VorDiv(Div)',&
    answer = xy_Divans,                                           &
    check  = xy_w(w_Div),                                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call MessageNotify('M','w_base_module_vector_test', &
                         'w_base_module subroutine tests succeeded!') 

end program w_base_module_vector_test

