Test_FieldDelta.pf Source File


This file depends on

sourcefile~~test_fielddelta.pf~~EfferentGraph sourcefile~test_fielddelta.pf Test_FieldDelta.pf sourcefile~esmf_testmethod.f90 ESMF_TestMethod.F90 sourcefile~test_fielddelta.pf->sourcefile~esmf_testmethod.f90 sourcefile~fieldcreate.f90 FieldCreate.F90 sourcefile~test_fielddelta.pf->sourcefile~fieldcreate.f90 sourcefile~fielddelta.f90 FieldDelta.F90 sourcefile~test_fielddelta.pf->sourcefile~fielddelta.f90 sourcefile~fieldget.f90 FieldGet.F90 sourcefile~test_fielddelta.pf->sourcefile~fieldget.f90 sourcefile~fieldinfo.f90 FieldInfo.F90 sourcefile~test_fielddelta.pf->sourcefile~fieldinfo.f90 sourcefile~infoutilities.f90 InfoUtilities.F90 sourcefile~test_fielddelta.pf->sourcefile~infoutilities.f90 sourcefile~ungriddeddim.f90 UngriddedDim.F90 sourcefile~test_fielddelta.pf->sourcefile~ungriddeddim.f90 sourcefile~ungriddeddims.f90 UngriddedDims.F90 sourcefile~test_fielddelta.pf->sourcefile~ungriddeddims.f90 sourcefile~verticalstaggerloc.f90 VerticalStaggerLoc.F90 sourcefile~test_fielddelta.pf->sourcefile~verticalstaggerloc.f90 sourcefile~esmf_testcase.f90 ESMF_TestCase.F90 sourcefile~esmf_testmethod.f90->sourcefile~esmf_testcase.f90 sourcefile~esmf_testparameter.f90 ESMF_TestParameter.F90 sourcefile~esmf_testmethod.f90->sourcefile~esmf_testparameter.f90 sourcefile~fieldcreate.f90->sourcefile~fieldinfo.f90 sourcefile~fieldcreate.f90->sourcefile~ungriddeddims.f90 sourcefile~fieldcreate.f90->sourcefile~verticalstaggerloc.f90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~fieldcreate.f90->sourcefile~errorhandling.f90 sourcefile~keywordenforcer.f90 KeywordEnforcer.F90 sourcefile~fieldcreate.f90->sourcefile~keywordenforcer.f90 sourcefile~lu_bound.f90 LU_Bound.F90 sourcefile~fieldcreate.f90->sourcefile~lu_bound.f90 sourcefile~fielddelta.f90->sourcefile~fieldget.f90 sourcefile~fielddelta.f90->sourcefile~fieldinfo.f90 sourcefile~fielddelta.f90->sourcefile~infoutilities.f90 sourcefile~fielddelta.f90->sourcefile~verticalstaggerloc.f90 sourcefile~fielddelta.f90->sourcefile~errorhandling.f90 sourcefile~fieldpointerutilities.f90 FieldPointerUtilities.F90 sourcefile~fielddelta.f90->sourcefile~fieldpointerutilities.f90 sourcefile~fielddelta.f90->sourcefile~keywordenforcer.f90 sourcefile~fieldget.f90->sourcefile~fieldinfo.f90 sourcefile~fieldget.f90->sourcefile~ungriddeddims.f90 sourcefile~fieldget.f90->sourcefile~verticalstaggerloc.f90 sourcefile~fieldget.f90->sourcefile~errorhandling.f90 sourcefile~fieldget.f90->sourcefile~keywordenforcer.f90 sourcefile~fieldinfo.f90->sourcefile~infoutilities.f90 sourcefile~fieldinfo.f90->sourcefile~ungriddeddims.f90 sourcefile~fieldinfo.f90->sourcefile~verticalstaggerloc.f90 sourcefile~fieldinfo.f90->sourcefile~errorhandling.f90 sourcefile~fieldinfo.f90->sourcefile~keywordenforcer.f90 sourcefile~mapl_esmf_infokeys.f90 MAPL_ESMF_InfoKeys.F90 sourcefile~fieldinfo.f90->sourcefile~mapl_esmf_infokeys.f90 sourcefile~infoutilities.f90->sourcefile~errorhandling.f90 sourcefile~infoutilities.f90->sourcefile~keywordenforcer.f90 sourcefile~infoutilities.f90->sourcefile~mapl_esmf_infokeys.f90 sourcefile~ungriddeddim.f90->sourcefile~infoutilities.f90 sourcefile~ungriddeddim.f90->sourcefile~errorhandling.f90 sourcefile~ungriddeddim.f90->sourcefile~lu_bound.f90 sourcefile~ungriddeddims.f90->sourcefile~infoutilities.f90 sourcefile~ungriddeddims.f90->sourcefile~ungriddeddim.f90 sourcefile~ungriddeddims.f90->sourcefile~errorhandling.f90 sourcefile~ungriddeddims.f90->sourcefile~lu_bound.f90 sourcefile~ungriddeddims.f90->sourcefile~mapl_esmf_infokeys.f90 sourcefile~ungriddeddimvector.f90 UngriddedDimVector.F90 sourcefile~ungriddeddims.f90->sourcefile~ungriddeddimvector.f90 sourcefile~mapl_throw.f90 MAPL_Throw.F90 sourcefile~errorhandling.f90->sourcefile~mapl_throw.f90 sourcefile~esmf_testcase.f90->sourcefile~esmf_testparameter.f90 sourcefile~mapl_exceptionhandling.f90 MAPL_ExceptionHandling.F90 sourcefile~fieldpointerutilities.f90->sourcefile~mapl_exceptionhandling.f90 sourcefile~mapl_esmf_infokeys.f90->sourcefile~errorhandling.f90 sourcefile~ungriddeddimvector.f90->sourcefile~ungriddeddim.f90 sourcefile~mapl_exceptionhandling.f90->sourcefile~errorhandling.f90 sourcefile~mapl_exceptionhandling.f90->sourcefile~mapl_throw.f90

