subroutine check_icgrid3Ddata_fSide( &
  & cptr_icgrid3D, mpi_flag &
  & )

  use, intrinsic :: iso_c_binding

#ifdef LIB_MPI
  use mpi
#endif

  use IcGrid3D_FVM_Manager, only: &
  IcGrid3D_FVM, &
  get_vertical_level_num

  implicit none
  type(c_ptr), value :: cptr_icgrid3D
  logical(c_bool), value :: mpi_flag

  type(IcGrid3D_FVM), pointer :: ptr_icgrid3D
  integer :: verticalLvNum
  integer :: mpi_rank, ierr
  integer :: vtLvID

  call c_f_pointer(cptr_icgrid3D, ptr_icgrid3D)

  verticalLvNum = get_vertical_level_num(ptr_icgrid3D)

  if ( mpi_flag ) then
#ifdef LIB_MPI
    call MPI_Comm_rank(MPI_COMM_WORLD, mpi_rank, ierr)
    if ( mpi_rank /= 0 ) return
#endif
  end if

  write(*,*) '--- redistributed vertical grid ------'
  write(*,*) (ptr_icgrid3D%verticalGrid(vtLvID), vtLvID=1, verticalLvNum)


end subroutine check_icgrid3Ddata_fSide

subroutine set_Zs_rot( &
  & cptr_Zs, cptr_rot)

  ! Use statements
  !
  use, intrinsic :: iso_c_binding

  use dc_types, only: DP

  use igmcore_math, only: &
  toRadians

  use IcGrid2D_FVM_Manager, only: &
    & IcGrid2D_FVM, &
    & get_IcRadius

  use Field_IcGrid2D_Manager, only: &
  Field_IcGrid2D, get_icgrid

  use Field_Pattern_Builder, only: &
  create_cosine_bell_field, create_solid_rotation_field

  ! Declaration statements
  !
  type(c_ptr), value :: cptr_Zs
  type(c_ptr), value :: cptr_rot

  !
  !
  !
  type(Field_IcGrid2D), pointer :: ptr_Zs
  type(Field_IcGrid2D), pointer :: ptr_rot
  type(IcGrid2D_FVM), pointer :: icgrid2d

  !
  !

  call c_f_pointer(cptr_Zs, ptr_Zs)
  call c_f_pointer(cptr_rot, ptr_rot)

  icgrid2d => get_icgrid(ptr_Zs)

  call create_cosine_bell_field( &
    & ptr_Zs, toRadians(0.0d0), toRadians(0.0d0), &
    & get_IcRadius(icgrid2d) / 3.0d0, &
    & 1000d0 &
  )

  call create_solid_rotation_field(ptr_rot, 1.0d0, 0.0d0)

end subroutine set_Zs_rot

subroutine set_field_data( &
  & cptr_field &
  & )

  ! Use statements
  !
  use, intrinsic :: iso_c_binding

  use dc_types, only: DP

  use igmcore_math, only: &
  toRadians

  use IcGrid2D_FVM_Manager, only: &
  IcGrid2D_FVM, &
  get_IcRadius

  use IcGrid3D_FVM_Manager, only: &
  IcGrid3D_FVM, &
  get_icgrid2d, get_vertical_level_num

  use Field_IcGrid2D_Manager, only: &
  Field_IcGrid2D

  use Field_IcGrid3D_Manager, only: &
  Field_IcGrid3D, &
  get_icgrid3d, get_field_layer

  use Field_Pattern_Builder, only: &
  create_cosine_bell_field

  ! Declaration statements
  !
  type(c_ptr), value :: cptr_field

  ! Work variables
  !
  !
  type(Field_IcGrid3D), pointer :: ptr_field
  type(IcGrid3D_FVM), pointer :: icgrid3d
  type(IcGrid2D_FVM), pointer :: icgrid2d
  type(Field_IcGrid2D), pointer :: field_k
  real(DP) :: ic_radius
  real(DP) :: delLon
  real(DP) :: lambda_c
  real(DP) :: cbRMax
  real(DP) :: h0Max
  integer :: vLvID, vLvNum

  ! Executable statements
  !

  call c_f_pointer(cptr_field, ptr_field)
  icgrid3d => get_icgrid3D(ptr_field)
  icgrid2d => get_icgrid2d(icgrid3d)

  ic_radius = get_IcRadius(icgrid2d)
  vLvNum = get_vertical_level_num(icgrid3d)
  lambda_c = 0d0
  delLon = 90d0 / vLvNum
  cbRMax = ic_radius / 3.0d0
  h0Max = 1000d0

  do vLvID=1, vLvNum

    field_k => get_field_layer(ptr_field, vLvID)

    call create_cosine_bell_field( &
    field_k, toRadians(lambda_c), toRadians(0.0d0), &
    cbRMax * real(vLvID) / real(vLvNum), &
    h0Max * real(vLvID) / real(vLvNum) &
    )

    lambda_c = lambda_c + delLon

  end do

