!----------------------------------------------------------------------
!     Copyright (c) 2019 Shin-ichi Takehiro. All rights reserved.
!----------------------------------------------------------------------
!
!表題  ua_spectrum_module テストプログラム :: スペクトル関数のテスト
!
!履歴  2019/05/03  竹広真一
!      2020/11/10  竹広真一  セクター計算オプション導入
!
program ua_mpi_module_spectrum_mint
  use mpi
  use dc_message, only : MessageNotify
  use dc_test, only : AssertEqual
  use ua_mpi_module_mint
  implicit none

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

  real(8), allocatable ::  ua_data(:,:)
  real(8), allocatable ::  xvb_data(:,:,:)
  real(8), allocatable               ::  b_data(:)

  real(8), dimension(0:nm,-nm:nm,km) ::  nma_data
  real(8), dimension(0:nm,km)        ::  na_data
  real(8), dimension(km)             ::  a_data

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

  integer :: n,m
  integer :: ip, np, ierr

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

  call ua_mpi_Initial( nm, im, jm, km, npv=npv, mint=mint )

  allocate(ua_data(nmc,km))
  allocate(xvb_data(0:im-1,1:jc,kc))
  allocate(b_data(kc))

  call MessageNotify('M','ua_mpi_module_spectrum_mint_test',&
                         'ua_mpi_module_mint spectrum functions tests.')

  ua_data = 0.0D0
  !ua_data = ua_xvb(xvb_ua(ua_data))

  ! 2Y_1^0
  if ( kp_kl(1) /= 0 ) &
       xvb_data(:,:,kp_kl(1)) = 2*sqrt(3.0D0)*sin(xv_Lat) 
  ! 3*Y_1^0 + 2Y_2^0 +Y_2^-2
  if ( kp_kl(2) /= 0 ) &
  xvb_data(:,:,kp_kl(2)) = 3*sqrt(3.0D0)*sin(xv_Lat) &
                + 2*sqrt(5.0D0)*(3.0/2*sin(xv_Lat)**2-1/2.0) &
                - sqrt(5.0D0/24)*3.0*cos(xv_Lat)**2*sin(2*xv_Lon)

  ua_data = ua_xvb(xvb_data)

  !--------- Energy spectrum ---------
  nma_data=ua_spectrum_VMiss

  do n=0,nm
     do m=-n,n
        nma_data(n,m,:) = 0.0D0
     enddo
  enddo

  nma_data(1,0,1) = 4.0D0
  nma_data(1,0,2) = 9.0D0
  nma_data(2,0,2) = 12.0D0
  nma_data(2,-2,2)= 2*3*(1.0D0/2)**2/2
  nma_data(2,2,2) = nma_data(2,-2,2)

  call AssertEqual(&
    message='nma_EnergyFromStreamfunc_ua',                        &
    answer = nma_EnergyFromStreamfunc_ua(ua_data),                &
    check =  nma_data,                                            &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  na_data = 0.0D0
  na_data(1,1) = 4.0D0
  na_data(1,2) = 9.0D0
  na_data(2,2) = 12.0D0 + 2*3*(1.0D0/2)**2

  call AssertEqual(&
    message='na_EnergyFromStreamfunc_ua',                         &
    answer = na_EnergyFromStreamfunc_ua(ua_data),                 &
    check =  na_data,                                             &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  nma_Data = nma_EnergyFromStreamfunc_ua(ua_data)
  b_data = 0.0D0
  do n=0,nm
     do m=-n,n
        b_data = b_data + nma_Data(n,m,ks:ke)
     enddo
  enddo

  call AssertEqual(&
    message='total energy by nm-spectrum',                        &
    answer = b_AvrLonLat_xvb(                                     &
    0.5*(xvb_GradLon_ua(ua_data)**2+xvb_GradLat_ua(ua_data)**2) ),&
    check = b_data,                                               &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  a_data = sum(na_EnergyFromStreamfunc_ua(ua_data),1)
  b_data = a_data(ks:ke)
  call AssertEqual(&
    message='total energy with n-spectrum',                       &
    answer = b_AvrLonLat_xvb(                                     &
    0.5*(xvb_GradLon_ua(ua_data)**2+xvb_GradLat_ua(ua_data)**2) ),&
    check =  b_data,                                              &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  !--------- Enstrophy spectrum ---------
  nma_data=ua_spectrum_VMiss
  do n=0,nm
     do m=-n,n
        nma_data(n,m,:) = 0.0D0
     enddo
  enddo

  nma_data(1,0,1) = 8.0D0

  nma_data(1,0,2)  = 18.0D0
  nma_data(2,0,2)  = 72.0D0
  nma_data(2,-2,2) = 2**2 * 3**2 * (1.0D0/2)**2 /2
  nma_data(2,2,2)  = nma_data(2,-2,2)

  call AssertEqual(&
    message='nma_EnstrophyFromStreamfunc_ua',                     &
    answer = nma_EnstrophyFromStreamfunc_ua(ua_data),             &
    check =  nma_data,                                            &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  na_data = 0.0
  na_data(1,1) = 8.0D0
  na_data(1,2) = 18.0D0
  na_data(2,2) = 72.0D0 + 2**2 * 3**2 * (1.0D0/2)**2

  call AssertEqual(&
    message='na_EnstrophyFromStreamfunc_ua',                      &
    answer = na_EnstrophyFromStreamfunc_ua(ua_data),              &
    check =  na_data,                                             &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  nma_Data = nma_EnstrophyFromStreamfunc_ua(ua_data)
  b_data = 0.0D0
  do n=0,nm
     do m=-n,n
        b_data = b_data + nma_Data(n,m,ks:ke)
     enddo
  enddo

  call AssertEqual(&
    message='total enstrophy by nm-spectrum',                     &
    answer = b_AvrLonLat_xvb( 0.5*(xvb_ua(ua_Lapla_ua(ua_data))**2)),&
    check = b_data,                                               &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  a_data = sum(na_EnstrophyFromStreamfunc_ua(ua_data),1)
  b_data = a_data(ks:ke)
  call AssertEqual(&
    message='total energy with n-spectrum',                       &
    answer = b_AvrLonLat_xvb( 0.5*(xvb_ua(ua_Lapla_ua(ua_data))**2)), &
    check =  b_data,                                              &
    significant_digits = check_digits, ignore_digits = ignore     &
    )

  call MessageNotify('M','ua_mpi_module_spectrum_mint_test', &
                     'ua_mpi_module_mint spectrum tests succeeded!')

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

  call MPI_FINALIZE(IERR)

end program ua_mpi_module_spectrum_mint
