Test_OutputInfo.pf Source File


This file depends on

sourcefile~~test_outputinfo.pf~~EfferentGraph sourcefile~test_outputinfo.pf Test_OutputInfo.pf sourcefile~mapl_esmf_infokeys.f90 MAPL_ESMF_InfoKeys.F90 sourcefile~test_outputinfo.pf->sourcefile~mapl_esmf_infokeys.f90 sourcefile~outputinfo.f90 OutputInfo.F90 sourcefile~test_outputinfo.pf->sourcefile~outputinfo.f90 sourcefile~ungriddeddim.f90 UngriddedDim.F90 sourcefile~test_outputinfo.pf->sourcefile~ungriddeddim.f90 sourcefile~ungriddeddimvector.f90 UngriddedDimVector.F90 sourcefile~test_outputinfo.pf->sourcefile~ungriddeddimvector.f90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~mapl_esmf_infokeys.f90->sourcefile~errorhandling.f90 sourcefile~outputinfo.f90->sourcefile~mapl_esmf_infokeys.f90 sourcefile~outputinfo.f90->sourcefile~ungriddeddim.f90 sourcefile~outputinfo.f90->sourcefile~ungriddeddimvector.f90 sourcefile~outputinfo.f90->sourcefile~errorhandling.f90 sourcefile~ungriddeddims.f90 UngriddedDims.F90 sourcefile~outputinfo.f90->sourcefile~ungriddeddims.f90 sourcefile~ungriddeddim.f90->sourcefile~errorhandling.f90 sourcefile~lu_bound.f90 LU_Bound.F90 sourcefile~ungriddeddim.f90->sourcefile~lu_bound.f90 sourcefile~ungriddeddimvector.f90->sourcefile~ungriddeddim.f90 sourcefile~mapl_throw.f90 MAPL_Throw.F90 sourcefile~errorhandling.f90->sourcefile~mapl_throw.f90 sourcefile~ungriddeddims.f90->sourcefile~ungriddeddim.f90 sourcefile~ungriddeddims.f90->sourcefile~ungriddeddimvector.f90 sourcefile~ungriddeddims.f90->sourcefile~errorhandling.f90 sourcefile~ungriddeddims.f90->sourcefile~lu_bound.f90

Source Code

#if defined SET_RC
#  undef SET_RC
#endif
#define SET_RC(A) if(present(rc)) rc = A
#define _SUCCESS 0
#define _FAILURE _SUCCESS-1
#include "MAPL_TestErr.h"
module Test_OutputInfo
   use mapl3g_output_info
   use mapl3g_esmf_info_keys
   use mapl3g_UngriddedDim
   use mapl3g_UngriddedDimVector
   use pfunit
   use esmf
   use gFTL2_StringVector

   implicit none

   integer, parameter :: NUM_FIELDS_DEFAULT = 2
   integer, parameter :: NUM_LEVELS_DEFAULT = 3
   character(len=*), parameter :: VLOC_DEFAULT = 'VERTICAL_DIM_CENTER'
   integer, parameter :: NUM_UNGRIDDED_DEFAULT = 3
   character(len=*), parameter :: NAME_DEFAULT = 'A1'
   character(len=*), parameter :: UNITS_DEFAULT = 'stones'
   real, parameter :: COORDINATES_DEFAULT(*) = [2.0, 2.4, 2.5]

   type(ESMF_Info), allocatable :: bundle_info(:)