end subroutine set_field_data

function compare_field_data( &
  & cptr_fieldA, cptr_fieldB &
  & ) result(ret)

  ! Use statements
  !
  use, intrinsic :: iso_c_binding

  use dc_types, only: DP

  use IcGrid2D_FVM_Manager, only: &
    & IcGrid2D_FVM, &
    & get_LocalProcRectInfo

  ! 正二十面格子における広域矩形領域のサブドメインである局所矩形領域(各 MPI プロセスと対応)の情報管理
  ! Manager of information about a local rectangle region (corresponding to each MPI process)
  !
  use LocalProcRect_Manager, only: &
    & LocalProcRectInfo, &
    & get_InteriorRegion_IndexInfo

  use IcGrid3D_FVM_Manager, only: &
    & IcGrid3D_FVM, get_icgrid2d, get_vertical_level_num
    
  use Field_IcGrid2D_Manager, only: &
    & Field_IcGrid2D, &
    & get_icgrid

  use Field_IcGrid3D_Manager, only: &
    & Field_IcGrid3D, &
    & get_icgrid3D, get_field_layer
    
  implicit none

  ! Declaration statements
  !
  type(c_ptr), value :: cptr_fieldA
  type(c_ptr), value :: cptr_fieldB
  logical(c_bool) :: ret

  ! Work variables
  !
  !
  type(Field_IcGrid3D), pointer :: fieldA, fieldB
  type(Field_IcGrid2D), pointer :: fieldA_k, fieldB_k

  type(IcGrid2D_FVM), pointer :: icgrid2D

  integer :: iEMin, iEMax, jEMin, jEMax, kMax, rcIDMin, rcIDMax
  type(LocalProcRectInfo), pointer :: lcRCInfo

  integer :: rcID, i, j, k

  ! Executable statements
  !


  call c_f_pointer(cptr_fieldA, fieldA)
  call c_f_pointer(cptr_fieldB, fieldB)

  icgrid2D => get_icgrid2d(get_icgrid3D(fieldA))
  lcRCInfo => get_LocalProcRectInfo(icgrid2D)

  call get_InteriorRegion_IndexInfo( &
    & lcRCInfo,            &                         ! (in)
    & iEMin, iEMax, jEMin, jEMax, rcIDMin, rcIDMax ) ! (out)
	kMax = get_vertical_level_num(get_icgrid3D(fieldA))
	
	do k=1, kMax
		fieldA_k => get_field_layer(fieldA, k)
		fieldB_k => get_field_layer(fieldB, k)
		
    do rcID=rcIDMin, rcIDMax
      do j=jEMin, jEMax
        do i=iEMin, iEMax
          if( fieldA_k%val(1, i,j,rcID) /= fieldB_k%val(1, i,j,rcID) ) then
            write(*,*) '(rcID,i,j,k)=', rcID, i,j,k
            write(*,*) 'fieldA=', fieldA_k%val(1, i,j,rcID), 'fieldB_k=', fieldB_k%val(1, i,j,rcID)
            ret = .false.
            return
          end if
        end do
      end do
    end do
	end do
  ret = .true.

end function compare_field_data
