program test_Field_IcGrid2D

  use dc_types, only: DP, TOKEN, STRING
  use dc_test, only: AssertLessThan, AssertEqual

  use igmcore_math, only: PI

  use IcGrid2D_FVM_Manager, only: &
    & IcGrid2D_FVM, &
    & IcGrid2D_FVM_Init, &
    & RC_REGIONS_NUM

  use IcGrid2D_FVM_Builder, only: &
    & construct_icosahedral_grid, GTYPE_STDGCGRID, GTYPE_STDGRID, GTYPE_SPRGCGRID
  use IcGrid_ncGridLoader, only: &
    & load_gridData

  use Field_IcGrid2D_Manager, only: &
    & Field_IcGrid2D, &
    & Field_IcGrid2D_Init, global_mean, Field_IcGrid2D_Final, &
    & get_field2D_name, get_field2D_rank, get_long_field2D_name, get_field2D_units, &
    & set_field2D_name, set_long_field2D_name, set_field2D_units

! use class_IcGrid_Scalar_Field, only: IcGrid_Scalar_Field

  implicit none

  type(IcGrid2D_FVM) :: icgrid
  type(Field_IcGrid2D) :: test_field
!  type(IcGrid_Scalar_Field) :: test_s_field

  character(STRING) :: gridData_ncfile = '../diffOptr_test/SPR-GC-grid_glevel5.nc'
  integer :: glevel = 5
  real(DP) :: ic_radius = 1.0d0

  character(TOKEN) :: name
  integer :: field_dim
  character(STRING) :: long_name
  character(TOKEN) :: units

  real(DP) :: gmean
  real(DP) :: true_global_mean

  !!!!!!!!!!!!!!!
  !
  ! 実行文 ; Executable statement
  !
  !!!!!!!!!!!!!!!

  ! 構造型 IcGrid2D_FVM の変数を初期化し, NetCDF から正二十面格子の座標データを取得する.
  call IcGrid2D_FVM_Init(icgrid, glevel, ic_radius)
  call load_gridData(gridData_ncfile, icgrid)
 !

  ! ユニットテスト
  !
  !

  name = 'test_field'
  field_dim = 3
  long_name = 'This physical field is a test field.'
  units = 'm/s'

  ! Unit test 2.1
  !
  write(*,*) '= Unit Test 2.1 [ Field_IcGrid2D_Manager]'
  write(*,*) '* Initialization and finalization of a variable of derived type Field_IcGrid2D'

  call Field_IcGrid2D_Init(test_field, icgrid, name, field_dim, long_name, units)

  call AssertEqual( message='get_name', answer=trim(name), check=trim(get_field2D_name(test_field)) )
  call AssertEqual( message='get_dimension', answer=field_dim, check=get_field2D_rank(test_field) )
  call AssertEqual( message='get_long_name', answer=trim(long_name), check=trim(get_long_field2D_name(test_field)) )
  call AssertEqual( message='get_units', answer=trim(units), check=trim(get_field2D_units(test_field)) )

  call Field_IcGrid2D_Final(test_field)


  ! Unit test 2.2
  !
  write(*,*) '= Unit Test 2.2 [ Field_IcGrid2D_Manager]'
  write(*,*) '* Getter and setter associated with derived type Field_IcGrid2D'

  call Field_IcGrid2D_Init(test_field, icgrid, name, field_dim, long_name, units)

  name = 'test_field_second'
  long_name = 'This physical field is a test field2.'
  units = 'm'

  call set_field2D_name(test_field, name)
  call AssertEqual( message='set_name', answer=trim(name), check=trim(get_field2D_name(test_field)) )
  call set_long_field2D_name(test_field, long_name)
  call AssertEqual( message='set_long_name', answer=trim(long_name), check=trim(get_long_field2D_name(test_field)) )
  call set_field2D_units(test_field, units)
  call AssertEqual( message='set_units', answer=trim(units), check=trim(get_field2D_units(test_field)) )

  call Field_IcGrid2D_Final(test_field)

  ! Unit test 2.3
  !
  write(*,*) '= Unit Test 2.3 [ Field_IcGrid2D_Manager]'
  write(*,*) '* Checks the behavior of other remained subroutines. '

  name = 'test_field'
  field_dim = 1
  long_name = 'This physical field is a test field.'
  units = 'm/s'

  call Field_IcGrid2D_Init(test_field, icgrid, name, field_dim, long_name, units)

  test_field%val = 1.0d0

  !
  gmean = global_mean(test_field)
  true_global_mean = 1.0d0

  write(*,*) gmean, true_global_mean

  ! 全球平均値が正しいか確認する.
  call AssertLessThan( &
      & message='global_mean (Check whether the normalized error is less than 1.0e-08)', &
      & answer=1.0d-08, check=abs( gmean - true_global_mean ) / abs(true_global_mean) )

  call Field_IcGrid2D_Final(test_field)

end program test_Field_IcGrid2D