Source Code

#include "MAPL_TestErr.h"
#include "unused_dummy.H"
module Test_FieldDelta
   use mapl3g_FieldDelta
   use mapl3g_FieldGet
   use mapl3g_FieldCreate
   use mapl3g_FieldInfo
   use mapl3g_UngriddedDims
   use mapl3g_UngriddedDim
   use mapl3g_InfoUtilities
   use mapl3g_VerticalStaggerLoc
   use mapl3g_FieldInfo
   use esmf
   use ESMF_TestMethod_mod
   use funit
   implicit none (type, external)

   integer, parameter :: ORIG_VGRID_LEVELS = 5
   real, parameter :: FILL_VALUE = 99.
   character(*), parameter :: ORIGINAL_UNITS = 'm'
   character(*), parameter :: REFERENCE_UNITS = 'km'
   
contains

   @test(type=ESMF_TestMethod, npes=[1])
   subroutine test_change_typekind(this)
      class(ESMF_TestMethod), intent(inout) :: this
      type(ESMF_Field) :: f
      type(ESMF_Grid) :: grid
      type(ESMF_Geom) :: geom

      integer :: status
      type(ESMF_FieldStatus_Flag) :: field_status
      type(ESMF_TypeKind_Flag) :: typekind
      type(FieldDelta) :: delta
      
      grid = ESMF_GridCreateNoPeriDim(maxIndex=[4,4], name='I_AM_GROOT', _RC)
      geom = ESMF_GeomCreate(grid, _RC)

      f = ESMF_FieldCreate(geom, typekind=ESMF_TYPEKIND_R4, name='in', _RC)
      call MAPL_FieldSet(f, num_levels=ORIG_VGRID_LEVELS+1, vert_staggerloc=VERTICAL_STAGGER_EDGE, _RC)

      delta = FieldDelta(typekind=ESMF_TYPEKIND_R8)
      call delta%reallocate_field(f, _RC)

      call ESMF_FieldGet(f, status=field_status, typekind=typekind, _RC)
      @assert_that(field_status == ESMF_FIELDSTATUS_COMPLETE, is(true()))
      @assert_that(typekind == ESMF_TYPEKIND_R8, is(true()))

      call ESMF_FieldDestroy(f, _RC)
      call ESMF_GridDestroy(grid, _RC)
      call ESMF_GeomDestroy(geom, _RC)

      _UNUSED_DUMMY(this)
   end subroutine test_change_typekind

   @test(type=ESMF_TestMethod, npes=[1])
   subroutine test_same_typekind_do_not_reallocate(this)
      class(ESMF_TestMethod), intent(inout) :: this
      type(ESMF_Field) :: f
      type(ESMF_Grid) :: grid
      type(ESMF_Geom) :: geom, other_geom

      integer :: status
      type(ESMF_FieldStatus_Flag) :: field_status
      type(ESMF_TypeKind_Flag) :: typekind
      real(kind=ESMF_KIND_R4), pointer :: x(:,:)
      type(FieldDelta) :: delta
      
      grid = ESMF_GridCreateNoPeriDim(maxIndex=[4,4], name='I_AM_GROOT', _RC)
      geom = ESMF_GeomCreate(grid, _RC)
      f = ESMF_FieldCreate(geom, typekind=ESMF_TYPEKIND_R4, name='in', _RC)
      call MAPL_FieldSet(f, num_levels=ORIG_VGRID_LEVELS+1, vert_staggerloc=VERTICAL_STAGGER_EDGE, _RC)

      call ESMF_FieldGet(f, fArrayPtr=x, _RC)
      x = FILL_VALUE

      delta = FieldDelta(typekind=ESMF_TYPEKIND_R4)
      call delta%reallocate_field(f, _RC)

      call ESMF_FieldGet(f, status=field_status, typekind=typekind, geom=other_geom, _RC)
      @assert_that(field_status == ESMF_FIELDSTATUS_COMPLETE, is(true()))
      @assert_that(typekind == ESMF_TYPEKIND_R4, is(true()))
      @assert_that(other_geom == geom, is(true()))

      call ESMF_FieldGet(f, fArrayPtr=x, _RC)
      @assert_that(all(x == FILL_VALUE), is(true()))

      call ESMF_FieldDestroy(f, _RC)
      call ESMF_GridDestroy(grid, _RC)
      call ESMF_GeomDestroy(geom, _RC)

      _UNUSED_DUMMY(this)
   end subroutine test_same_typekind_do_not_reallocate

   @test(type=ESMF_TestMethod, npes=[1])
   subroutine test_change_geom(this)
      class(ESMF_TestMethod), intent(inout) :: this
      type(ESMF_Field) :: f
      type(ESMF_Grid), target :: grid1, grid2
      type(ESMF_Geom) :: geom1, geom2

      integer :: status
      type(ESMF_FieldStatus_Flag) :: field_status
      type(ESMF_TypeKind_Flag) :: typekind
      real(kind=ESMF_KIND_R4), pointer :: x(:,:)
      type(FieldDelta) :: delta
      
      grid1 = ESMF_GridCreateNoPeriDim(maxIndex=[4,4], name='I_AM_GROOT', _RC)
      geom1 = ESMF_GeomCreate(grid1, _RC)
      f = ESMF_FieldCreate(geom1, typekind=ESMF_TYPEKIND_R4, name='in', _RC)
      call MAPL_FieldSet(f, num_levels=ORIG_VGRID_LEVELS+1, vert_staggerloc=VERTICAL_STAGGER_EDGE, _RC)

      grid2 = ESMF_GridCreateNoPeriDim(maxIndex=[3,5], name='I_AM_GROOT', _RC)
      geom2 = ESMF_GeomCreate(grid2, _RC)
      delta = FieldDelta(geom=geom2)
      call delta%reallocate_field(f, _RC)
 
      call ESMF_FieldGet(f, status=field_status, typekind=typekind, _RC)
      @assert_that(field_status == ESMF_FIELDSTATUS_COMPLETE, is(true()))
      @assert_that(typekind == ESMF_TYPEKIND_R4, is(true()))

      call ESMF_FieldGet(f, fArrayPtr=x, _RC)
      @assert_that(shape(x),is(equal_to([3,5])))

      call ESMF_FieldDestroy(f, _RC)
      call ESMF_GridDestroy(grid1, _RC)
      call ESMF_GridDestroy(grid2, _RC)
      call ESMF_GeomDestroy(geom2, _RC)

       _UNUSED_DUMMY(this)
  end subroutine test_change_geom

   @test(type=ESMF_TestMethod, npes=[1])
   subroutine test_same_geom_do_not_reallocate(this)
      class(ESMF_TestMethod), intent(inout) :: this
      type(ESMF_Field) :: f
      type(ESMF_Grid), target :: grid1
      type(ESMF_Geom) :: geom1
      type(ESMF_Geom) :: geom2

      integer :: status
      type(ESMF_FieldStatus_Flag) :: field_status
      type(ESMF_TypeKind_Flag) :: typekind
      real(kind=ESMF_KIND_R4), pointer :: x(:,:)
      type(FieldDelta) :: delta

      grid1 = ESMF_GridCreateNoPeriDim(maxIndex=[4,4], name='I_AM_GROOT', _RC)
      geom1 = ESMF_GeomCreate(grid1, _RC)
      f = ESMF_FieldCreate(geom1, typekind=ESMF_TYPEKIND_R4, name='in', _RC)
      call MAPL_FieldSet(f, num_levels=ORIG_VGRID_LEVELS+1, vert_staggerloc=VERTICAL_STAGGER_EDGE, _RC)
      call ESMF_FieldGet(f, fArrayPtr=x, _RC)
      x = FILL_VALUE

      geom2 = geom1
      delta = FieldDelta(geom=geom2)
      call delta%reallocate_field(f, _RC)

      call ESMF_FieldGet(f, status=field_status, typekind=typekind, _RC)
      @assert_that(field_status == ESMF_FIELDSTATUS_COMPLETE, is(true()))
      @assert_that(typekind == ESMF_TYPEKIND_R4, is(true()))

      call ESMF_FieldGet(f, fArrayPtr=x, _RC)
      @assert_that(all(x == FILL_VALUE), is(true()))

      call ESMF_FieldDestroy(f, _RC)
      call ESMF_GridDestroy(grid1, _RC)
      call ESMF_GeomDestroy(geom2, _RC)

      _UNUSED_DUMMY(this)
   end subroutine test_same_geom_do_not_reallocate


    @test(type=ESMF_TestMethod, npes=[1])
   ! Probably exceedingly rare, but MAPL3 allows the vertical grid to change with time
   ! which could change the number of levels ...
   subroutine test_change_n_levels(this)
      class(ESMF_TestMethod), intent(inout) :: this
      type(ESMF_Field) :: f
      type(ESMF_Grid) :: grid
      type(ESMF_Geom) :: geom

      integer :: status
      type(ESMF_FieldStatus_Flag) :: field_status
      type(ESMF_TypeKind_Flag) :: typekind
      real(ESMF_KIND_R4), pointer :: x(:,:,:,:)
      type(FieldDelta) :: delta
      integer, parameter :: NEW_NUM_LEVELS = 7

      grid = ESMF_GridCreateNoPeriDim(maxIndex=[4,4], name='I_AM_GROOT', _RC)
      geom = ESMF_GeomCreate(grid, _RC)

      f = ESMF_FieldCreate(geom, typekind=ESMF_TYPEKIND_R4, name='in', &
           ungriddedLbound=[1,1], ungriddedUbound=[ORIG_VGRID_LEVELS+1,3], _RC)
      call MAPL_FieldSet(f, num_levels=ORIG_VGRID_LEVELS+1, vert_staggerloc=VERTICAL_STAGGER_EDGE, _RC)

      delta = FieldDelta(num_levels=NEW_NUM_LEVELS+1) ! edge
      call delta%reallocate_field(f, _RC)
      
      call ESMF_FieldGet(f, status=field_status, typekind=typekind, _RC)
      @assert_that(field_status == ESMF_FIELDSTATUS_COMPLETE, is(true()))
      @assert_that(typekind == ESMF_TYPEKIND_R4, is(true()))

      call ESMF_FieldGet(f, fArrayPtr=x, _RC)
      @assert_that(shape(x), is(equal_to([4,4,NEW_NUM_LEVELS+1,3])))

      call ESMF_FieldDestroy(f, _RC)
      call ESMF_GridDestroy(grid, _RC)
      call ESMF_GeomDestroy(geom, _RC)

      _UNUSED_DUMMY(this)
   end subroutine test_change_n_levels

   @test(type=ESMF_TestMethod, npes=[1])
   ! Surface fields should be unaffected when changing num_levels of
   ! vertical grid.
   subroutine test_change_n_levels_surface(this)
      class(ESMF_TestMethod), intent(inout) :: this
      type(ESMF_Field) :: f
      type(ESMF_Grid) :: grid
      type(ESMF_Geom) :: geom

      integer :: status
      type(ESMF_FieldStatus_Flag) :: field_status
      type(ESMF_TypeKind_Flag) :: typekind
      real(ESMF_KIND_R4), pointer :: x(:,:,:,:)
      type(FieldDelta) :: delta

      grid = ESMF_GridCreateNoPeriDim(maxIndex=[4,4], name='I_AM_GROOT', _RC)
      geom = ESMF_GeomCreate(grid, _RC)

      ! Surface field
      f = ESMF_FieldCreate(geom, typekind=ESMF_TYPEKIND_R4, name='in', &
           ungriddedLbound=[1,1], ungriddedUbound=[2,3], _RC)
      call MAPL_FieldSet(f, num_levels=0, vert_staggerloc=VERTICAL_STAGGER_NONE, _RC)
      call ESMF_FieldGet(f, fArrayPtr=x, _RC)
      x = FILL_VALUE

      delta = FieldDelta(num_levels=4)
      call delta%reallocate_field(f, _RC)

      call ESMF_FieldGet(f, status=field_status, typekind=typekind, _RC)
      @assert_that(field_status == ESMF_FIELDSTATUS_COMPLETE, is(true()))
      @assert_that(typekind == ESMF_TYPEKIND_R4, is(true()))

      call ESMF_FieldGet(f, fArrayPtr=x, _RC)
      @assert_that(shape(x), is(equal_to([4,4,2,3])))
      @assert_that(all(x == FILL_VALUE), is(true()))

      call ESMF_FieldDestroy(f, _RC)
      call ESMF_GridDestroy(grid, _RC)
      call ESMF_GeomDestroy(geom, _RC)

      _UNUSED_DUMMY(this)
   end subroutine test_change_n_levels_surface
   


    @test(type=ESMF_TestMethod, npes=[1])
   subroutine test_same_n_levels_do_not_reallocate(this)
      class(ESMF_TestMethod), intent(inout) :: this
      type(ESMF_Field) :: f
      type(ESMF_Grid) :: grid
      type(ESMF_Geom) :: geom, other_geom

      integer :: status
      type(ESMF_FieldStatus_Flag) :: field_status
      real(ESMF_KIND_R4), pointer :: x(:,:,:,:)
      type(ESMF_TypeKind_Flag) :: typekind
      type(FieldDelta) :: delta
      type(UngriddedDims) :: ungridded_dims

      grid = ESMF_GridCreateNoPeriDim(maxIndex=[4,4], name='I_AM_GROOT', _RC)
      geom = ESMF_GeomCreate(grid, _RC)

      call ungridded_dims%add_dim(UngriddedDim(3))
      f = MAPL_FieldCreate(geom=geom, typekind=ESMF_TYPEKIND_R4, &
          num_levels=ORIG_VGRID_LEVELS,  ungridded_dims=ungridded_dims, &
          vert_staggerloc=VERTICAL_STAGGER_CENTER, _RC)
      call ESMF_FieldGet(f, fArrayPtr=x, _RC)
      x = FILL_VALUE

      delta = FieldDelta(num_levels=ORIG_VGRID_LEVELS)
      call delta%reallocate_field(f, _RC)

      call ESMF_FieldGet(f, status=field_status, typekind=typekind, geom=other_geom, _RC)
      @assert_that(field_status == ESMF_FIELDSTATUS_COMPLETE, is(true()))
      @assert_that(typekind == ESMF_TYPEKIND_R4, is(true()))
      @assert_that(other_geom == geom, is(true()))

      ! Check that Field data is unchanged
      call ESMF_FieldGet(f, fArrayPtr=x, _RC)
      @assert_that(all(x == FILL_VALUE), is(true()))

      call ESMF_FieldDestroy(f, _RC)
      call ESMF_GridDestroy(grid, _RC)
      call ESMF_GeomDestroy(geom, _RC)

      _UNUSED_DUMMY(this)
   end subroutine test_same_n_levels_do_not_reallocate


    @test(type=ESMF_TestMethod, npes=[1])
   subroutine test_field_update_from_field_ignore_geom(this)
      class(ESMF_TestMethod), intent(inout) :: this
      type(ESMF_Field) :: f, f_ref
      type(ESMF_Grid) :: grid, grid_ref
      type(ESMF_Geom) :: geom, geom_ref, new_geom
      character(:), allocatable :: new_units

      integer :: status
      type(ESMF_FieldStatus_Flag) :: field_status
      real(ESMF_KIND_R8), pointer :: x8(:,:,:,:)
      type(ESMF_TypeKind_Flag) :: typekind
      type(FieldDelta) :: delta

      grid = ESMF_GridCreateNoPeriDim(maxIndex=[4,4], name='I_AM_GROOT', _RC)
      geom = ESMF_GeomCreate(grid, _RC)

      grid_ref = ESMF_GridCreateNoPeriDim(maxIndex=[7,7], name='I_AM_GROOT', _RC)
      geom_ref = ESMF_GeomCreate(grid_ref, _RC)

      f = ESMF_FieldCreate(geom, typekind=ESMF_TYPEKIND_R4, name='in', &
           ungriddedLbound=[1,1], ungriddedUbound=[ORIG_VGRID_LEVELS,3], _RC)

      f_ref = ESMF_FieldCreate(geom_ref, typekind=ESMF_TYPEKIND_R8, name='in', &
           ungriddedLbound=[1,1], ungriddedUbound=[ORIG_VGRID_LEVELS-1,3], _RC)

      call MAPL_FieldSet(f, num_levels=ORIG_VGRID_LEVELS, vert_staggerloc=VERTICAL_STAGGER_CENTER, &
           units=ORIGINAL_UNITS, _RC)
      call MAPL_FieldSet(f_ref, num_levels=ORIG_VGRID_LEVELS, vert_staggerloc=VERTICAL_STAGGER_CENTER, &
           units=REFERENCE_UNITS, _RC)


      call delta%initialize(f, f_ref, _RC)
      call delta%update_field(f, ignore='geom', _RC)

      call ESMF_FieldGet(f, status=field_status, typekind=typekind, geom=new_geom, _RC)
      @assert_that(field_status == ESMF_FIELDSTATUS_COMPLETE, is(true()))
      @assert_that(typekind == ESMF_TYPEKIND_R8, is(true()))
      @assert_that(new_geom == geom, is(true()))

      call MAPL_FieldGet(f, units=new_units, _RC)
      @assertEqual(REFERENCE_UNITS, new_units)

      ! check that field shape is changed due to new num levels
      call ESMF_FieldGet(f, fArrayPtr=x8, _RC)
      @assert_that(shape(x8),is(equal_to([4,4,ORIG_VGRID_LEVELS,3])))

      call ESMF_FieldDestroy(f, _RC)
      call ESMF_GridDestroy(grid, _RC)
      call ESMF_GeomDestroy(geom, _RC)

      _UNUSED_DUMMY(this)
   end subroutine test_field_update_from_field_ignore_geom

end module Test_FieldDelta