Test_ModelVerticalGrid.pf Source File


This file depends on

sourcefile~~test_modelverticalgrid.pf~~EfferentGraph sourcefile~test_modelverticalgrid.pf Test_ModelVerticalGrid.pf sourcefile~actualconnectionpt.f90 ActualConnectionPt.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~actualconnectionpt.f90 sourcefile~componentdriver.f90 ComponentDriver.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~componentdriver.f90 sourcefile~componentdriverptrvector.f90 ComponentDriverPtrVector.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~componentdriverptrvector.f90 sourcefile~componentdrivervector.f90 ComponentDriverVector.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~componentdrivervector.f90 sourcefile~couplermetacomponent.f90 CouplerMetaComponent.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~couplermetacomponent.f90 sourcefile~esmf_testmethod.f90 ESMF_TestMethod.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~esmf_testmethod.f90 sourcefile~geom_mgr.f90 geom_mgr.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~geom_mgr.f90 sourcefile~griddedcomponentdriver.f90 GriddedComponentDriver.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~griddedcomponentdriver.f90 sourcefile~make_itemspec.f90 make_itemSpec.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~make_itemspec.f90 sourcefile~modelverticalgrid.f90 ModelVerticalGrid.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~modelverticalgrid.f90 sourcefile~multistate.f90 MultiState.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~multistate.f90 sourcefile~stateitemextension.f90 StateItemExtension.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~stateitemextension.f90 sourcefile~stateitemspec.f90 StateItemSpec.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~stateitemspec.f90 sourcefile~stateregistry.f90 StateRegistry.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~stateregistry.f90 sourcefile~variablespec.f90 VariableSpec.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~variablespec.f90 sourcefile~verticaldimspec.f90 VerticalDimSpec.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~verticaldimspec.f90 sourcefile~virtualconnectionpt.f90 VirtualConnectionPt.F90 sourcefile~test_modelverticalgrid.pf->sourcefile~virtualconnectionpt.f90

Source Code

#include "MAPL_TestErr.h"

! We use ESMF_TestMethod rather than basic TestMethod just in case
! there are any implied barriers is the ESMF construction in these
! tests.  E.g., if we end up needing to create nested grid comps.
! Almost certainly, is unnecessary.

module Test_ModelVerticalGrid
   use mapl3g_VerticalDimSpec
   use mapl3g_ModelVerticalGrid
   use mapl3g_StateRegistry
   use mapl3g_VariableSpec
   use mapl3g_VirtualConnectionPt
   use mapl3g_ActualConnectionPt
   use mapl3g_StateItemSpec
   use mapl3g_StateItemExtension
   use mapl3g_GriddedComponentDriver
   use mapl3g_ComponentDriver
   use mapl3g_ComponentDriverVector
   use mapl3g_ComponentDriverPtrVector
   use mapl3g_MultiState
   use mapl3g_make_ItemSpec
   use mapl3g_geom_mgr
   use mapl3g_CouplerMetaComponent, only: GENERIC_COUPLER_UPDATE
   use esmf
   ! testing framework
   use ESMF_TestMethod_mod
   use funit
   implicit none (type, external)

   integer, parameter :: IM=6, JM=7, LM=3

   ! Trying to avoid a complex test fixture
   type(StateRegistry), target :: r

