From c1706307fe94b574cd3527c7d352ac0f48ffcd0d Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Mon, 28 Oct 2024 11:28:12 -0400 Subject: [PATCH 01/19] Overloaded write for FieldSpec --- generic3g/specs/FieldSpec.F90 | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/generic3g/specs/FieldSpec.F90 b/generic3g/specs/FieldSpec.F90 index b07a59524ed5..2c762c4c41eb 100644 --- a/generic3g/specs/FieldSpec.F90 +++ b/generic3g/specs/FieldSpec.F90 @@ -113,6 +113,9 @@ module mapl3g_FieldSpec procedure :: set_info procedure :: set_geometry + + procedure :: write_formatted + generic :: write(formatted) => write_formatted end type FieldSpec interface FieldSpec @@ -329,6 +332,31 @@ subroutine allocate(this, rc) _RETURN(ESMF_SUCCESS) end subroutine allocate + subroutine write_formatted(this, unit, iotype, v_list, iostat, iomsg) + class(FieldSpec), intent(in) :: this + integer, intent(in) :: unit + character(*), intent(in) :: iotype + integer, intent(in) :: v_list(:) + integer, intent(out) :: iostat + character(*), intent(inout) :: iomsg + + write(unit, "(a, a)", iostat=iostat, iomsg=iomsg) "FieldSpec(", new_line("a") + if (allocated(this%standard_name)) then + write(unit, "(3x, a, a, a)", iostat=iostat, iomsg=iomsg) "standard name:", this%standard_name, new_line("a") + end if + if (allocated(this%long_name)) then + write(unit, "(3x, a, a, a)", iostat=iostat, iomsg=iomsg) "long name:", this%long_name, new_line("a") + end if + if (allocated(this%units)) then + write(unit, "(3x, a, a, a)", iostat=iostat, iomsg=iomsg) "unit:", this%units, new_line("a") + end if + write(unit, "(3x, dt'g0', a)", iostat=iostat, iomsg=iomsg) this%vertical_dim_spec, new_line("a") + if (allocated(this%vertical_grid)) then + write(unit, "(3x, dt'g0', a)", iostat=iostat, iomsg=iomsg) this%vertical_grid, new_line("a") + end if + write(unit, "(a)") ")" + end subroutine write_formatted + function get_ungridded_bounds(this, rc) result(bounds) type(LU_Bound), allocatable :: bounds(:) type(FieldSpec), intent(in) :: this From c4c8ee5758044472d806907559644a1ee3649dac Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Mon, 28 Oct 2024 11:33:48 -0400 Subject: [PATCH 02/19] Added vertical_dim_spec to VerticalGridAdapter --- generic3g/specs/FieldSpec.F90 | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/generic3g/specs/FieldSpec.F90 b/generic3g/specs/FieldSpec.F90 index 2c762c4c41eb..a7c906cf0368 100644 --- a/generic3g/specs/FieldSpec.F90 +++ b/generic3g/specs/FieldSpec.F90 @@ -154,6 +154,7 @@ module mapl3g_FieldSpec type(ESMF_Geom), allocatable :: geom type(ESMF_TypeKind_Flag) :: typekind character(:), allocatable :: units + type(VerticalDimSpec), allocatable :: vertical_dim_spec type(VerticalRegridMethod), allocatable :: regrid_method contains procedure :: adapt_one => adapt_vertical_grid @@ -844,18 +845,20 @@ logical function adapter_match_geom(this, spec, rc) result(match) _RETURN(_SUCCESS) end function adapter_match_geom - function new_VerticalGridAdapter(vertical_grid, geom, typekind, units, regrid_method) result(vertical_grid_adapter) + function new_VerticalGridAdapter(vertical_grid, geom, typekind, units, vertical_dim_spec, regrid_method) result(vertical_grid_adapter) type(VerticalGridAdapter) :: vertical_grid_adapter class(VerticalGrid), optional, intent(in) :: vertical_grid type(ESMF_Geom), optional, intent(in) :: geom type(ESMF_Typekind_Flag), intent(in) :: typekind character(*), optional, intent(in) :: units + type(VerticalDimSpec), intent(in) :: vertical_dim_spec type(VerticalRegridMethod), optional, intent(in) :: regrid_method if (present(vertical_grid)) vertical_grid_adapter%vertical_grid = vertical_grid if (present(geom)) vertical_grid_adapter%geom = geom vertical_grid_adapter%typekind = typekind if (present(units)) vertical_grid_adapter%units = units + vertical_grid_adapter%vertical_dim_spec = vertical_dim_spec if (present(regrid_method)) vertical_grid_adapter%regrid_method = regrid_method end function new_VerticalGridAdapter @@ -873,9 +876,9 @@ subroutine adapt_vertical_grid(this, spec, action, rc) select type (spec) type is (FieldSpec) call spec%vertical_grid%get_coordinate_field(v_in_coord, v_in_coupler, & - 'ignore', spec%geom, spec%typekind, spec%units, _RC) + 'ignore', spec%geom, spec%typekind, spec%units, spec%vertical_dim_spec, _RC) call this%vertical_grid%get_coordinate_field(v_out_coord, v_out_coupler, & - 'ignore', this%geom, this%typekind, this%units, _RC) + 'ignore', this%geom, this%typekind, this%units, this%vertical_dim_spec, _RC) action = VerticalRegridAction(v_in_coord, v_out_coupler, v_out_coord, v_out_coupler, this%regrid_method) spec%vertical_grid = this%vertical_grid end select @@ -1020,14 +1023,21 @@ recursive function make_adapters(this, goal_spec, rc) result(adapters) class(StateItemSpec), intent(in) :: goal_spec integer, optional, intent(out) :: rc + type(VerticalGridAdapter) :: vertical_grid_adapter integer :: status select type (goal_spec) type is (FieldSpec) allocate(adapters(4)) allocate(adapters(1)%adapter, source=GeomAdapter(goal_spec%geom, goal_spec%regrid_param)) - allocate(adapters(2)%adapter, & - source=VerticalGridAdapter(goal_spec%vertical_grid, goal_spec%geom, goal_spec%typekind, goal_spec%units, VERTICAL_REGRID_LINEAR)) + vertical_grid_adapter = VerticalGridAdapter( & + goal_spec%vertical_grid, & + goal_spec%geom, & + goal_spec%typekind, & + goal_spec%units, & + goal_spec%vertical_dim_spec, & + VERTICAL_REGRID_LINEAR) + allocate(adapters(2)%adapter, source=vertical_grid_adapter) allocate(adapters(3)%adapter, source=TypeKindAdapter(goal_spec%typekind)) allocate(adapters(4)%adapter, source=UnitsAdapter(goal_spec%units)) type is (WildCardSpec) From d71793f9d3edb8ac216f4c48b638ac73361a84a0 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Mon, 28 Oct 2024 11:49:33 -0400 Subject: [PATCH 03/19] Added arg vertical_dim_spec to VerticalGrid::get_coordinate_field. Also overloaded write for VerticalGrid and its subclasses --- generic3g/vertical/BasicVerticalGrid.F90 | 27 ++++++++++++- .../vertical/FixedLevelsVerticalGrid.F90 | 9 +++-- generic3g/vertical/MirrorVerticalGrid.F90 | 20 +++++++++- generic3g/vertical/ModelVerticalGrid.F90 | 39 ++++++++++++------- generic3g/vertical/VerticalGrid.F90 | 17 +++++++- 5 files changed, 90 insertions(+), 22 deletions(-) diff --git a/generic3g/vertical/BasicVerticalGrid.F90 b/generic3g/vertical/BasicVerticalGrid.F90 index 3c6d9baee0a1..cd8546a46db1 100644 --- a/generic3g/vertical/BasicVerticalGrid.F90 +++ b/generic3g/vertical/BasicVerticalGrid.F90 @@ -5,6 +5,7 @@ module mapl3g_BasicVerticalGrid use mapl_ErrorHandling use mapl3g_VerticalGrid use mapl3g_GriddedComponentDriver + use mapl3g_VerticalDimSpec use esmf, only: ESMF_TypeKind_Flag use esmf, only: ESMF_Field use esmf, only: ESMF_Geom @@ -21,6 +22,7 @@ module mapl3g_BasicVerticalGrid procedure :: get_num_levels procedure :: get_coordinate_field procedure :: can_connect_to + procedure :: write_formatted end type BasicVerticalGrid interface operator(==) @@ -58,8 +60,8 @@ function get_num_levels(this) result(num_levels) class(BasicVerticalGrid), intent(in) :: this num_levels = this%num_levels end function - - subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typekind, units, rc) + + subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typekind, units, vertical_dim_spec, rc) class(BasicVerticalGrid), intent(in) :: this type(ESMF_Field), intent(out) :: field type(GriddedComponentDriver), pointer, intent(out) :: coupler @@ -67,15 +69,19 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek type(ESMF_Geom), intent(in) :: geom type(ESMF_TypeKind_Flag), intent(in) :: typekind character(*), intent(in) :: units + type(VerticalDimSpec), intent(in) :: vertical_dim_spec integer, optional, intent(out) :: rc _FAIL('BasicVerticalGrid should have been connected to a different subclass before this is called.') + + _UNUSED_DUMMY(this) _UNUSED_DUMMY(field) _UNUSED_DUMMY(coupler) _UNUSED_DUMMY(standard_name) _UNUSED_DUMMY(geom) _UNUSED_DUMMY(typekind) _UNUSED_DUMMY(units) + _UNUSED_DUMMY(vertical_dim_spec) end subroutine get_coordinate_field elemental logical function equal_to(a, b) @@ -88,4 +94,21 @@ elemental logical function not_equal_to(a, b) not_equal_to = .not. (a == b) end function not_equal_to + subroutine write_formatted(this, unit, iotype, v_list, iostat, iomsg) + class(BasicVerticalGrid), intent(in) :: this + integer, intent(in) :: unit + character(*), intent(in) :: iotype + integer, intent(in) :: v_list(:) + integer, intent(out) :: iostat + character(*), intent(inout) :: iomsg + + write(unit, "(a, a, g0, a)", iostat=iostat, iomsg=iomsg) & + "BasicVerticalGrid(", & + "num levels: ", this%num_levels, & + ")" + + _UNUSED_DUMMY(iotype) + _UNUSED_DUMMY(v_list) + end subroutine write_formatted + end module mapl3g_BasicVerticalGrid diff --git a/generic3g/vertical/FixedLevelsVerticalGrid.F90 b/generic3g/vertical/FixedLevelsVerticalGrid.F90 index 11a52b01d833..a2b67edb0d2c 100644 --- a/generic3g/vertical/FixedLevelsVerticalGrid.F90 +++ b/generic3g/vertical/FixedLevelsVerticalGrid.F90 @@ -5,7 +5,9 @@ module mapl3g_FixedLevelsVerticalGrid use mapl_ErrorHandling use mapl3g_VerticalGrid use mapl3g_GriddedComponentDriver + use mapl3g_VerticalDimSpec use esmf + use, intrinsic :: iso_fortran_env, only: REAL32 implicit none @@ -25,7 +27,6 @@ module mapl3g_FixedLevelsVerticalGrid procedure :: get_coordinate_field procedure :: can_connect_to procedure :: write_formatted - generic :: write(formatted) => write_formatted end type FixedLevelsVerticalGrid interface FixedLevelsVerticalGrid @@ -59,7 +60,7 @@ integer function get_num_levels(this) result(num_levels) num_levels = size(this%levels) end function get_num_levels - subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typekind, units, rc) + subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typekind, units, vertical_dim_spec, rc) class(FixedLevelsVerticalGrid), intent(in) :: this type(ESMF_Field), intent(out) :: field type(GriddedComponentDriver), pointer, intent(out) :: coupler @@ -67,6 +68,7 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek type(ESMF_Geom), intent(in) :: geom type(ESMF_TypeKind_Flag), intent(in) :: typekind character(*), intent(in) :: units + type(VerticalDimSpec), intent(in) :: vertical_dim_spec integer, optional, intent(out) :: rc integer :: status @@ -89,6 +91,7 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek _UNUSED_DUMMY(standard_name) _UNUSED_DUMMY(typekind) _UNUSED_DUMMY(units) + _UNUSED_DUMMY(vertical_dim_spec) end subroutine get_coordinate_field logical function can_connect_to(this, src, rc) @@ -110,7 +113,7 @@ subroutine write_formatted(this, unit, iotype, v_list, iostat, iomsg) integer, intent(out) :: iostat character(*), intent(inout) :: iomsg - write(unit, "(1x, a, a, 4x, a, a, a, 4x, a, a, a, 4x, a, *(g0, 1x), a, 1x, a)", iostat=iostat, iomsg=iomsg) & + write(unit, "(a, a, 3x, a, a, a, 3x, a, a, a, 3x, a, *(g0, 1x), a, a)", iostat=iostat, iomsg=iomsg) & "FixedLevelsVerticalGrid(", new_line("a"), & "standard name: ", this%standard_name, new_line("a"), & "units: ", this%units, new_line("a"), & diff --git a/generic3g/vertical/MirrorVerticalGrid.F90 b/generic3g/vertical/MirrorVerticalGrid.F90 index a450145da695..c1266aff89d0 100644 --- a/generic3g/vertical/MirrorVerticalGrid.F90 +++ b/generic3g/vertical/MirrorVerticalGrid.F90 @@ -10,6 +10,7 @@ module mapl3g_MirrorVerticalGrid use mapl_ErrorHandling use mapl3g_VerticalGrid use mapl3g_GriddedComponentDriver + use mapl3g_VerticalDimSpec use esmf, only: ESMF_TypeKind_Flag use esmf, only: ESMF_Field use esmf, only: ESMF_Geom @@ -25,6 +26,7 @@ module mapl3g_MirrorVerticalGrid procedure :: get_num_levels procedure :: get_coordinate_field procedure :: can_connect_to + procedure :: write_formatted end type MirrorVerticalGrid interface MirrorVerticalGrid @@ -44,7 +46,7 @@ function get_num_levels(this) result(num_levels) _UNUSED_DUMMY(this) end function - subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typekind, units, rc) + subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typekind, units, vertical_dim_spec, rc) class(MirrorVerticalGrid), intent(in) :: this type(ESMF_Field), intent(out) :: field type(GriddedComponentDriver), pointer, intent(out) :: coupler @@ -52,6 +54,7 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek type(ESMF_Geom), intent(in) :: geom type(ESMF_TypeKind_Flag), intent(in) :: typekind character(*), intent(in) :: units + type(VerticalDimSpec), intent(in) :: vertical_dim_spec integer, optional, intent(out) :: rc _FAIL('MirrorVerticalGrid should have been replaced before this procedure was called.') @@ -63,6 +66,7 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek _UNUSED_DUMMY(geom) _UNUSED_DUMMY(typekind) _UNUSED_DUMMY(units) + _UNUSED_DUMMY(vertical_dim_spec) end subroutine get_coordinate_field logical function can_connect_to(this, src, rc) @@ -77,4 +81,18 @@ logical function can_connect_to(this, src, rc) _UNUSED_DUMMY(src) end function can_connect_to + subroutine write_formatted(this, unit, iotype, v_list, iostat, iomsg) + class(MirrorVerticalGrid), intent(in) :: this + integer, intent(in) :: unit + character(*), intent(in) :: iotype + integer, intent(in) :: v_list(:) + integer, intent(out) :: iostat + character(*), intent(inout) :: iomsg + + write(unit, "(a)", iostat=iostat, iomsg=iomsg) "MirrorVerticalGrid()" + + _UNUSED_DUMMY(iotype) + _UNUSED_DUMMY(v_list) + end subroutine write_formatted + end module mapl3g_MirrorVerticalGrid diff --git a/generic3g/vertical/ModelVerticalGrid.F90 b/generic3g/vertical/ModelVerticalGrid.F90 index d913ee45ceb7..729cc3a92dbd 100644 --- a/generic3g/vertical/ModelVerticalGrid.F90 +++ b/generic3g/vertical/ModelVerticalGrid.F90 @@ -38,6 +38,7 @@ module mapl3g_ModelVerticalGrid procedure :: get_num_levels procedure :: get_coordinate_field procedure :: can_connect_to + procedure :: write_formatted ! subclass-specific methods procedure :: add_variant @@ -78,7 +79,6 @@ function new_ModelVerticalGrid_basic(num_levels) result(vgrid) !# vgrid%registry => registry end function new_ModelVerticalGrid_basic - integer function get_num_levels(this) result(num_levels) class(ModelVerticalGrid), intent(in) :: this num_levels = this%num_levels @@ -109,7 +109,7 @@ function get_registry(this) result(registry) registry => this%registry end function get_registry - subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typekind, units, rc) + subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typekind, units, vertical_dim_spec, rc) class(ModelVerticalGrid), intent(in) :: this type(ESMF_Field), intent(out) :: field type(GriddedComponentDriver), pointer, intent(out) :: coupler @@ -117,28 +117,20 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek type(ESMF_Geom), intent(in) :: geom type(ESMF_TypeKind_Flag), intent(in) :: typekind character(*), intent(in) :: units + type(VerticalDimSpec), intent(in) :: vertical_dim_spec integer, optional, intent(out) :: rc integer :: status - character(len=ESMF_MAXSTR) :: short_name + character(:), allocatable :: short_name type(VirtualConnectionPt) :: v_pt type(StateItemExtension), pointer :: new_extension class(StateItemSpec), pointer :: new_spec type(FieldSpec) :: goal_spec - type(VerticalDimSpec) :: vertical_dim_spec integer :: i short_name = this%variants%of(1) - v_pt = VirtualConnectionPt(state_intent='export', short_name=short_name) - select case (short_name) - case ("PLE") - vertical_dim_spec = VERTICAL_DIM_EDGE - case ("PL") - vertical_dim_spec = VERTICAL_DIM_CENTER - case default - _FAIL("short name should be one of PL/PLE, not" // trim(short_name)) - end select - + v_pt = VirtualConnectionPt(state_intent="export", short_name=short_name) + goal_spec = FieldSpec( & geom=geom, vertical_grid=this, vertical_dim_spec=vertical_dim_spec, & typekind=typekind, standard_name=standard_name, units=units, ungridded_dims=UngriddedDims()) @@ -150,10 +142,27 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek type is (FieldSpec) field = new_spec%get_payload() class default - _FAIL('unsupported spec type; must be FieldSpec') + _FAIL("unsupported spec type; must be FieldSpec") end select _RETURN(_SUCCESS) end subroutine get_coordinate_field + subroutine write_formatted(this, unit, iotype, v_list, iostat, iomsg) + class(ModelVerticalGrid), intent(in) :: this + integer, intent(in) :: unit + character(*), intent(in) :: iotype + integer, intent(in) :: v_list(:) + integer, intent(out) :: iostat + character(*), intent(inout) :: iomsg + + write(unit, "(a, a, g0, a)", iostat=iostat, iomsg=iomsg) & + "ModelVerticalGrid(", & + "num levels: ", this%num_levels, & + ")" + + _UNUSED_DUMMY(iotype) + _UNUSED_DUMMY(v_list) + end subroutine write_formatted + end module mapl3g_ModelVerticalGrid diff --git a/generic3g/vertical/VerticalGrid.F90 b/generic3g/vertical/VerticalGrid.F90 index 1a82ecedc020..d76689df4329 100644 --- a/generic3g/vertical/VerticalGrid.F90 +++ b/generic3g/vertical/VerticalGrid.F90 @@ -14,6 +14,8 @@ module mapl3g_VerticalGrid procedure(I_get_num_levels), deferred :: get_num_levels procedure(I_get_coordinate_field), deferred :: get_coordinate_field procedure(I_can_connect_to), deferred :: can_connect_to + procedure(I_write_formatted), deferred :: write_formatted + generic :: write(formatted) => write_formatted procedure :: set_id procedure :: get_id @@ -24,13 +26,15 @@ module mapl3g_VerticalGrid integer :: global_id = 0 abstract interface + integer function I_get_num_levels(this) result(num_levels) import VerticalGrid class(VerticalGrid), intent(in) :: this end function I_get_num_levels - subroutine I_get_coordinate_field(this, field, coupler, standard_name, geom, typekind, units, rc) + subroutine I_get_coordinate_field(this, field, coupler, standard_name, geom, typekind, units, vertical_dim_spec, rc) use mapl3g_GriddedComponentDriver + use mapl3g_VerticalDimSpec use esmf, only: ESMF_Geom, ESMF_TypeKind_Flag, ESMF_Field import VerticalGrid @@ -41,6 +45,7 @@ subroutine I_get_coordinate_field(this, field, coupler, standard_name, geom, typ type(ESMF_Geom), intent(in) :: geom type(ESMF_TypeKind_Flag), intent(in) :: typekind character(*), intent(in) :: units + type(VerticalDimSpec), intent(in) :: vertical_dim_spec integer, optional, intent(out) :: rc end subroutine I_get_coordinate_field @@ -51,6 +56,16 @@ logical function I_can_connect_to(this, src, rc) result(can_connect_to) integer, optional, intent(out) :: rc end function I_can_connect_to + subroutine I_write_formatted(this, unit, iotype, v_list, iostat, iomsg) + import VerticalGrid + class(VerticalGrid), intent(in) :: this + integer, intent(in) :: unit + character(*), intent(in) :: iotype + integer, intent(in) :: v_list(:) + integer, intent(out) :: iostat + character(*), intent(inout) :: iomsg + end subroutine I_write_formatted + end interface contains From f0f127be89142a742bf7d9dce5bed6e5ce7dd171 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Tue, 29 Oct 2024 11:58:18 -0400 Subject: [PATCH 04/19] Added arg registry to ComponentSpecParser::parse_geometry_spec to be able to create ModelVerticalGrid --- generic3g/ComponentSpecParser.F90 | 10 +++++++--- .../parse_component_spec.F90 | 5 +++-- .../parse_geometry_spec.F90 | 18 +++++++++++++++--- generic3g/OuterMetaComponent/SetServices.F90 | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/generic3g/ComponentSpecParser.F90 b/generic3g/ComponentSpecParser.F90 index efeda4b0ea96..257b66652b01 100644 --- a/generic3g/ComponentSpecParser.F90 +++ b/generic3g/ComponentSpecParser.F90 @@ -1,6 +1,7 @@ #include "MAPL_ErrLog.h" module mapl3g_ComponentSpecParser + use mapl3g_ComponentSpec use mapl3g_ChildSpec use mapl3g_ChildSpecMap @@ -23,12 +24,13 @@ module mapl3g_ComponentSpecParser use mapl3g_Stateitem use mapl3g_ESMF_Utilities use mapl3g_UserSetServices + use mapl3g_StateRegistry use gftl2_StringVector, only: StringVector use esmf + implicit none private - ! public :: parse_component_spec ! The following interfaces are public only for testing purposes. @@ -63,15 +65,17 @@ module mapl3g_ComponentSpecParser !> ! Submodule declarations INTERFACE - module function parse_component_spec(hconfig, rc) result(spec) + module function parse_component_spec(hconfig, registry, rc) result(spec) type(ComponentSpec) :: spec type(ESMF_HConfig), target, intent(inout) :: hconfig + type(StateRegistry), optional, intent(in) :: registry integer, optional, intent(out) :: rc end function parse_component_spec - module function parse_geometry_spec(mapl_cfg, rc) result(geometry_spec) + module function parse_geometry_spec(mapl_cfg, registry, rc) result(geometry_spec) type(GeometrySpec) :: geometry_spec type(ESMF_HConfig), intent(in) :: mapl_cfg + type(StateRegistry), optional, intent(in) :: registry integer, optional, intent(out) :: rc end function parse_geometry_spec diff --git a/generic3g/ComponentSpecParser/parse_component_spec.F90 b/generic3g/ComponentSpecParser/parse_component_spec.F90 index 1a3f7880c0f8..65b05fc3f737 100644 --- a/generic3g/ComponentSpecParser/parse_component_spec.F90 +++ b/generic3g/ComponentSpecParser/parse_component_spec.F90 @@ -4,9 +4,10 @@ contains - module function parse_component_spec(hconfig, rc) result(spec) + module function parse_component_spec(hconfig, registry, rc) result(spec) type(ComponentSpec) :: spec type(ESMF_HConfig), target, intent(inout) :: hconfig + type(StateRegistry), optional, intent(in) :: registry integer, optional, intent(out) :: rc integer :: status @@ -17,7 +18,7 @@ module function parse_component_spec(hconfig, rc) result(spec) _RETURN_UNLESS(has_mapl_section) mapl_cfg = ESMF_HConfigCreateAt(hconfig, keyString=MAPL_SECTION, _RC) - spec%geometry_spec = parse_geometry_spec(mapl_cfg, _RC) + spec%geometry_spec = parse_geometry_spec(mapl_cfg, registry, _RC) spec%var_specs = parse_var_specs(mapl_cfg, _RC) spec%connections = parse_connections(mapl_cfg, _RC) spec%children = parse_children(mapl_cfg, _RC) diff --git a/generic3g/ComponentSpecParser/parse_geometry_spec.F90 b/generic3g/ComponentSpecParser/parse_geometry_spec.F90 index 78f529094ace..0030c6574032 100644 --- a/generic3g/ComponentSpecParser/parse_geometry_spec.F90 +++ b/generic3g/ComponentSpecParser/parse_geometry_spec.F90 @@ -1,18 +1,22 @@ #include "MAPL_ErrLog.h" submodule (mapl3g_ComponentSpecParser) parse_geometry_spec_smod + use mapl3g_VerticalGrid use mapl3g_BasicVerticalGrid use mapl3g_FixedLevelsVerticalGrid + use mapl3g_ModelVerticalGrid + implicit none(external,type) contains ! Geom subcfg is passed raw to the GeomManager layer. So little ! processing is needed here. - module function parse_geometry_spec(mapl_cfg, rc) result(geometry_spec) + module function parse_geometry_spec(mapl_cfg, registry, rc) result(geometry_spec) type(GeometrySpec) :: geometry_spec type(ESMF_HConfig), intent(in) :: mapl_cfg + type(StateRegistry), optional, intent(in) :: registry integer, optional, intent(out) :: rc integer :: status @@ -29,7 +33,7 @@ module function parse_geometry_spec(mapl_cfg, rc) result(geometry_spec) type(GeomManager), pointer :: geom_mgr class(GeomSpec), allocatable :: geom_spec integer :: num_levels - character(:), allocatable :: vertical_grid_class, standard_name, units + character(:), allocatable :: vertical_grid_class, standard_name, units, short_name class(VerticalGrid), allocatable :: vertical_grid real, allocatable :: levels(:) @@ -102,6 +106,15 @@ module function parse_geometry_spec(mapl_cfg, rc) result(geometry_spec) units = ESMF_HConfigAsString(vertical_grid_cfg, keyString='units', _RC) levels = ESMF_HConfigAsR4Seq(vertical_grid_cfg, keyString='levels' ,_RC) vertical_grid = FixedLevelsVerticalGrid(standard_name, levels, units) + case('model') + num_levels = ESMF_HConfigAsI4(vertical_grid_cfg, keyString='num_levels', _RC) + vertical_grid = ModelVerticalGrid(num_levels=num_levels) + short_name = ESMF_HConfigAsString(vertical_grid_cfg, keyString='short_name', _RC) + select type(vertical_grid) + type is(ModelVerticalGrid) + call vertical_grid%add_variant(short_name=short_name) + call vertical_grid%set_registry(registry) + end select case default _FAIL('vertical grid class '//vertical_grid_class//' not supported') end select @@ -112,4 +125,3 @@ module function parse_geometry_spec(mapl_cfg, rc) result(geometry_spec) end function parse_geometry_spec end submodule parse_geometry_spec_smod - diff --git a/generic3g/OuterMetaComponent/SetServices.F90 b/generic3g/OuterMetaComponent/SetServices.F90 index db3b6cd49426..b97866257cfe 100644 --- a/generic3g/OuterMetaComponent/SetServices.F90 +++ b/generic3g/OuterMetaComponent/SetServices.F90 @@ -32,7 +32,7 @@ recursive module subroutine SetServices_(this, rc) integer :: status type(ESMF_GridComp) :: user_gridcomp - this%component_spec = parse_component_spec(this%hconfig, _RC) + this%component_spec = parse_component_spec(this%hconfig, this%registry, _RC) user_gridcomp = this%user_gc_driver%get_gridcomp() call attach_inner_meta(user_gridcomp, this%self_gridcomp, _RC) call this%user_setservices%run(user_gridcomp, _RC) From 4f01e1f0cd997d710c3aef0e9b138e97ffb88824 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Tue, 29 Oct 2024 11:59:21 -0400 Subject: [PATCH 05/19] Updated function FieldSpec::same_vertical_grid to handle ModelVerticalGrid --- generic3g/specs/FieldSpec.F90 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/generic3g/specs/FieldSpec.F90 b/generic3g/specs/FieldSpec.F90 index a7c906cf0368..d4e9a90af4ac 100644 --- a/generic3g/specs/FieldSpec.F90 +++ b/generic3g/specs/FieldSpec.F90 @@ -909,8 +909,9 @@ logical function same_vertical_grid(src_grid, dst_grid, rc) class(VerticalGrid), allocatable, intent(in) :: dst_grid integer, optional, intent(out) :: rc - same_vertical_grid = .true. + same_vertical_grid = .false. if (.not. allocated(dst_grid)) then + same_vertical_grid = .true. _RETURN(_SUCCESS) ! mirror grid end if @@ -932,10 +933,11 @@ logical function same_vertical_grid(src_grid, dst_grid, rc) type is(FixedLevelsVerticalGrid) same_vertical_grid = (src_grid == dst_grid) class default - _FAIL("not implemented yet") + same_vertical_grid = .false. end select class default - _FAIL("not implemented yet") + same_vertical_grid = .false. + ! _FAIL("not implemented yet") end select _RETURN(_SUCCESS) From c4c08a90da8233994d6b181985bae93bc6bb6ba4 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Tue, 29 Oct 2024 12:00:06 -0400 Subject: [PATCH 06/19] Added function shape that returns [n_rows, n_columns] --- generic3g/vertical/CSR_SparseMatrix.F90 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/generic3g/vertical/CSR_SparseMatrix.F90 b/generic3g/vertical/CSR_SparseMatrix.F90 index 54bc3768461a..2ecb78945595 100644 --- a/generic3g/vertical/CSR_SparseMatrix.F90 +++ b/generic3g/vertical/CSR_SparseMatrix.F90 @@ -18,6 +18,7 @@ module mapl3g_CSR_SparseMatrix public :: T(dp) public :: matmul public :: add_row + public :: shape integer, parameter :: sp = REAL32 integer, parameter :: dp = REAL64 @@ -43,6 +44,9 @@ module mapl3g_CSR_SparseMatrix interface add_row ;\ procedure CONCAT(add_row_,kz) ;\ end interface add_row ;\ + interface shape ;\ + procedure CONCAT(shape_, kz) ;\ + end interface shape ;\ interface T(kz) ;\ procedure CONCAT(new_csr_matrix_,kz) ;\ end interface T(kz) @@ -88,6 +92,13 @@ pure subroutine CONCAT(add_row_,kz)(this, row, start_column, v) ;\ \ end subroutine +#define SHAPE(kz) \ + pure function CONCAT(shape_, kz)(A) result(s) ;\ + type(T(kz)), intent(in) :: A ;\ + integer :: s(2) ;\ + \ + s = [A%n_rows, A%n_columns] ;\ + end function #define MATMUL_VEC(kz,kx) \ pure function CONCAT3(matmul_vec_,kz,kx)(A, x) result(y) ;\ @@ -133,6 +144,7 @@ pure function CONCAT3(matmul_multi_vec_,kz,kx)(A, x) result(b) ;\ NEW_CSR_MATRIX(sp) ADD_ROW(sp) + SHAPE(sp) MATMUL_VEC(sp,sp) MATMUL_VEC(sp,dp) MATMUL_MULTI_VEC(sp,sp) @@ -140,6 +152,7 @@ pure function CONCAT3(matmul_multi_vec_,kz,kx)(A, x) result(b) ;\ NEW_CSR_MATRIX(dp) ADD_ROW(dp) + SHAPE(dp) MATMUL_VEC(dp,sp) MATMUL_VEC(dp,dp) MATMUL_MULTI_VEC(dp,sp) From eaeb3894b800bdfc9a7625c6de04343deaf6a9f2 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Tue, 29 Oct 2024 12:01:07 -0400 Subject: [PATCH 07/19] Hack to increase number of fixed verticals levels by 1 for the case when vertical dimspec is edge --- generic3g/vertical/FixedLevelsVerticalGrid.F90 | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/generic3g/vertical/FixedLevelsVerticalGrid.F90 b/generic3g/vertical/FixedLevelsVerticalGrid.F90 index a2b67edb0d2c..7c78238d923d 100644 --- a/generic3g/vertical/FixedLevelsVerticalGrid.F90 +++ b/generic3g/vertical/FixedLevelsVerticalGrid.F90 @@ -71,19 +71,28 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek type(VerticalDimSpec), intent(in) :: vertical_dim_spec integer, optional, intent(out) :: rc + real(kind=REAL32), allocatable :: adjusted_levels(:) integer :: status + if (vertical_dim_spec == VERTICAL_DIM_CENTER) then + adjusted_levels = this%levels + else if (vertical_dim_spec == VERTICAL_DIM_EDGE) then + adjusted_levels = [this%levels, this%levels(size(this%levels))] + else + _FAIL("unsupported vertical_dim_spec") + end if + ! Add the 1D array, levels(:), to an ESMF Field field = ESMF_FieldEmptyCreate(name="FixedLevelsVerticalGrid", _RC) call ESMF_FieldEmptySet(field, geom=geom, _RC) call ESMF_FieldEmptyComplete( & field, & - farray=this%levels, & + farray=adjusted_levels, & indexflag=ESMF_INDEX_DELOCAL, & datacopyFlag=ESMF_DATACOPY_VALUE, & gridToFieldMap=[0, 0], & ungriddedLBound=[1], & - ungriddedUBound=[size(this%levels)], & + ungriddedUBound=[size(adjusted_levels)], & _RC) _RETURN(_SUCCESS) @@ -91,7 +100,6 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek _UNUSED_DUMMY(standard_name) _UNUSED_DUMMY(typekind) _UNUSED_DUMMY(units) - _UNUSED_DUMMY(vertical_dim_spec) end subroutine get_coordinate_field logical function can_connect_to(this, src, rc) From 4cb69a28e2bc0f7bb524eae86e8c84144a0c3c5c Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Tue, 29 Oct 2024 12:12:50 -0400 Subject: [PATCH 08/19] Working for the specific case where vcoord_in is (1:IM, 1:JM, :) and vcoord_out is (:) --- generic3g/actions/VerticalRegridAction.F90 | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/generic3g/actions/VerticalRegridAction.F90 b/generic3g/actions/VerticalRegridAction.F90 index 7480098b862e..08d27b692663 100644 --- a/generic3g/actions/VerticalRegridAction.F90 +++ b/generic3g/actions/VerticalRegridAction.F90 @@ -8,7 +8,7 @@ module mapl3g_VerticalRegridAction use mapl3g_CouplerPhases, only: GENERIC_COUPLER_UPDATE use mapl3g_VerticalRegridMethod use mapl3g_VerticalLinearMap, only: compute_linear_map - use mapl3g_CSR_SparseMatrix, only: SparseMatrix_sp => CSR_SparseMatrix_sp, matmul + use mapl3g_CSR_SparseMatrix, only: SparseMatrix_sp => CSR_SparseMatrix_sp, matmul, shape use mapl3g_FieldCondensedArray, only: assign_fptr_condensed_array use esmf @@ -23,7 +23,7 @@ module mapl3g_VerticalRegridAction type, extends(ExtensionAction) :: VerticalRegridAction type(ESMF_Field) :: v_in_coord, v_out_coord - type(SparseMatrix_sp) :: matrix + type(SparseMatrix_sp), allocatable :: matrix(:) type(GriddedComponentDriver), pointer :: v_in_coupler => null() type(GriddedComponentDriver), pointer :: v_out_coupler => null() type(VerticalRegridMethod) :: method = VERTICAL_REGRID_UNKNOWN @@ -65,9 +65,9 @@ subroutine initialize(this, importState, exportState, clock, rc) type(ESMF_Clock) :: clock integer, optional, intent(out) :: rc - real(ESMF_KIND_R4), pointer :: vcoord_in(:) + real(ESMF_KIND_R4), pointer :: vcoord_in(:, :, :) real(ESMF_KIND_R4), pointer :: vcoord_out(:) - integer :: status + integer :: vshape(3), i, j, IM, JM, status _ASSERT(this%method == VERTICAL_REGRID_LINEAR, "regrid method can only be linear") @@ -79,10 +79,20 @@ subroutine initialize(this, importState, exportState, clock, rc) ! call this%v_out_coupler%initialize(_RC) ! end if + ! call assign_fptr_condensed_array(this%v_in_coord, vcoord_in, _RC) + ! call assign_fptr_condensed_array(this%v_out_coord, vcoord_out, _RC) + call ESMF_FieldGet(this%v_in_coord, fArrayPtr=vcoord_in, _RC) + vshape = shape(vcoord_in) + IM = vshape(1); JM = vshape(2) call ESMF_FieldGet(this%v_out_coord, fArrayPtr=vcoord_out, _RC) + allocate(this%matrix(IM*JM)) - call compute_linear_map(vcoord_in, vcoord_out, this%matrix, RC) + do i=1,IM + do j=1,JM + call compute_linear_map(vcoord_in(i, j, :), vcoord_out(:), this%matrix(i + (j-1) * IM), _RC) + end do + end do _RETURN(_SUCCESS) end subroutine initialize @@ -116,7 +126,7 @@ subroutine update(this, importState, exportState, clock, rc) x_shape = shape(x_out) do concurrent (horz=1:x_shape(1), ungridded=1:x_shape(3)) - x_out(horz, :, ungridded) = matmul(this%matrix, x_in(horz, :, ungridded)) + x_out(horz, :, ungridded) = matmul(this%matrix(horz), x_in(horz, :, ungridded)) end do _RETURN(_SUCCESS) From 7ab85485b382391b2b0fbf43e6cebbf254680687 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Wed, 30 Oct 2024 07:57:02 -0400 Subject: [PATCH 09/19] Field created in FixedLevelsVerticalGrid needs info keys KEY_VLOC and KEY_NUM_LEVELS set --- generic3g/vertical/FixedLevelsVerticalGrid.F90 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/generic3g/vertical/FixedLevelsVerticalGrid.F90 b/generic3g/vertical/FixedLevelsVerticalGrid.F90 index 7c78238d923d..f5cb56bd03ea 100644 --- a/generic3g/vertical/FixedLevelsVerticalGrid.F90 +++ b/generic3g/vertical/FixedLevelsVerticalGrid.F90 @@ -6,6 +6,8 @@ module mapl3g_FixedLevelsVerticalGrid use mapl3g_VerticalGrid use mapl3g_GriddedComponentDriver use mapl3g_VerticalDimSpec + use mapl3g_InfoUtilities, only: MAPL_InfoSetInternal + use mapl3g_esmf_info_keys, only: KEY_VLOC, KEY_NUM_LEVELS use esmf use, intrinsic :: iso_fortran_env, only: REAL32 @@ -72,12 +74,16 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek integer, optional, intent(out) :: rc real(kind=REAL32), allocatable :: adjusted_levels(:) + character(:), allocatable :: vloc integer :: status + type(ESMF_Info) :: info if (vertical_dim_spec == VERTICAL_DIM_CENTER) then adjusted_levels = this%levels + vloc = "VERTICAL_DIM_CENTER" else if (vertical_dim_spec == VERTICAL_DIM_EDGE) then adjusted_levels = [this%levels, this%levels(size(this%levels))] + vloc = "VERTICAL_DIM_CENTER" else _FAIL("unsupported vertical_dim_spec") end if @@ -94,6 +100,8 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek ungriddedLBound=[1], & ungriddedUBound=[size(adjusted_levels)], & _RC) + call MAPL_InfoSetInternal(field, key=KEY_VLOC, value=vloc, _RC) + call MAPL_InfoSetInternal(field, key=KEY_NUM_LEVELS, value=size(adjusted_levels), _RC) _RETURN(_SUCCESS) _UNUSED_DUMMY(coupler) From 7c6240d2e7f2e986f11b42c7dbb55ce1a264d63d Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Wed, 30 Oct 2024 11:29:55 -0400 Subject: [PATCH 10/19] FixedLevelsVerticalGrid - Instead of wrapping the 1D levels(:) in an ESMF_Field, we create a 3D array where levels(:) is copied to each horz location --- .../vertical/FixedLevelsVerticalGrid.F90 | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/generic3g/vertical/FixedLevelsVerticalGrid.F90 b/generic3g/vertical/FixedLevelsVerticalGrid.F90 index f5cb56bd03ea..7342d390a424 100644 --- a/generic3g/vertical/FixedLevelsVerticalGrid.F90 +++ b/generic3g/vertical/FixedLevelsVerticalGrid.F90 @@ -3,6 +3,7 @@ module mapl3g_FixedLevelsVerticalGrid use mapl_ErrorHandling + use MAPLBase_Mod use mapl3g_VerticalGrid use mapl3g_GriddedComponentDriver use mapl3g_VerticalDimSpec @@ -73,10 +74,10 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek type(VerticalDimSpec), intent(in) :: vertical_dim_spec integer, optional, intent(out) :: rc - real(kind=REAL32), allocatable :: adjusted_levels(:) + type(ESMF_Grid) :: grid + real(kind=REAL32), allocatable :: adjusted_levels(:), farray(:, :, :) character(:), allocatable :: vloc - integer :: status - type(ESMF_Info) :: info + integer :: counts(3), IM, JM, i, j, status if (vertical_dim_spec == VERTICAL_DIM_CENTER) then adjusted_levels = this%levels @@ -88,15 +89,20 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek _FAIL("unsupported vertical_dim_spec") end if - ! Add the 1D array, levels(:), to an ESMF Field - field = ESMF_FieldEmptyCreate(name="FixedLevelsVerticalGrid", _RC) - call ESMF_FieldEmptySet(field, geom=geom, _RC) - call ESMF_FieldEmptyComplete( & - field, & - farray=adjusted_levels, & + ! Create an ESMF_Field containing the levels + ! First, copy the 1D levels array to each point on the horz grid + call ESMF_GeomGet(geom, grid=grid) + call MAPL_GridGet(grid, localCellCountPerDim=counts, _RC) + IM = counts(1); JM = counts(2) + allocate(farray(IM, JM, size(adjusted_levels))) + do concurrent (i=1:IM, j=1:JM) + farray(i, j, :) = adjusted_levels(:) + end do + field = ESMF_FieldCreate( & + geom=geom, & + farray=farray, & indexflag=ESMF_INDEX_DELOCAL, & datacopyFlag=ESMF_DATACOPY_VALUE, & - gridToFieldMap=[0, 0], & ungriddedLBound=[1], & ungriddedUBound=[size(adjusted_levels)], & _RC) From 0135752c1a46108472a65123afae5b25623d7f4a Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Wed, 30 Oct 2024 11:32:37 -0400 Subject: [PATCH 11/19] VerticalRegridAction - working version for the curated case where we have 2 gridcomps A (vertical grid: model) and B (vertical grid: fixed_levels); A exports PLE, B imports PLE --- generic3g/actions/VerticalRegridAction.F90 | 53 ++++++++++++++-------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/generic3g/actions/VerticalRegridAction.F90 b/generic3g/actions/VerticalRegridAction.F90 index 08d27b692663..1c1d57701e87 100644 --- a/generic3g/actions/VerticalRegridAction.F90 +++ b/generic3g/actions/VerticalRegridAction.F90 @@ -65,9 +65,9 @@ subroutine initialize(this, importState, exportState, clock, rc) type(ESMF_Clock) :: clock integer, optional, intent(out) :: rc - real(ESMF_KIND_R4), pointer :: vcoord_in(:, :, :) - real(ESMF_KIND_R4), pointer :: vcoord_out(:) - integer :: vshape(3), i, j, IM, JM, status + real(ESMF_KIND_R4), pointer :: v_in(:, :, :), v_out(:, :, :) + integer :: shape_in(3), shape_out(3), n_horz, n_ungridded + integer :: horz1, horz2, ungrd, ndx, status _ASSERT(this%method == VERTICAL_REGRID_LINEAR, "regrid method can only be linear") @@ -79,18 +79,25 @@ subroutine initialize(this, importState, exportState, clock, rc) ! call this%v_out_coupler%initialize(_RC) ! end if - ! call assign_fptr_condensed_array(this%v_in_coord, vcoord_in, _RC) - ! call assign_fptr_condensed_array(this%v_out_coord, vcoord_out, _RC) - - call ESMF_FieldGet(this%v_in_coord, fArrayPtr=vcoord_in, _RC) - vshape = shape(vcoord_in) - IM = vshape(1); JM = vshape(2) - call ESMF_FieldGet(this%v_out_coord, fArrayPtr=vcoord_out, _RC) - allocate(this%matrix(IM*JM)) - - do i=1,IM - do j=1,JM - call compute_linear_map(vcoord_in(i, j, :), vcoord_out(:), this%matrix(i + (j-1) * IM), _RC) + call assign_fptr_condensed_array(this%v_in_coord, v_in, _RC) + shape_in = shape(v_in) + n_horz = shape_in(1) + n_ungridded = shape_in(3) + + call assign_fptr_condensed_array(this%v_out_coord, v_out, _RC) + shape_out = shape(v_out) + _ASSERT((shape_in(1) == shape_out(1)), "horz dims are expected to be equal") + _ASSERT((shape_in(3) == shape_out(3)), "ungridded dims are expected to be equal") + + allocate(this%matrix(n_horz*n_horz)) + + ! TODO: Convert to a do concurrent loop + do horz1 = 1, n_horz + do horz2 = 1, n_horz + ndx = horz1 + (horz2 - 1) * n_horz + do ungrd = 1, n_ungridded + call compute_linear_map(v_in(horz1, :, ungrd), v_out(horz2, :, ungrd), this%matrix(ndx), _RC) + end do end do end do @@ -108,7 +115,8 @@ subroutine update(this, importState, exportState, clock, rc) integer :: status type(ESMF_Field) :: f_in, f_out real(ESMF_KIND_R4), pointer :: x_in(:,:,:), x_out(:,:,:) - integer :: x_shape(3), horz, ungridded + integer :: shape_in(3), shape_out(3), n_horz, n_ungridded + integer :: horz1, horz2, ungrd, ndx ! if (associated(this%v_in_coupler)) then ! call this%v_in_coupler%run(phase_idx=GENERIC_COUPLER_UPDATE, _RC) @@ -120,13 +128,20 @@ subroutine update(this, importState, exportState, clock, rc) call ESMF_StateGet(importState, itemName='import[1]', field=f_in, _RC) call assign_fptr_condensed_array(f_in, x_in, _RC) + shape_in = shape(x_in) + n_horz = shape_in(1) + n_ungridded = shape_in(3) call ESMF_StateGet(exportState, itemName='export[1]', field=f_out, _RC) call assign_fptr_condensed_array(f_out, x_out, _RC) + shape_out = shape(x_out) + + _ASSERT((shape_in(1) == shape_out(1)), "horz dims are expected to be equal") + _ASSERT((shape_in(3) == shape_out(3)), "ungridded dims are expected to be equal") - x_shape = shape(x_out) - do concurrent (horz=1:x_shape(1), ungridded=1:x_shape(3)) - x_out(horz, :, ungridded) = matmul(this%matrix(horz), x_in(horz, :, ungridded)) + do concurrent (horz1=1:n_horz, horz2=1:n_horz, ungrd=1:n_ungridded) + ndx = horz1 + (horz2 - 1) * n_horz + x_out(horz2, :, ungrd) = matmul(this%matrix(ndx), x_in(horz1, :, ungrd)) end do _RETURN(_SUCCESS) From 39c912f9f4ca8f6edfc098be4718ce349e9496da Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Wed, 30 Oct 2024 12:10:22 -0400 Subject: [PATCH 12/19] Test_ModelVerticalGrid.pf - added new arg vertical_dim_spec to get_coordinate_field --- generic3g/tests/Test_ModelVerticalGrid.pf | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/generic3g/tests/Test_ModelVerticalGrid.pf b/generic3g/tests/Test_ModelVerticalGrid.pf index f57f921b41c9..aaa9ef599e1b 100644 --- a/generic3g/tests/Test_ModelVerticalGrid.pf +++ b/generic3g/tests/Test_ModelVerticalGrid.pf @@ -180,7 +180,12 @@ contains call vgrid%get_coordinate_field( & vcoord, coupler, & - standard_name='air_pressure', geom=geom, typekind=ESMF_TYPEKIND_R4, units='hPa', _RC) + standard_name='air_pressure', & + geom=geom, & + typekind=ESMF_TYPEKIND_R4, & + units='hPa', & + vertical_dim_spec=VERTICAL_DIM_EDGE, & + _RC) @assert_that(associated(coupler), is(false())) call ESMF_FieldGet(vcoord, fArrayPtr=a, _RC) @@ -204,12 +209,16 @@ contains integer :: i, rc call setup("PLE", vgrid, _RC) - ! call setup("PL", 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) + standard_name='air_pressure', & + geom=geom, & + typekind=ESMF_TYPEKIND_R4, & + units='Pa', & + vertical_dim_spec=VERTICAL_DIM_EDGE, & + _RC) @assert_that(associated(coupler), is(true())) call r%allocate(_RC) @@ -248,7 +257,11 @@ contains call vgrid%get_coordinate_field( & vcoord, coupler, & - standard_name='air_pressure', geom=geom, typekind=ESMF_TYPEKIND_R4, units='Pa', _RC) + standard_name='air_pressure', & + geom=geom, & + typekind=ESMF_TYPEKIND_R4, units='Pa', & + vertical_dim_spec=VERTICAL_DIM_CENTER, & + _RC) @assert_that(associated(coupler), is(true())) call r%allocate(_RC) From 9cfa579b0189881545fad853dfd943964eaa5e86 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Wed, 30 Oct 2024 13:51:52 -0400 Subject: [PATCH 13/19] Added a new scenarios test, vertical_regridding_2, to test Model to FixedLevels regridding --- generic3g/tests/Test_Scenarios.pf | 3 ++- .../scenarios/vertical_regridding_2/A.yaml | 23 +++++++++++++++++++ .../scenarios/vertical_regridding_2/B.yaml | 23 +++++++++++++++++++ .../vertical_regridding_2/expectations.yaml | 12 ++++++++++ .../vertical_regridding_2/parent.yaml | 18 +++++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 generic3g/tests/scenarios/vertical_regridding_2/A.yaml create mode 100644 generic3g/tests/scenarios/vertical_regridding_2/B.yaml create mode 100644 generic3g/tests/scenarios/vertical_regridding_2/expectations.yaml create mode 100644 generic3g/tests/scenarios/vertical_regridding_2/parent.yaml diff --git a/generic3g/tests/Test_Scenarios.pf b/generic3g/tests/Test_Scenarios.pf index 31ad4d5e5c31..02d86694ad07 100644 --- a/generic3g/tests/Test_Scenarios.pf +++ b/generic3g/tests/Test_Scenarios.pf @@ -127,7 +127,8 @@ contains ScenarioDescription('export_dependency', 'parent.yaml', check_name, check_stateitem), & ScenarioDescription('regrid', 'cap.yaml', check_name, check_stateitem), & ScenarioDescription('propagate_geom', 'parent.yaml', check_name, check_stateitem), & - ScenarioDescription('vertical_regridding', 'parent.yaml', check_name, check_stateitem) & + ScenarioDescription('vertical_regridding', 'parent.yaml', check_name, check_stateitem), & + ScenarioDescription('vertical_regridding_2', 'parent.yaml', check_name, check_stateitem) & ] end function add_params diff --git a/generic3g/tests/scenarios/vertical_regridding_2/A.yaml b/generic3g/tests/scenarios/vertical_regridding_2/A.yaml new file mode 100644 index 000000000000..eb341a427c2a --- /dev/null +++ b/generic3g/tests/scenarios/vertical_regridding_2/A.yaml @@ -0,0 +1,23 @@ +mapl: + + geometry: + esmf_geom: + class: latlon + im_world: 12 + jm_world: 13 + pole: PC + dateline: DC + vertical_grid: + class: model + short_name: "PLE" + units: hPa + num_levels: 4 + + states: + import: {} + export: + PLE: + standard_name: "E" + units: "hPa" + default_value: 17. + vertical_dim_spec: edge diff --git a/generic3g/tests/scenarios/vertical_regridding_2/B.yaml b/generic3g/tests/scenarios/vertical_regridding_2/B.yaml new file mode 100644 index 000000000000..584e30b2809b --- /dev/null +++ b/generic3g/tests/scenarios/vertical_regridding_2/B.yaml @@ -0,0 +1,23 @@ +mapl: + + geometry: + esmf_geom: + class: latlon + im_world: 12 + jm_world: 13 + pole: PC + dateline: DC + vertical_grid: + class: fixed_levels + standard_name: air_pressure + units: hPa + levels: [17.] + + states: + import: + I: + standard_name: "I" + units: "hPa" + default_value: 1. + vertical_dim_spec: edge + export: {} diff --git a/generic3g/tests/scenarios/vertical_regridding_2/expectations.yaml b/generic3g/tests/scenarios/vertical_regridding_2/expectations.yaml new file mode 100644 index 000000000000..89ef896209c0 --- /dev/null +++ b/generic3g/tests/scenarios/vertical_regridding_2/expectations.yaml @@ -0,0 +1,12 @@ +# For each component: +# - provide a path to the outer/user componen in the hierarchy +# - list the fields expected in each import/export/internal states +# - annotate whether field is "complete" + +- component: A + export: + PLE: {status: complete} + +- component: B + import: + I: {status: complete} diff --git a/generic3g/tests/scenarios/vertical_regridding_2/parent.yaml b/generic3g/tests/scenarios/vertical_regridding_2/parent.yaml new file mode 100644 index 000000000000..a91d53f98092 --- /dev/null +++ b/generic3g/tests/scenarios/vertical_regridding_2/parent.yaml @@ -0,0 +1,18 @@ +mapl: + + children: + A: + sharedObj: libsimple_leaf_gridcomp + setServices: setservices_ + config_file: scenarios/vertical_regridding_2/A.yaml + B: + dso: libsimple_leaf_gridcomp + config_file: scenarios/vertical_regridding_2/B.yaml + + states: {} + + connections: + - src_name: PLE + dst_name: I + src_comp: A + dst_comp: B From 5b629daae28bb85049d13c881f41c9909068319c Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Wed, 30 Oct 2024 19:05:41 -0400 Subject: [PATCH 14/19] VerticalRegridAction - cleaner version using 'associate' --- generic3g/actions/VerticalRegridAction.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/generic3g/actions/VerticalRegridAction.F90 b/generic3g/actions/VerticalRegridAction.F90 index 1c1d57701e87..4a46b3b4e6aa 100644 --- a/generic3g/actions/VerticalRegridAction.F90 +++ b/generic3g/actions/VerticalRegridAction.F90 @@ -91,12 +91,14 @@ subroutine initialize(this, importState, exportState, clock, rc) allocate(this%matrix(n_horz*n_horz)) - ! TODO: Convert to a do concurrent loop + ! TODO: Convert to a `do concurrent` loop do horz1 = 1, n_horz do horz2 = 1, n_horz ndx = horz1 + (horz2 - 1) * n_horz do ungrd = 1, n_ungridded - call compute_linear_map(v_in(horz1, :, ungrd), v_out(horz2, :, ungrd), this%matrix(ndx), _RC) + associate(src => v_in(horz1, :, ungrd), dst => v_out(horz2, :, ungrd)) + call compute_linear_map(src, dst, this%matrix(ndx), _RC) + end associate end do end do end do From e4aa9155fae5b83ef8b09223db457a1f24941684 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Wed, 30 Oct 2024 19:11:46 -0400 Subject: [PATCH 15/19] FixedLevelsVerticalGrid - separate routines, esmf_field_create_ and MAPL_GeomGet_ for creating an ESMF_Field with a 'replicated' 1D array --- .../vertical/FixedLevelsVerticalGrid.F90 | 89 +++++++++++++------ 1 file changed, 63 insertions(+), 26 deletions(-) diff --git a/generic3g/vertical/FixedLevelsVerticalGrid.F90 b/generic3g/vertical/FixedLevelsVerticalGrid.F90 index 7342d390a424..d86c770ca276 100644 --- a/generic3g/vertical/FixedLevelsVerticalGrid.F90 +++ b/generic3g/vertical/FixedLevelsVerticalGrid.F90 @@ -3,7 +3,6 @@ module mapl3g_FixedLevelsVerticalGrid use mapl_ErrorHandling - use MAPLBase_Mod use mapl3g_VerticalGrid use mapl3g_GriddedComponentDriver use mapl3g_VerticalDimSpec @@ -74,40 +73,24 @@ subroutine get_coordinate_field(this, field, coupler, standard_name, geom, typek type(VerticalDimSpec), intent(in) :: vertical_dim_spec integer, optional, intent(out) :: rc - type(ESMF_Grid) :: grid - real(kind=REAL32), allocatable :: adjusted_levels(:), farray(:, :, :) + real(kind=REAL32), allocatable :: adjusted_levels(:) character(:), allocatable :: vloc - integer :: counts(3), IM, JM, i, j, status + integer :: status + ! KLUDGE - for VERTICAL_DIM_EDGE, we simply extend the the size + ! [40, 30, 20, 10] -> [40, 30, 20, 10, 10] + ! Also, vloc assignment gets simpler once we have co-located description in VerticalDimSpec if (vertical_dim_spec == VERTICAL_DIM_CENTER) then adjusted_levels = this%levels vloc = "VERTICAL_DIM_CENTER" else if (vertical_dim_spec == VERTICAL_DIM_EDGE) then adjusted_levels = [this%levels, this%levels(size(this%levels))] - vloc = "VERTICAL_DIM_CENTER" + vloc = "VERTICAL_DIM_EDGE" else - _FAIL("unsupported vertical_dim_spec") + _FAIL("invalid vertical_dim_spec") end if - ! Create an ESMF_Field containing the levels - ! First, copy the 1D levels array to each point on the horz grid - call ESMF_GeomGet(geom, grid=grid) - call MAPL_GridGet(grid, localCellCountPerDim=counts, _RC) - IM = counts(1); JM = counts(2) - allocate(farray(IM, JM, size(adjusted_levels))) - do concurrent (i=1:IM, j=1:JM) - farray(i, j, :) = adjusted_levels(:) - end do - field = ESMF_FieldCreate( & - geom=geom, & - farray=farray, & - indexflag=ESMF_INDEX_DELOCAL, & - datacopyFlag=ESMF_DATACOPY_VALUE, & - ungriddedLBound=[1], & - ungriddedUBound=[size(adjusted_levels)], & - _RC) - call MAPL_InfoSetInternal(field, key=KEY_VLOC, value=vloc, _RC) - call MAPL_InfoSetInternal(field, key=KEY_NUM_LEVELS, value=size(adjusted_levels), _RC) + field = esmf_field_create_(geom, adjusted_levels, vloc, _RC) _RETURN(_SUCCESS) _UNUSED_DUMMY(coupler) @@ -162,7 +145,61 @@ impure elemental logical function not_equal_FixedLevelsVerticalGrid(a, b) result type(FixedLevelsVerticalGrid), intent(in) :: a, b not_equal = .not. (a==b) - end function not_equal_FixedLevelsVerticalGrid + ! Create an ESMF_Field containing a 3D array that is replicated from + ! a 1D array at each point of the horizontal grid + function esmf_field_create_(geom, farray1d, vloc, rc) result(field) + type(ESMF_Field) :: field ! result + type(ESMF_Geom), intent(in) :: geom + real(kind=REAL32), intent(in) :: farray1d(:) + character(len=*), intent(in) :: vloc + integer, optional, intent(out) :: rc + + integer, allocatable :: local_cell_count(:) + real(kind=REAL32), allocatable :: farray3d(:, :, :) + integer :: i, j, IM, JM, status + + ! First, copy the 1D array, farray1d, to each point on the horz grid + call MAPL_GeomGet_(geom, localCellCount=local_cell_count, _RC) + IM = local_cell_count(1); JM = local_cell_count(2) + allocate(farray3d(IM, JM, size(farray1d))) + do concurrent (i=1:IM, j=1:JM) + farray3d(i, j, :) = farray1d(:) + end do + + ! Create an ESMF_Field containing farray3d + field = ESMF_FieldCreate( & + geom=geom, & + farray=farray3d, & + indexflag=ESMF_INDEX_DELOCAL, & + datacopyFlag=ESMF_DATACOPY_VALUE, & + ungriddedLBound=[1], & + ungriddedUBound=[size(farray1d)], & + _RC) + call MAPL_InfoSetInternal(field, key=KEY_NUM_LEVELS, value=size(farray1d), _RC) + call MAPL_InfoSetInternal(field, key=KEY_VLOC, value=vloc, _RC) + + _RETURN(_SUCCESS) + end function esmf_field_create_ + + ! Temporary version here while the detailed MAPL_GeomGet utility gets developed + subroutine MAPL_GeomGet_(geom, localCellCount, rc) + use MAPLBase_Mod + type(ESMF_Geom), intent(in) :: geom + integer, allocatable, intent(out), optional :: localCellCount(:) + integer, intent(out), optional :: rc + + type(ESMF_Grid) :: grid + integer :: status + + if (present(localCellCount)) then + call ESMF_GeomGet(geom, grid=grid) + allocate(localCellCount(3), source=-1) + call MAPL_GridGet(grid, localCellCountPerDim=localCellCount, _RC) + end if + + _RETURN(_SUCCESS) + end subroutine MAPL_GeomGet_ + end module mapl3g_FixedLevelsVerticalGrid From 579491e249c05e696ea3d282502254000c222475 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Wed, 30 Oct 2024 21:41:28 -0400 Subject: [PATCH 16/19] CSR_SparseMatrix.F90 - trying to fix syntax error flagged by GNU compiler --- generic3g/vertical/CSR_SparseMatrix.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic3g/vertical/CSR_SparseMatrix.F90 b/generic3g/vertical/CSR_SparseMatrix.F90 index 2ecb78945595..5f744edeb6c5 100644 --- a/generic3g/vertical/CSR_SparseMatrix.F90 +++ b/generic3g/vertical/CSR_SparseMatrix.F90 @@ -45,7 +45,7 @@ module mapl3g_CSR_SparseMatrix procedure CONCAT(add_row_,kz) ;\ end interface add_row ;\ interface shape ;\ - procedure CONCAT(shape_, kz) ;\ + procedure CONCAT(shape_,kz) ;\ end interface shape ;\ interface T(kz) ;\ procedure CONCAT(new_csr_matrix_,kz) ;\ @@ -93,7 +93,7 @@ pure subroutine CONCAT(add_row_,kz)(this, row, start_column, v) ;\ end subroutine #define SHAPE(kz) \ - pure function CONCAT(shape_, kz)(A) result(s) ;\ + pure function CONCAT(shape_,kz)(A) result(s) ;\ type(T(kz)), intent(in) :: A ;\ integer :: s(2) ;\ \ From dc57b482eb3918e26e50849b01fa5991cc56d151 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Fri, 1 Nov 2024 15:21:57 -0400 Subject: [PATCH 17/19] Made the methods StateRegistry::extend and StateItemExtension::make_extension recursive --- generic3g/registry/StateItemExtension.F90 | 2 +- generic3g/registry/StateRegistry.F90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/generic3g/registry/StateItemExtension.F90 b/generic3g/registry/StateItemExtension.F90 index 1cb16351f854..313dc00e6f18 100644 --- a/generic3g/registry/StateItemExtension.F90 +++ b/generic3g/registry/StateItemExtension.F90 @@ -103,7 +103,7 @@ end subroutine add_consumer ! is added to the export specs of source (this), and the new extension ! gains it as a reference (pointer). - function make_extension(this, goal, rc) result(extension) + recursive function make_extension(this, goal, rc) result(extension) type(StateItemExtension), target :: extension class(StateItemExtension), target, intent(inout) :: this class(StateItemSpec), target, intent(in) :: goal diff --git a/generic3g/registry/StateRegistry.F90 b/generic3g/registry/StateRegistry.F90 index 05d9fb3df76c..a8276cae664b 100644 --- a/generic3g/registry/StateRegistry.F90 +++ b/generic3g/registry/StateRegistry.F90 @@ -797,7 +797,7 @@ end function get_import_couplers ! Repeatedly extend family at v_pt until extension can directly ! connect to goal_spec. - function extend(registry, v_pt, goal_spec, rc) result(extension) + recursive function extend(registry, v_pt, goal_spec, rc) result(extension) use mapl3g_MultiState use mapl3g_ActualConnectionPt, only: ActualConnectionPt type(StateItemExtension), pointer :: extension From 774030e4a8057bc19c10115adde31a69b62fe628 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Fri, 1 Nov 2024 22:26:39 -0400 Subject: [PATCH 18/19] VerticalRegidAction: matrix(n_horz*nhorz) -> matrix(n_horz, n_horz) --- generic3g/actions/VerticalRegridAction.F90 | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/generic3g/actions/VerticalRegridAction.F90 b/generic3g/actions/VerticalRegridAction.F90 index 4a46b3b4e6aa..ee5c400a2092 100644 --- a/generic3g/actions/VerticalRegridAction.F90 +++ b/generic3g/actions/VerticalRegridAction.F90 @@ -23,7 +23,7 @@ module mapl3g_VerticalRegridAction type, extends(ExtensionAction) :: VerticalRegridAction type(ESMF_Field) :: v_in_coord, v_out_coord - type(SparseMatrix_sp), allocatable :: matrix(:) + type(SparseMatrix_sp), allocatable :: matrix(:, :) type(GriddedComponentDriver), pointer :: v_in_coupler => null() type(GriddedComponentDriver), pointer :: v_out_coupler => null() type(VerticalRegridMethod) :: method = VERTICAL_REGRID_UNKNOWN @@ -67,7 +67,7 @@ subroutine initialize(this, importState, exportState, clock, rc) real(ESMF_KIND_R4), pointer :: v_in(:, :, :), v_out(:, :, :) integer :: shape_in(3), shape_out(3), n_horz, n_ungridded - integer :: horz1, horz2, ungrd, ndx, status + integer :: horz1, horz2, ungrd, status _ASSERT(this%method == VERTICAL_REGRID_LINEAR, "regrid method can only be linear") @@ -89,15 +89,14 @@ subroutine initialize(this, importState, exportState, clock, rc) _ASSERT((shape_in(1) == shape_out(1)), "horz dims are expected to be equal") _ASSERT((shape_in(3) == shape_out(3)), "ungridded dims are expected to be equal") - allocate(this%matrix(n_horz*n_horz)) + allocate(this%matrix(n_horz, n_horz)) ! TODO: Convert to a `do concurrent` loop do horz1 = 1, n_horz do horz2 = 1, n_horz - ndx = horz1 + (horz2 - 1) * n_horz do ungrd = 1, n_ungridded associate(src => v_in(horz1, :, ungrd), dst => v_out(horz2, :, ungrd)) - call compute_linear_map(src, dst, this%matrix(ndx), _RC) + call compute_linear_map(src, dst, this%matrix(horz1, horz2), _RC) end associate end do end do @@ -118,7 +117,7 @@ subroutine update(this, importState, exportState, clock, rc) type(ESMF_Field) :: f_in, f_out real(ESMF_KIND_R4), pointer :: x_in(:,:,:), x_out(:,:,:) integer :: shape_in(3), shape_out(3), n_horz, n_ungridded - integer :: horz1, horz2, ungrd, ndx + integer :: horz1, horz2, ungrd ! if (associated(this%v_in_coupler)) then ! call this%v_in_coupler%run(phase_idx=GENERIC_COUPLER_UPDATE, _RC) @@ -142,8 +141,7 @@ subroutine update(this, importState, exportState, clock, rc) _ASSERT((shape_in(3) == shape_out(3)), "ungridded dims are expected to be equal") do concurrent (horz1=1:n_horz, horz2=1:n_horz, ungrd=1:n_ungridded) - ndx = horz1 + (horz2 - 1) * n_horz - x_out(horz2, :, ungrd) = matmul(this%matrix(ndx), x_in(horz1, :, ungrd)) + x_out(horz2, :, ungrd) = matmul(this%matrix(horz1, horz2), x_in(horz1, :, ungrd)) end do _RETURN(_SUCCESS) From 6ee28a442402e7e8896fb5c09813cd13d189f7e6 Mon Sep 17 00:00:00 2001 From: Purnendu Chakraborty Date: Sat, 2 Nov 2024 19:07:12 -0400 Subject: [PATCH 19/19] Added test for the case when Model VerticalGrid is ZLE --- .../scenarios/vertical_regridding_2/A.yaml | 4 ++-- .../scenarios/vertical_regridding_2/C.yaml | 23 +++++++++++++++++++ .../scenarios/vertical_regridding_2/D.yaml | 23 +++++++++++++++++++ .../vertical_regridding_2/expectations.yaml | 8 +++++++ .../vertical_regridding_2/parent.yaml | 15 +++++++++++- 5 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 generic3g/tests/scenarios/vertical_regridding_2/C.yaml create mode 100644 generic3g/tests/scenarios/vertical_regridding_2/D.yaml diff --git a/generic3g/tests/scenarios/vertical_regridding_2/A.yaml b/generic3g/tests/scenarios/vertical_regridding_2/A.yaml index eb341a427c2a..e8f3bc009247 100644 --- a/generic3g/tests/scenarios/vertical_regridding_2/A.yaml +++ b/generic3g/tests/scenarios/vertical_regridding_2/A.yaml @@ -10,7 +10,7 @@ mapl: vertical_grid: class: model short_name: "PLE" - units: hPa + units: "hPa" num_levels: 4 states: @@ -20,4 +20,4 @@ mapl: standard_name: "E" units: "hPa" default_value: 17. - vertical_dim_spec: edge + vertical_dim_spec: "edge" diff --git a/generic3g/tests/scenarios/vertical_regridding_2/C.yaml b/generic3g/tests/scenarios/vertical_regridding_2/C.yaml new file mode 100644 index 000000000000..bd0e2b768bf6 --- /dev/null +++ b/generic3g/tests/scenarios/vertical_regridding_2/C.yaml @@ -0,0 +1,23 @@ +mapl: + + geometry: + esmf_geom: + class: latlon + im_world: 2 + jm_world: 3 + pole: PC + dateline: DC + vertical_grid: + class: model + short_name: ZLE + units: m + num_levels: 4 + + states: + import: {} + export: + ZLE: + standard_name: E + units: m + default_value: 17. + vertical_dim_spec: edge diff --git a/generic3g/tests/scenarios/vertical_regridding_2/D.yaml b/generic3g/tests/scenarios/vertical_regridding_2/D.yaml new file mode 100644 index 000000000000..70724ab2e38b --- /dev/null +++ b/generic3g/tests/scenarios/vertical_regridding_2/D.yaml @@ -0,0 +1,23 @@ +mapl: + + geometry: + esmf_geom: + class: latlon + im_world: 2 + jm_world: 3 + pole: PC + dateline: DC + vertical_grid: + class: fixed_levels + standard_name: height + units: m + levels: [17.] + + states: + import: + I: + standard_name: I + units: m + default_value: 1. + vertical_dim_spec: edge + export: {} diff --git a/generic3g/tests/scenarios/vertical_regridding_2/expectations.yaml b/generic3g/tests/scenarios/vertical_regridding_2/expectations.yaml index 89ef896209c0..547929d57d9c 100644 --- a/generic3g/tests/scenarios/vertical_regridding_2/expectations.yaml +++ b/generic3g/tests/scenarios/vertical_regridding_2/expectations.yaml @@ -10,3 +10,11 @@ - component: B import: I: {status: complete} + +- component: C + export: + ZLE: {status: complete} + +- component: D + import: + I: {status: complete} diff --git a/generic3g/tests/scenarios/vertical_regridding_2/parent.yaml b/generic3g/tests/scenarios/vertical_regridding_2/parent.yaml index a91d53f98092..20861d3a051e 100644 --- a/generic3g/tests/scenarios/vertical_regridding_2/parent.yaml +++ b/generic3g/tests/scenarios/vertical_regridding_2/parent.yaml @@ -6,8 +6,17 @@ mapl: setServices: setservices_ config_file: scenarios/vertical_regridding_2/A.yaml B: - dso: libsimple_leaf_gridcomp + sharedObj: libsimple_leaf_gridcomp + setServices: setservices_ config_file: scenarios/vertical_regridding_2/B.yaml + C: + sharedObj: libsimple_leaf_gridcomp + setServices: setservices_ + config_file: scenarios/vertical_regridding_2/C.yaml + D: + sharedObj: libsimple_leaf_gridcomp + setServices: setservices_ + config_file: scenarios/vertical_regridding_2/D.yaml states: {} @@ -16,3 +25,7 @@ mapl: dst_name: I src_comp: A dst_comp: B + - src_name: ZLE + dst_name: I + src_comp: C + dst_comp: D