!----------------------------------------------------------------------
!     Copyright (c) 2019 Shin-ichi Takehiro. All rights reserved.
!----------------------------------------------------------------------
!
!表題  w_deriv_module テストプログラム :: 微分関数のテスト
!
!履歴  2019/03/16  竹広真一
!      2020/11/06  竹広真一 セクター計算テスト
!
program w_deriv_module_mint_test

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

!!$  integer, parameter :: im=64, jm=32, nm=21, mint=1
  integer, parameter :: im=32, jm=32, nm=21, mint=2

  real(8), dimension(0:im-1,1:jm)  ::  xy_data1              ! 元の関数
  real(8), dimension(0:im-1,1:jm)  ::  xy_data2              ! 元の関数
  real(8), dimension(0:im-1,1:jm)  ::  xy_ddata              ! 微分の正解
  real(8), dimension(0:im-1,1:jm)  ::  mu                    ! μ=sinφ

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

  call MessageNotify('M','w_deriv_module_svpack_test', &
                         'w_deriv_module_svpack function tests')

  call w_Initial( nm, im, jm, mint=mint )

  !---- Y_1^0 のテスト ----
  xy_data1 = sin(xy_Lat)                     ! Y_1^0

  xy_ddata = -2*sin(xy_Lat)                  ! w_Lapla_w
  call AssertEqual(&
    message='Y_1^0 test of w_Lapla_w',                            &
    answer = xy_ddata,                                            &
    check = xy_w(w_Lapla_w(w_xy(xy_data1))),                      &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = -1.0/2.0*sin(xy_Lat)            ! w_LaplaInv_w
  call AssertEqual(&
    message='Y_1^0 test of w_LaplaInv_w',                         &
    answer = xy_ddata,                                            &
    check = xy_w(w_LaplaInv_w(w_xy(xy_data1))),                   &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = 0.0D0                           ! w_DLon_w
  call AssertEqual(&
    message='Y_1^0 test of w_DLon_w',                             &
    answer = xy_ddata,                                            &
    check = xy_w(w_DLon_w(w_xy(xy_data1))),                       &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = 0.0D0                           ! xy_GradLon_w
  call AssertEqual(&
    message='Y_1^0 test of xy_GradLon_w',                         &
    answer = xy_ddata,                                            &
    check = xy_GradLon_w(w_xy(xy_data1)),                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = cos(xy_Lat)                     ! xy_GradLat_w
  call AssertEqual(&
    message='Y_1^0 test of xy_GradLat_w',                         &
    answer = xy_ddata,                                            &
    check = xy_GradLat_w(w_xy(xy_data1)),                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !---- Y_1^0 cosφ のテスト ----
  xy_data1 = sin(xy_Lat)*cos(xy_Lat)                 ! Y_1^0 cosφ

  xy_ddata = 0.0D0                                   ! w_DivLon_xy
  call AssertEqual(&
    message='Y_1^0 cosφ test of xy_DivLon_w',                    &
    answer = xy_ddata,                                            &
    check = xy_w(w_DivLon_xy(xy_data1)),                          &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = cos(xy_Lat)**2 - 2*sin(xy_Lat)**2       ! w_DivLat_w
  call AssertEqual(&
    message='Y_1^0 cosφ test of xy_DivLat_w',                    &
    answer = xy_ddata,                                            &
    check = xy_w(w_DivLat_xy(xy_data1)),                          &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !---- Jacobian のテスト ----
  xy_data1 = sin(xy_Lat)                             ! Y_1^0
  xy_data2 = cos(xy_Lat)**2*sin(2*xy_Lon)            ! Y_2^-2

  xy_ddata = 0.0
  call AssertEqual(&
    message='Y_1^0test of w_Jacobian_w_w',                        &
    answer = xy_ddata,                                            &
    check = xy_w(w_Jacobian_w_w(w_xy(xy_data1),w_xy(xy_data1))),  &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = - cos(xy_Lat) * cos(xy_Lat)*2*cos(2*xy_Lon)
  call AssertEqual(&
    message='Y_1^0 and Y_2^-2 test of w_Jacobian_w_w',            &
    answer = xy_ddata,                                            &
    check = xy_w(w_Jacobian_w_w(w_xy(xy_data1),w_xy(xy_data2))),  &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = cos(xy_Lat) * cos(xy_Lat)*2*cos(2*xy_Lon)
  call AssertEqual(&
    message='Y_2^-2 and Y_1^0 test of w_Jacobian_w_w',            &
    answer = xy_ddata,                                            &
    check = xy_w(w_Jacobian_w_w(w_xy(xy_data2),w_xy(xy_data1))),  &
    significant_digits = check_digits, ignore_digits = ignore     &
    )


  !---- Y_2^2 のテスト ----
  xy_data1 = cos(xy_Lat)**2*cos(2*xy_Lon)       ! Y_2^2

  xy_ddata = -6*cos(xy_Lat)**2*cos(2*xy_Lon)    ! w_Lapla_w
  call AssertEqual(&
    message='Y_2^2 test of w_Lapla_w',                            &
    answer = xy_ddata,                                            &
    check = xy_w(w_Lapla_w(w_xy(xy_data1))),                      &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = -1.0D0/6.0D0*cos(xy_Lat)**2*cos(2*xy_Lon) ! w_LaplaInv_w
  call AssertEqual(&
    message='Y_2^2 test of w_LaplaInv_w',                         &
    answer = xy_ddata,                                            &
    check = xy_w(w_LaplaInv_w(w_xy(xy_data1))),                   &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = cos(xy_Lat)**2*(-2)*sin(2*xy_Lon)     ! w_DLon_w
  call AssertEqual(&
    message='Y_2^2 test of w_DLon_w',                             &
    answer = xy_ddata,                                            &
    check = xy_w(w_DLon_w(w_xy(xy_data1))),                       &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = cos(xy_Lat)*(-2)*sin(2*xy_Lon)        ! xy_GradLon_w
  call AssertEqual(&
    message='Y_2^2 test of xy_GradLon_w',                         &
    answer = xy_ddata,                                            &
    check = xy_GradLon_w(w_xy(xy_data1)),                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = (-2)*cos(xy_Lat)*sin(xy_Lat)*cos(2*xy_Lon)  ! xy_GradLat_w
  call AssertEqual(&
    message='Y_2^2 test of xy_GradLat_w',                         &
    answer = xy_ddata,                                            &
    check = xy_GradLat_w(w_xy(xy_data1)),                         &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !---- Y_2^2 cosφ のテスト ----
  xy_data1 = cos(xy_Lat)**3*cos(2*xy_Lon)            ! Y_2^2 cosφ

  xy_ddata = cos(xy_Lat)**2*(-2)*sin(2*xy_Lon)       ! w_DivLon_xy
  call AssertEqual(&
    message='Y_2^2 cosφ test of xy_DivLon_w',                    &
    answer = xy_ddata,                                            &
    check = xy_w(w_DivLon_xy(xy_data1)),                          &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = (-4)*cos(xy_Lat)**2*sin(xy_Lat)*cos(2*xy_Lon) ! w_DivLat_w
  call AssertEqual(&
    message='Y_2^2 cosφ test of xy_DivLat_w',                    &
    answer = xy_ddata,                                            &
    check = xy_w(w_DivLat_xy(xy_data1)),                          &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

!!$  !---- Jacobian のテスト ----
!!$  xy_data1 = sin(xy_Lat)                             ! Y_2^2
!!$  xy_data2 = sin(xy_Lat)                             ! Y_2^2
!!$
!!$  xy_ddata = 0.0
!!$  call AssertEqual(&
!!$    message='Y_2^2 test of w_Jacobian_w_w',                        &
!!$    answer = xy_ddata,                                            &
!!$    check = xy_w(w_Jacobian_w_w(w_xy(xy_data1),w_xy(xy_data1))),  &
!!$    significant_digits = check_digits, ignore_digits = ignore     &
!!$    )
!!$
  !============== 微分計算 (λ,μ座標系用) のテスト ==============
  mu = sin(xy_Lat)

  !----- Y_2^0 のテスト -----
  xy_data1 = 3*mu**2-1                              ! Y_2^0

  xy_ddata = 0.0
  call AssertEqual(&
    message='Y_2^0 test of xy_GradLambda_w',                      &
    answer = xy_ddata,                                            &
    check = xy_GradLambda_w(w_xy(xy_data1)),                      &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = 6*mu*(1-mu**2)
  call AssertEqual(&
    message='Y_2^0 test of xy_GradMu_w',                          &
    answer = xy_ddata,                                            &
    check = xy_GradMu_w(w_xy(xy_data1)),                          &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !----- Y_2^0 cosφ のテスト -----
  xy_data1 = (3*mu**2-1)*(1-mu**2)                ! Y_2^0 (1-μ^2)

  xy_ddata = 0.0
  call AssertEqual(&
    message='Y_2^0 (1-μ^2) test of xy_DivLambda_w',                 &
    answer = xy_ddata,                                            &
    check = xy_w(w_DivLambda_xy(xy_data1)),                       &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  xy_ddata = (2-3*mu**2)*4*mu
  call AssertEqual(&
    message='Y_2^0 (1-μ^2) test of xy_DivMu_w',                  &
    answer = xy_ddata,                                            &
    check = xy_w(w_DivMu_xy(xy_data1)),                           &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call MessageNotify('M','w_deriv_module_svpack_test', &
                         'w_deriv_module_svpack function tests succeeded!')

end program w_deriv_module_mint_test
