Skip to content

Commit

Permalink
Merge pull request #3300 from GEOS-ESM/feature/pchakrab/configurable-…
Browse files Browse the repository at this point in the history
…gridcomp-read-k-values

Allow Configurable gridcomp to read k values from config file
  • Loading branch information
tclune authored Jan 10, 2025
2 parents 80afc89 + bca4af6 commit 4bb6d82
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 55 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ add_subdirectory (generic)
add_subdirectory (generic3g)
add_subdirectory (field)
add_subdirectory (field_bundle)
add_subdirectory (state)
add_subdirectory (oomph) # temporary - will rename to generic when done
add_subdirectory (shared)
add_subdirectory (include)
Expand Down
2 changes: 1 addition & 1 deletion generic3g/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ endif ()

esma_add_library(${this}
SRCS ${srcs}
DEPENDENCIES MAPL.regridder_mgr MAPL.geom_mgr MAPL.GeomIO MAPL.esmf_utils MAPL.field MAPL.shared MAPL.profiler MAPL.base MAPL.hconfig_utils
DEPENDENCIES MAPL.regridder_mgr MAPL.geom_mgr MAPL.GeomIO MAPL.esmf_utils MAPL.field MAPL.state MAPL.shared MAPL.profiler MAPL.base MAPL.hconfig_utils
ESMF::ESMF NetCDF::NetCDF_Fortran udunits2f PFLOGGER::pflogger GFTL_SHARED::gftl-shared-v2 GFTL::gftl-v2
TYPE SHARED
)
Expand Down
36 changes: 2 additions & 34 deletions generic3g/RestartHandler.F90
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module mapl3g_RestartHandler
use mapl_ErrorHandling, only: MAPL_Verify, MAPL_Return, MAPL_Assert
use mapl3g_geomio, only: bundle_to_metadata, GeomPFIO, make_geom_pfio, get_mapl_geom
use mapl3g_SharedIO, only: esmf_to_pfio_type
use mapl3g_StateGet, only: MAPL_StateGet
use pFIO, only: PFIO_READ, FileMetaData, NetCDF4_FileFormatter
use pFIO, only: i_Clients, o_Clients
use pFlogger, only: logging, logger
Expand Down Expand Up @@ -70,7 +71,7 @@ subroutine write(this, state_type, state, rc)
! TODO: the file_name should come from OuterMetaComponents's hconfig
file_name = trim(this%gc_name) // "_" // trim(state_type) // "_checkpoint.nc4"
call this%lgr%info("Writing checkpoint: %a", trim(file_name))
out_bundle = get_bundle_from_state_(state, _RC)
out_bundle = MAPL_StateGet(state, _RC)
call this%write_bundle_(out_bundle, file_name, rc)
end if

Expand Down Expand Up @@ -106,39 +107,6 @@ subroutine read(this, state_type, state, rc)
_RETURN(_SUCCESS)
end subroutine read

type(ESMF_FieldBundle) function get_bundle_from_state_(state, rc) result(bundle)
! Arguments
type(ESMF_State), intent(in) :: state
integer, optional, intent(out) :: rc

! Locals
character(len=ESMF_MAXSTR), allocatable :: item_name(:)
type (ESMF_StateItem_Flag), allocatable :: item_type(:)
type(ESMF_Field) :: field
type(ESMF_FieldStatus_Flag) :: field_status
integer :: item_count, idx, status

! bundle to pack fields in
bundle = ESMF_FieldBundleCreate(_RC)
call ESMF_StateGet(state, itemCount=item_count, _RC)
allocate(item_name(item_count), _STAT)
allocate(item_type(item_count), _STAT)
call ESMF_StateGet(state, itemNameList=item_name, itemTypeList=item_type, _RC)
do idx = 1, item_count
if (item_type(idx) /= ESMF_STATEITEM_FIELD) then
_FAIL("FieldBundle has not been implemented yet")
end if
call ESMF_StateGet(state, item_name(idx), field, _RC)
call ESMF_FieldGet(field, status=field_status, _RC)
if (field_status == ESMF_FIELDSTATUS_COMPLETE) then
call ESMF_FieldBundleAdd(bundle, [field], _RC)
end if
end do
deallocate(item_name, item_type, _STAT)