contains

   subroutine setup(vgrid, rc)
      type(ModelVerticalGrid), intent(out) :: vgrid
      integer, intent(out) :: rc

      type(ESMF_Geom) :: geom
      type(VirtualConnectionPt) :: ple_pt
      type(VariableSpec) :: var_spec
      class(StateItemSpec), allocatable :: ple_spec
      type(StateItemExtension), pointer :: extension
      class(StateItemSpec), pointer :: spec
      integer :: status

      rc = 0
      ! Inside user "set_geom" phase.
      geom = make_geom(_RC)
      vgrid = ModelVerticalGrid(num_levels=LM)
      call vgrid%add_variant(short_name='PLE')

      ! inside OuterMeta
      r = StateRegistry('dyn')
      call vgrid%set_registry(r) ! MAPL_SetVerticalGrid(...)

      ple_pt = VirtualConnectionPt(state_intent='export', short_name='PLE')
     var_spec = VariableSpec(&
           short_name='PLE', &
           state_intent=ESMF_STATEINTENT_EXPORT, &
           standard_name='air_pressure', &
           units='hPa', &
           vertical_dim_spec=VERTICAL_DIM_EDGE, &
           default_value=3.)
     allocate(ple_spec, source=make_itemSpec(var_spec, r, rc=status))
     _VERIFY(status)
     call ple_spec%set_geometry(geom=geom, vertical_grid=vgrid, _RC)

      call r%add_primary_spec(ple_pt, ple_spec)

      extension => r%get_primary_extension(ple_pt, _RC)
      spec => extension%get_spec()
      call spec%set_active()
      call spec%create(_RC)
      call spec%allocate(_RC)

   end subroutine setup

   function make_geom(rc) result(geom)
      integer, intent(out) :: rc
      type(ESMF_Geom) :: geom
      type(ESMF_Grid) :: grid
      integer :: status
      type(ESMF_HConfig) :: hconfig
      type(GeomManager), pointer :: geom_mgr
      class(GeomSpec), allocatable :: geom_spec
      type(MaplGeom), pointer :: mapl_geom
      
      rc = 0
      geom_mgr => get_geom_manager()
      hconfig = ESMF_HConfigCreate(content='{class: latlon, im_world: 6, jm_world: 7, pole: PC, dateline: DC}', _RC)
      mapl_geom => geom_mgr%get_mapl_geom(hconfig, _RC)
      geom = mapl_geom%get_geom()
      
   end function make_geom
   

  @test
   subroutine test_num_levels()
      type(ModelVerticalGrid) :: vgrid

      integer :: num_levels

      num_levels = 10
      vgrid = ModelVerticalGrid(num_levels=num_levels)
      @assert_that(vgrid%get_num_levels(), is(num_levels))

   end subroutine test_num_levels

   @test
   subroutine test_num_variants()
      type(ModelVerticalGrid) :: vgrid
      integer :: num_variants

      vgrid = ModelVerticalGrid(num_levels=3)
      @assert_that(vgrid%get_num_variants(), is(0))
      call vgrid%add_variant(short_name='PLE')
      @assert_that(vgrid%get_num_variants(), is(1))
      call vgrid%add_variant(short_name='ZLE')
      @assert_that(vgrid%get_num_variants(), is(2))

   end subroutine test_num_variants

   @test(type=ESMF_TestMethod, npes=[1])
   subroutine test_created_fields_have_num_levels(this)
      class(ESMF_TestMethod), intent(inout) :: this
      type(ModelVerticalGrid) :: vgrid
      integer :: rank
      integer, allocatable :: localElementCount(:)
      type(VirtualConnectionPt) :: ple_pt
      class(StateItemSpec), pointer :: spec
      type(MultiState) :: multi_state
      type(StateItemExtension), pointer :: extension
      type(ESMF_Field) :: ple
      integer :: status

      call setup(vgrid, _RC)

      ple_pt = VirtualConnectionPt(state_intent='export', short_name='PLE')
      extension => r%get_primary_extension(ple_pt, _RC)
      spec => extension%get_spec()

      multi_state = MultiState()
      call spec%add_to_state(multi_state, ActualConnectionPt(ple_pt), _RC)
      call ESMF_StateGet(multi_state%exportState, itemName='PLE', field=ple, _RC)
      call ESMF_FieldGet(ple, rank=rank, _RC)
      allocate(localElementCount(rank))
      call ESMF_FieldGet(ple, localElementCount=localElementCount, _RC)
      @assert_that(localElementCount, is(equal_to([IM,JM,LM+1])))

   end subroutine test_created_fields_have_num_levels

   @test(type=ESMF_TestMethod, npes=[1])
   ! Request the specific coordinate corresponding particular geom/unit.
   ! In this case we start with one that already exists.  A later test
   ! should force extensions.
   subroutine test_get_coordinate_field_simple(this)
      class(ESMF_TestMethod), intent(inout) :: this
      type(ModelVerticalGrid) :: vgrid
      type(GriddedComponentDriver), pointer :: coupler 
      type(ESMF_Field) :: vcoord
      type(ESMF_Geom) :: geom
      integer :: status
      real(ESMF_KIND_R4), pointer :: a(:,:,:)

      call setup(vgrid, _RC)
      geom = make_geom(_RC)
           
      call vgrid%get_coordinate_field(vcoord, coupler, &
           standard_name='air_pressure', geom=geom, typekind=ESMF_TYPEKIND_R4, units='hPa', _RC)
      @assert_that(associated(coupler), is(false()))

      call ESMF_FieldGet(vcoord, fArrayPtr=a, _RC)
      @assert_that(a, every_item(is(equal_to(3.))))

   end subroutine test_get_coordinate_field_simple
   
   @test
   ! Request the specific coordinate corresponding particular geom/unit.
   ! Here we request different units which should return a coordinate
   ! scaled by 100 (hPa = 100 Pa)
   subroutine test_get_coordinate_field_change_units()
      type(ModelVerticalGrid) :: vgrid

      type(ESMF_Field) :: vcoord
      type(ESMF_Geom) :: geom
      integer :: status
      real(ESMF_KIND_R4), pointer :: a(:,:,:)
      type(ComponentDriverPtrVector) :: couplers
      type(ComponentDriverPtr) :: driver
      type(GriddedComponentDriver), pointer :: coupler 
      integer :: i

      call setup(vgrid, _RC)
      geom = make_geom(_RC)
      call vgrid%get_coordinate_field(vcoord, coupler, &
           standard_name='air_pressure', geom=geom, typekind=ESMF_TYPEKIND_R4, units='Pa', _RC)
      @assert_that(associated(coupler), is(true()))

      call r%allocate(_RC)

      call ESMF_FieldGet(vcoord, fArrayPtr=a, _RC)
      ! usually update is called on imports, but here we don't have an import handy,
      ! so we force updates on all export couplers in registry r.
      couplers = r%get_export_couplers()
      do i = 1, couplers%size()
         driver = couplers%of(i)
         call driver%ptr%initialize(_RC)
         call driver%ptr%run(phase_idx=GENERIC_COUPLER_UPDATE, _RC)
      end do
      @assert_that(a, every_item(is(equal_to(300.))))
      
   end subroutine test_get_coordinate_field_change_units
   

end module Test_ModelVerticalGrid