contains

   @Test
   subroutine test_get_num_levels()
      integer :: status
      integer, parameter :: EXPECTED_NUM_LEVELS = 3
      integer :: num_levels
      integer :: i

      call safe_dealloc(bundle_info)
      allocate(bundle_info(2))
      do i=1, size(bundle_info)
         bundle_info(i) = make_esmf_info(num_levels=EXPECTED_NUM_LEVELS, _RC)
      end do
      num_levels = get_num_levels_bundle_info(bundle_info, _RC)
      @assertEqual(EXPECTED_NUM_LEVELS, num_levels, 'num_levels does not match.')

      call safe_dealloc(bundle_info)

   end subroutine test_get_num_levels

   @Test
   subroutine test_get_vertical_dim_spec_names()
      integer :: status
      character(len=*), parameter :: EXPECTED_NAME_1 = 'VERTICAL_DIM_CENTER'
      character(len=*), parameter :: EXPECTED_NAME_2 = 'VERTICAL_DIM_EDGE'
      type(StringVector), allocatable :: names
      integer :: sz

      call safe_dealloc(bundle_info)
      allocate(bundle_info(3))
      bundle_info(1) = make_esmf_info(vloc=EXPECTED_NAME_1, _RC)
      bundle_info(2) = make_esmf_info(vloc=EXPECTED_NAME_2, _RC)
      bundle_info(3) = make_esmf_info(vloc=EXPECTED_NAME_1, _RC)
      names = get_vertical_dim_spec_names_bundle_info(bundle_info, _RC)
      sz = names%size()
      @assertEqual(2, sz, 'There should only be two unique vertical_dim_spec names.')
      @assertEqual(EXPECTED_NAME_1, names%at(1), 'vertical_dim_spec_name 1 does not match.')
      @assertEqual(EXPECTED_NAME_2, names%at(2), 'vertical_dim_spec_name 2 does not match.')
      call safe_dealloc(bundle_info)

   end subroutine test_get_vertical_dim_spec_names

   @Test
   subroutine test_get_ungridded_dims()
      integer :: status
      integer :: i
      integer, parameter :: N = 2
      integer, parameter :: D = 3
      character(len=*), parameter :: EXPECTED_NAMES(N) = ['color', 'phase']
      character(len=*), parameter :: EXPECTED_UNITS(N) = ['K  ', 'rad']
      real, parameter :: REAL_ARRAY(D) = [1.0, 2.0, 3.0]
      real :: EXPECTED_COORDINATES(N, D)
      character(len=:), allocatable :: name
      character(len=:), allocatable :: units
      real, allocatable :: coordinates(:)
      type(UngriddedDimVector) :: vec
      type(UngriddedDim) :: undim

      call safe_dealloc(bundle_info)

      do i=1, N
         EXPECTED_COORDINATES(i,:) = REAL_ARRAY
      end do

      allocate(bundle_info(N))
      do i=1, N
         bundle_info(i) = make_esmf_info(names=EXPECTED_NAMES, units_array=EXPECTED_UNITS, coordinates=EXPECTED_COORDINATES, _RC)
      end do
      vec = get_ungridded_dims_bundle_info(bundle_info, _RC)
      do i=1, N
         undim = vec%at(i)
         name = undim%get_name()
         @assertEqual(EXPECTED_NAMES(i), name, 'ungridded dimension name does not match.')
         units = undim%get_units()
         @assertEqual(EXPECTED_UNITS(i), units, 'ungridded dimension units does not match.')
         coordinates = undim%get_coordinates()
         @assertEqual(EXPECTED_COORDINATES(i, :), coordinates, 0.01, 'ungridded dimensions coordinates does not match.')
      end do
      call safe_dealloc(bundle_info)

   end subroutine test_get_ungridded_dims

   function make_esmf_info(num_levels, vloc, num_ungridded, names, units_array, coordinates, rc) &
         result(info)
      type(ESMF_Info) :: info
      integer, optional, intent(in) :: num_levels
      character(len=*), optional, intent(in) :: vloc
      integer, optional, intent(in) :: num_ungridded
      character(len=*), optional, intent(in) :: names(:)
      character(len=*), optional, intent(in) :: units_array(:)
      real, optional, intent(in) :: coordinates(:, :)
      integer, optional, intent(out) :: rc
      integer :: status
      integer :: num_levels_, num_ungridded_
      character(len=:), allocatable :: vloc_

      num_ungridded_ = -1
      num_levels_ = NUM_LEVELS_DEFAULT
      if(present(num_levels)) num_levels_ = num_levels
      vloc_ = VLOC_DEFAULT
      if(present(vloc)) vloc_ = vloc
      info = ESMF_InfoCreate(_RC)
      call make_vertical_dim(info, vloc_, _RC)
      call make_vertical_geom(info, num_levels_, _RC)

      SET_RC(status)

      if(present(names) .and. present(units_array)) then
         if(size(names) /= size(units_array)) return
         num_ungridded_ = size(names)
      end if
      if(present(num_ungridded)) then
         if((num_ungridded_ >= 0) .and. (num_ungridded /= num_ungridded)) return
         num_ungridded_ = num_ungridded
      end if
      call make_ungridded_dims_info(info, num_ungridded_, names, units_array, coordinates, _RC)
      SET_RC(status)

   end function make_esmf_info

   subroutine make_vertical_dim(info, vloc, rc)
      type(ESMF_Info), intent(inout) :: info
      character(len=*), intent(in) :: vloc
      integer, optional, intent(out) :: rc
      integer :: status

      call ESMF_InfoSet(info, KEY_VLOC, vloc, _RC)
      SET_RC(status)

   end subroutine make_vertical_dim

   subroutine make_vertical_geom(info, num_levels, rc)
      type(ESMF_Info), intent(inout) :: info
      integer, intent(in) :: num_levels
      integer, optional, intent(out) :: rc
      integer :: status

      call ESMF_InfoSet(info, KEY_NUM_LEVELS, num_levels, _RC)
      SET_RC(status)

   end subroutine make_vertical_geom

   subroutine make_ungridded_dims_info(info, num_ungridded, names, units_array, coordinates, rc)
      type(ESMF_Info), intent(inout) :: info
      integer, intent(in) :: num_ungridded
      character(len=*), optional, intent(in) :: names(:)
      character(len=*), optional, intent(in) :: units_array(:)
      real, optional, intent(in) :: coordinates(:, :)
      integer, optional, intent(out) :: rc
      integer :: status, i
      character(len=:), allocatable :: names_(:), units_(:)
      real, allocatable :: coordinates_(:, :)
      character(len=:), allocatable :: key
      character(len=:), allocatable :: name, units
      real, allocatable :: coord(:)

      if(present(rc)) rc = -1

      allocate(character(len=len(NAME_DEFAULT)) :: names_(num_ungridded))
      names_ = NAME_DEFAULT
      if(present(names)) then
         if(size(names) /= num_ungridded) return
         names_ = names
      end if

      allocate(character(len=len(UNITS_DEFAULT)) :: units_(num_ungridded))
      units_ = UNITS_DEFAULT
      if(present(units_array)) then
         if(size(units_array) /= num_ungridded) return
         units_ = units_array
      end if

      allocate(coordinates_(num_ungridded, size(COORDINATES_DEFAULT)))
      do i=1, num_ungridded
         coordinates_(i, :) = COORDINATES_DEFAULT
      end do

      if(present(rc)) rc = -1
      if(present(coordinates)) then
         if(size(coordinates, 1) /= num_ungridded) return
         if(allocated(coordinates_)) deallocate(coordinates_)
         coordinates_ = coordinates
      end if

      call ESMF_InfoSet(info, KEY_NUM_UNGRID_DIMS, num_ungridded, _RC)

      do i=1, num_ungridded
         key = make_dim_key(i, _RC)
         name = names_(i)
         units = units_(i)
         coord = coordinates_(i, :)
         call ESMF_InfoSet(info, key // '/' // KEY_UNGRIDDED_NAME, name, _RC)
         call ESMF_InfoSet(info, key // '/' // KEY_UNGRIDDED_UNITS, units, _RC)
         call ESMF_InfoSet(info, key // '/' // KEY_UNGRIDDED_COORD, coord, _RC)
      end do

      SET_RC(status)

   end subroutine make_ungridded_dims_info

   subroutine destroy_all(info)
      type(ESMF_Info), allocatable, intent(inout) :: info(:)
      integer :: i

      do i = 1, size(info)
         call ESMF_InfoDestroy(info(i))
      end do

   end subroutine destroy_all

   subroutine deallocate_destroy(info)
      type(ESMF_Info), allocatable, intent(inout) :: info(:)

      call destroy_all(info)
      deallocate(info)

   end subroutine deallocate_destroy

   subroutine safe_dealloc(info)
      type(ESMF_Info), allocatable, intent(inout) :: info(:)
      if(allocated(info)) call deallocate_destroy(info)
   end subroutine safe_dealloc

end module Test_OutputInfo