_RETURN(_SUCCESS)
end function get_bundle_from_state_

subroutine write_bundle_(this, bundle, file_name, rc)
! Arguments
class(RestartHandler), intent(in) :: this
Expand Down
20 changes: 10 additions & 10 deletions generic3g/tests/Test_Scenarios.pf
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ contains
params = [params, add_params('field status', check_field_status)]
params = [params, add_params('field typekind', check_field_typekind)]
params = [params, add_params('field value', check_field_value)]
params = [params, add_params('field k_values', check_field_k_values)]
params = [params, add_params('field vertical_profile', check_field_vertical_profile)]
params = [params, add_params('field exists', check_field_rank)]

! Service oriented tests
Expand Down Expand Up @@ -515,14 +515,14 @@ contains
rc = 0
end subroutine check_field_value

subroutine check_field_k_values(expectations, state, short_name, description, rc)
subroutine check_field_vertical_profile(expectations, state, short_name, description, rc)
type(ESMF_HConfig), intent(in) :: expectations
type(ESMF_State), intent(inout) :: state
character(*), intent(in) :: short_name
character(*), intent(in) :: description
integer, intent(out) :: rc

real, allocatable :: expected_k_values(:)
real, allocatable :: expected_vertical_profile(:)
integer :: rank
type(ESMF_TypeKind_Flag) :: typekind
integer :: status
Expand All @@ -539,12 +539,12 @@ contains
return
end if
if (.not. ESMF_HConfigIsDefined(expectations,keyString='k_values')) then
if (.not. ESMF_HConfigIsDefined(expectations,keyString='vertical_profile')) then
rc = 0
return
end if
expected_k_values = ESMF_HConfigAsR4Seq(expectations,keyString='k_values',_RC)
expected_vertical_profile = ESMF_HConfigAsR4Seq(expectations,keyString='vertical_profile',_RC)
call ESMF_StateGet(state, short_name, field, _RC)
call ESMF_FieldGet(field, typekind=typekind, rank=rank, rc=status)
Expand All @@ -559,7 +559,7 @@ contains
shape3 = shape(x3)
do i = 1, shape3(1)
do j = 1, shape3(2)
@assert_that("value of "//short_name, x3(i, j, :), is(equal_to(expected_k_values)))
@assert_that("value of "//short_name, x3(i, j, :), is(equal_to(expected_vertical_profile)))
end do
end do
case(4)
Expand All @@ -568,7 +568,7 @@ contains
do i = 1, shape4(1)
do j = 1, shape4(2)
do l = 1, shape4(4)
@assert_that("value of "//short_name, x4(i, j, :, l), is(equal_to(expected_k_values)))
@assert_that("value of "//short_name, x4(i, j, :, l), is(equal_to(expected_vertical_profile)))
end do
end do
end do
Expand All @@ -585,7 +585,7 @@ contains
shape3 = shape(x3)
do i = 1, shape3(1)
do j = 1, shape3(2)
@assert_that("value of "//short_name, x3(i, j, :), is(equal_to(expected_k_values)))
@assert_that("value of "//short_name, x3(i, j, :), is(equal_to(expected_vertical_profile)))
end do
end do
case(4)
Expand All @@ -594,7 +594,7 @@ contains
do i = 1, shape4(1)
do j = 1, shape4(2)
do l = 1, shape4(4)
@assert_that("value of "//short_name, x4(i, j, :, l), is(equal_to(expected_k_values)))
@assert_that("value of "//short_name, x4(i, j, :, l), is(equal_to(expected_vertical_profile)))
end do
end do
end do
Expand All @@ -607,7 +607,7 @@ contains
end if
rc = 0
end subroutine check_field_k_values
end subroutine check_field_vertical_profile
subroutine check_field_rank(expectations, state, short_name, description, rc)
type(ESMF_HConfig), intent(in) :: expectations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
- component: DYN
export:
PL: {status: complete}
T_DYN: {status: complete, typekind: R4, rank: 3, k_values: [40., 20., 10., 5.]}
T_DYN: {status: complete, typekind: R4, rank: 3, vertical_profile: [40., 20., 10., 5.]}

- component: PHYS
import:
T_PHYS: {status: complete, typekind: R4, rank: 3, k_values: [18., 6.]}
T_PHYS: {status: complete, typekind: R4, rank: 3, vertical_profile: [18., 6.]}

- component: C
import:
I_C: {status: complete, typekind: R4, rank: 3, k_values: [40., 20., 10.]}
I_C: {status: complete, typekind: R4, rank: 3, vertical_profile: [40., 20., 10.]}
2 changes: 1 addition & 1 deletion gridcomps/configurable/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ esma_set_this (OVERRIDE configurable_gridcomp)

esma_add_library(${this}
SRCS ConfigurableGridComp.F90
DEPENDENCIES MAPL.generic3g
DEPENDENCIES MAPL.generic3g MAPL
TYPE SHARED)
54 changes: 48 additions & 6 deletions gridcomps/configurable/ConfigurableGridComp.F90
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
#include "MAPL_Generic.h"

module ConfigurableGridComp
module mapl3g_ConfigurableGridComp

use mapl_ErrorHandling
use mapl3g_Generic, only: MAPL_GridCompSetEntryPoint, MAPL_RunChildren
use mapl3g_Generic, only: MAPL_GridCompGet
use mapl, only: MAPL_GetPointer
use esmf

implicit none
private

public :: setServices

character(*), parameter :: MAPL_SECTION = "mapl"
character(*), parameter :: COMPONENT_STATES_SECTION = "states"
character(*), parameter :: COMPONENT_EXPORT_STATE_SECTION = "export"
character(*), parameter :: KEY_DEFAULT_VERT_PROFILE = "default_vertical_profile"

contains

subroutine setServices(gridcomp, rc)
Expand All @@ -32,12 +39,47 @@ subroutine init(gridcomp, importState, exportState, clock, rc)
type(ESMF_Clock) :: clock
integer, intent(out) :: rc

integer :: status
character(:), allocatable :: field_name
type(ESMF_HConfig) :: hconfig, mapl_cfg, states_cfg, export_cfg, field_cfg
logical :: has_export_section, has_default_vert_profile
real(kind=ESMF_KIND_R4), allocatable :: default_vert_profile(:)
real(kind=ESMF_KIND_R4), pointer :: ptr3d(:, :, :)
integer :: ii, jj, shape_(3), status

type(ESMF_HConfigIter) :: iter, e, b

call MAPL_GridCompGet(gridcomp, hconfig=hconfig, _RC)
! ASSUME: mapl and states sections always exist
mapl_cfg = ESMF_HConfigCreateAt(hconfig, keyString=MAPL_SECTION, _RC)
states_cfg = ESMF_HConfigCreateAt(mapl_cfg, keyString=COMPONENT_STATES_SECTION, _RC)
has_export_section = ESMF_HConfigIsDefined(states_cfg, keyString=COMPONENT_EXPORT_STATE_SECTION, _RC)
_RETURN_UNLESS(has_export_section)

! For each field getting 'export'ed, check hconfig and use default_vert_profile if specified
export_cfg = ESMF_HConfigCreateAt(states_cfg, keyString=COMPONENT_EXPORT_STATE_SECTION, _RC)
b = ESMF_HConfigIterBegin(export_cfg, _RC)
e = ESMF_HConfigIterEnd(export_cfg, _RC)
iter = b
do while (ESMF_HConfigIterLoop(iter, b, e))
field_name = ESMF_HConfigAsStringMapKey(iter, _RC)
! print *, "FIELD: ", field_name
field_cfg = ESMF_HConfigCreateAtMapVal(iter, _RC)
has_default_vert_profile = ESMF_HConfigIsDefined(field_cfg, keyString=KEY_DEFAULT_VERT_PROFILE, _RC)
if (has_default_vert_profile) then
default_vert_profile = ESMF_HConfigAsR4Seq(field_cfg, keyString=KEY_DEFAULT_VERT_PROFILE, _RC)
call MAPL_GetPointer(exportState, ptr3d, trim(field_name), _RC)
shape_ = shape(ptr3d)
_ASSERT(shape_(3) == size(default_vert_profile), "incorrect size of vertical profile")
print *, ptr3d(1, 4, 3)
do concurrent(ii = 1:shape_(1), jj=1:shape_(2))
ptr3d(ii, jj, :) = default_vert_profile
end do
print *, ptr3d(1, 4, 3)
end if
end do

_RETURN(_SUCCESS)
_UNUSED_DUMMY(gridcomp)
_UNUSED_DUMMY(importState)
_UNUSED_DUMMY(exportState)
_UNUSED_DUMMY(clock)
end subroutine init

Expand All @@ -58,12 +100,12 @@ recursive subroutine run(gridcomp, importState, exportState, clock, rc)
_UNUSED_DUMMY(clock)
end subroutine run

end module ConfigurableGridComp
end module Mapl3g_ConfigurableGridComp

subroutine setServices(gridcomp, rc)
use ESMF
use MAPL_ErrorHandlingMod
use ConfigurableGridComp, only: Configurable_setServices => SetServices
use mapl3g_ConfigurableGridComp, only: Configurable_setServices => SetServices
type(ESMF_GridComp) :: gridcomp
integer, intent(out) :: rc

Expand Down
21 changes: 21 additions & 0 deletions state/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
esma_set_this (OVERRIDE MAPL.state)

set(srcs
StateGet.F90
)

list (APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")

if (BUILD_WITH_PFLOGGER)
find_package (PFLOGGER REQUIRED)
endif ()

esma_add_library(${this}
SRCS ${srcs}
DEPENDENCIES MAPL.shared ESMF::ESMF
TYPE SHARED
)

# if (PFUNIT_FOUND)
# add_subdirectory(tests EXCLUDE_FROM_ALL)
# endif ()
50 changes: 50 additions & 0 deletions state/StateGet.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "MAPL_Generic.h"

module mapl3g_StateGet

use mapl_ErrorHandling
use esmf

implicit none
private

public :: MAPL_StateGet

interface MAPL_StateGet
procedure get_bundle_from_state_
end interface MAPL_StateGet

contains

type(ESMF_FieldBundle) function get_bundle_from_state_(state, rc) result(bundle)
type(ESMF_State), intent(in) :: state
integer, optional, intent(out) :: rc

character(len=ESMF_MAXSTR), allocatable :: item_name(:)
type (ESMF_StateItem_Flag), allocatable :: item_type(:)
type(ESMF_Field) :: field
type(ESMF_FieldStatus_Flag) :: field_status
integer :: item_count, idx, status

! bundle to pack fields in
bundle = ESMF_FieldBundleCreate(_RC)
call ESMF_StateGet(state, itemCount=item_count, _RC)
allocate(item_name(item_count), _STAT)
allocate(item_type(item_count), _STAT)
call ESMF_StateGet(state, itemNameList=item_name, itemTypeList=item_type, _RC)
do idx = 1, item_count
if (item_type(idx) /= ESMF_STATEITEM_FIELD) then
_FAIL("FieldBundle has not been implemented yet")
end if
call ESMF_StateGet(state, item_name(idx), field, _RC)
call ESMF_FieldGet(field, status=field_status, _RC)
if (field_status == ESMF_FIELDSTATUS_COMPLETE) then
call ESMF_FieldBundleAdd(bundle, [field], _RC)
end if
end do
deallocate(item_name, item_type, _STAT)

_RETURN(_SUCCESS)
end function get_bundle_from_state_

end module mapl3g_StateGet

0 comments on commit 4bb6d82

Please sign in to comment.