!----------------------------------------------------------------------
!     Copyright (c) 2012 Shin-ichi Takehiro. All rights reserved.
!----------------------------------------------------------------------
!
!表題  w_integral_mpi_module テストプログラム :: 積分・平均関数のテスト
!
!履歴  2012/04/03  竹広真一
!
program w_integral_mpi_module_test

  use dc_message, only : MessageNotify
  use dc_test, only : AssertEqual
  use w_mpi_module
  use mpi
  implicit none

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

  real(8), dimension(0:im-1,jm) ::  xy_data            ! 元の関数
  real(8), dimension(0:im-1)    ::  x_idata            ! 積分・平均の正解
  real(8), dimension(jm)        ::  y_idata            ! 積分・平均の正解
  real(8)                       ::  idata              ! 積分・平均の正解

  real(8), allocatable          ::  xv_data(:,:)       ! 元の関数
  real(8), allocatable          ::  v_idata(:)         ! 積分・平均の正解

  real(8) :: pi
  integer :: iproc, np, ierr

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

 !---------------- MPI スタート ---------------------
  call MPI_INIT(IERR)
  call MPI_COMM_RANK(MPI_COMM_WORLD,IPROC,IERR)
  call MPI_COMM_SIZE(MPI_COMM_WORLD,NP,IERR)

  pi = atan(1.0D0)*4.0D0

  call MessageNotify('M','w_integral_mpi_module_test', &
                         'w_integral_mpi_module function tests') 

  call w_mpi_Initial( nm, im, jm )

  allocate(xv_data(0:im-1,jc))
  allocate(v_idata(jc))

  !---- 積分のテスト(全領域) ----
  xy_data = sin(xy_Lat)**2*(1-cos(xy_Lon)**2)

  idata = 2*pi/3       ! IntLonLat_xy
  call AssertEqual(&
    message='IntLonLat_xy',                                       &
    answer = idata,                                               &
    check = IntLonLat_xy(xy_data),                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  y_idata = pi*sin(y_Lat)**2       ! y_IntLon_xy
  call AssertEqual(&
    message='y_IntLon_xy',                                        &
    answer = y_idata,                                             &
    check = y_IntLon_xy(xy_data),                                 &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  x_idata = 2.0D0/3*(1-cos(x_Lon)**2)       ! x_IntLat_xy
  call AssertEqual(&
    message='x_IntLat_xy',                                        &
    answer = x_idata,                                             &
    check = x_IntLat_xy(xy_data),                                 &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call AssertEqual(&
    message='IntLon_x',                                           &
    answer = idata,                                               &
    check = IntLon_x(x_idata),                                    &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call AssertEqual(&
    message='IntLat_y',                                           &
    answer = idata,                                               &
    check = IntLat_y(y_idata),                                    &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !---- 平均のテスト(全領域) ----
  xy_data = sin(xy_Lat)**2*(1-cos(xy_Lon)**2)

  idata = 1.0D0/6       ! AvrLonLat_xy
  call AssertEqual(&
    message='AvrLonLat_xy',                                       &
    answer = idata,                                               &
    check = AvrLonLat_xy(xy_data),                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  y_idata = 0.5*sin(y_Lat)**2       ! y_AvrLon_xy
  call AssertEqual(&
    message='y_AvrLon_xy',                                        &
    answer = y_idata,                                             &
    check = y_AvrLon_xy(xy_data),                                 &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  x_idata = 1.0D0/3*(1-cos(x_Lon)**2)       ! x_AvrLat_xy

  call AssertEqual(&
    message='x_AvrLat_xy',                                        &
    answer = x_idata,                                             &
    check = x_AvrLat_xy(xy_data),                                 &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call AssertEqual(&
    message='AvrLon_x',                                           &
    answer = idata,                                               &
    check = AvrLon_x(x_idata),                                    &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call AssertEqual(&
    message='AvrLat_y',                                           &
    answer = idata,                                               &
    check = AvrLat_y(y_idata),                                    &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !---- 積分のテスト(分割領域) ----
  xv_data = sin(xv_Lat)**2*(1-cos(xv_Lon)**2)

  idata = 2*pi/3       ! IntLonLat_xv
  call AssertEqual(&
    message='IntLonLat_xv',                                       &
    answer = idata,                                               &
    check = IntLonLat_xv(xv_data),                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  v_idata = pi*sin(v_Lat)**2       ! y_IntLon_xv
  call AssertEqual(&
    message='v_IntLon_xv',                                        &
    answer = v_idata,                                             &
    check = v_IntLon_xv(xv_data),                                 &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  x_idata = 2.0D0/3*(1-cos(x_Lon)**2)       ! x_IntLat_xv
  call AssertEqual(&
    message='x_IntLat_xv',                                        &
    answer = x_idata,                                             &
    check = x_IntLat_xv(xv_data),                                 &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call AssertEqual(&
    message='IntLat_v',                                           &
    answer = idata,                                               &
    check = IntLat_v(v_idata),                                    &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !---- 平均のテスト(分割領域) ----
  xv_data = sin(xv_Lat)**2*(1-cos(xv_Lon)**2)

  idata = 1.0D0/6       ! AvrLonLat_xy
  call AssertEqual(&
    message='AvrLonLat_xv',                                       &
    answer = idata,                                               &
    check = AvrLonLat_xv(xv_data),                                &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  v_idata = 0.5*sin(v_Lat)**2       ! y_AvrLon_xy
  call AssertEqual(&
    message='v_AvrLon_xv',                                        &
    answer = v_idata,                                             &
    check = v_AvrLon_xv(xv_data),                                 &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  x_idata = 1.0D0/3*(1-cos(x_Lon)**2)       ! x_AvrLat_xv
  call AssertEqual(&
    message='x_AvrLat_xv',                                        &
    answer = x_idata,                                             &
    check = x_AvrLat_xv(xv_data),                                 &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call AssertEqual(&
    message='AvrLat_v',                                           &
    answer = idata,                                               &
    check = AvrLat_v(v_idata),                                    &
    significant_digits = check_digits, ignore_digits = ignore     &
    )


  call MessageNotify('M','w_integral_mpi_module_test', &
                         'w_integral_mpi_module function tests succeded!') 

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

  call MPI_FINALIZE(IERR)      

end program w_integral_mpi_module_test

