Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/wdboggs/add reference time for timestep 3322 #3349

Open
wants to merge 4 commits into
base: release/MAPL-v3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add FrequencyAspect
- Remove MAPL `==` and `/=` for `ESMF_Geom`
- NOTE: This *requires* ESMF 8.8.0 or later
- Add timestep_start

### Changed

Expand Down
4 changes: 3 additions & 1 deletion generic3g/ComponentSpecParser.F90
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ module mapl3g_ComponentSpecParser
character(*), parameter :: KEY_VERTICAL_DIM_SPEC = 'vertical_dim_spec'
character(*), parameter :: KEY_ACCUMULATION_TYPE = 'accumulation_type'
character(*), parameter :: KEY_TIMESTEP = 'timestep'
character(*), parameter :: KEY_TIMESTEP_START = 'timestep_start'

!>
! Submodule declarations
Expand Down Expand Up @@ -112,9 +113,10 @@ module function parse_child(hconfig, rc) result(child)
integer, optional, intent(out) :: rc
end function parse_child

module subroutine parse_timestep(hconfig, timestep, rc)
module subroutine parse_timestep(hconfig, timestep, start, rc)
type(ESMF_HConfig), intent(in) :: hconfig
type(ESMF_TimeInterval), allocatable, intent(inout) :: timestep
type(ESMF_Time), allocatable, intent(inout) :: start
integer, optional, intent(out) :: rc
end subroutine parse_timestep

Expand Down
2 changes: 1 addition & 1 deletion generic3g/ComponentSpecParser/parse_component_spec.F90
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module function parse_component_spec(hconfig, registry, rc) result(spec)
spec%var_specs = parse_var_specs(mapl_cfg, _RC)
spec%connections = parse_connections(mapl_cfg, _RC)
spec%children = parse_children(mapl_cfg, _RC)
call parse_timestep(mapl_cfg, spec%timestep, _RC)
call parse_timestep(mapl_cfg, spec%timestep, spec%timestep_start, _RC)

call ESMF_HConfigDestroy(mapl_cfg, _RC)

Expand Down
18 changes: 13 additions & 5 deletions generic3g/ComponentSpecParser/parse_timestep.F90
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
#include "MAPL_ErrLog.h"

submodule (mapl3g_ComponentSpecParser) parse_timestep_smod
use MAPL_TimeStringConversion, only: parse_isostring => string_to_esmf_timeinterval
use MAPL_TimeStringConversion, only: string_to_esmf_timeinterval, string_to_esmf_time
contains

module subroutine parse_timestep(hconfig, timestep, rc)
module subroutine parse_timestep(hconfig, timestep, start, rc)
type(ESMF_HConfig), intent(in) :: hconfig
type(ESMF_TimeInterval), allocatable, intent(inout) :: timestep
type(ESMF_Time), allocatable, intent(inout) :: start
integer, optional, intent(out) :: rc

integer :: status
logical :: has_timestep
character(len=:), allocatable :: iso_duration
logical :: has_timestep, has_start
character(len=32) :: iso_datetime
character(len=128) :: iso_duration

has_timestep = ESMF_HConfigIsDefined(hconfig, keyString=KEY_TIMESTEP, _RC)
_RETURN_UNLESS(has_timestep)
iso_duration = ESMF_HConfigAsString(hconfig, keyString=KEY_TIMESTEP, _RC)
timestep = parse_isostring(iso_duration, _RC)
timestep = string_to_esmf_timeinterval(trim(iso_duration), _RC)

has_start = ESMF_HConfigIsDefined(hconfig, keyString=KEY_TIMESTEP_START, _RC)
_RETURN_UNLESS(has_start)
iso_datetime = ESMF_HConfigAsString(hconfig, keyString=KEY_TIMESTEP_START, _RC)
start = string_to_esmf_time(iso_datetime, _RC)

_RETURN(_SUCCESS)

end subroutine parse_timestep
Expand Down
1 change: 1 addition & 0 deletions generic3g/specs/ComponentSpec.F90
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module mapl3g_ComponentSpec
type(ChildSpecMap) :: children
type(ESMF_HConfig), allocatable :: geom_hconfig ! optional
type(ESMF_TimeInterval), allocatable :: timestep
type(ESMF_Time), allocatable :: timestep_start
contains
procedure :: has_geom_hconfig
procedure :: add_var_spec
Expand Down
32 changes: 18 additions & 14 deletions generic3g/tests/Test_ComponentSpecParser.pf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Test_ComponentSpecParser
use mapl3g_ChildSpec
use mapl3g_ChildSpecMap
use mapl_ErrorHandling
use MAPL_TimeStringConversion
use esmf
implicit none

Expand Down Expand Up @@ -182,34 +183,37 @@ contains

@test
subroutine test_parse_timestep()
integer(kind=ESMF_KIND_I4) :: d(6)
integer(kind=ESMF_KIND_I4), parameter :: IMM=3
integer(kind=ESMF_KIND_I4), parameter :: MM=10
integer(kind=ESMF_KIND_I4), parameter :: YY=1582
integer(kind=ESMF_KIND_I4), parameter :: DD=15
type(ESMF_TimeInterval) :: expected
character(len=:), allocatable :: iso_duration
type(ESMF_Time) :: expected_start
character(len=*), parameter :: iso_duration = 'P3M'
character(len=*), parameter :: iso_time = '1582-10-15'
character(len=*), parameter :: NL = new_line('NL')
character(len=:), allocatable :: content
type(ESMF_HConfig) :: hconfig
type(ESMF_TimeInterval), allocatable :: actual
type(ESMF_Time), allocatable :: actual_start
integer :: rc, status
character(len=:), allocatable :: msg
character(len=ESMF_MAXSTR) :: expected_timestring, actual_timestring

! Test with correct key for timestep
d = [10, 3, 7, 13, 57, 32]
call ESMF_TimeIntervalSet(expected, yy=d(1), mm=d(2), d=d(3), h=d(4), m=d(5), s=d(6), _RC)
iso_duration = 'P10Y3M7DT13H57M32S'
content = 'timestep: ' // iso_duration
call ESMF_TimeIntervalSet(expected, mm=IMM, _RC)
call ESMF_TimeSet(expected_start, yy=YY, mm=MM, dd=DD, _RC)
content = 'timestep: ' // iso_duration // NL // 'timestep_start: ' // iso_time
hconfig = ESMF_HConfigCreate(content=content, _RC)
call parse_timestep(hconfig, actual, _RC)
call ESMF_TimeIntervalGet(expected, timeString=expected_timestring, _RC)
call ESMF_TimeIntervalGet(actual, timeString=actual_timestring, _RC)
msg = trim(actual_timestring) // ' /= ' // trim(expected_timestring)
@assertTrue(actual == expected, msg)
call parse_timestep(hconfig, actual, actual_start, _RC)
@assertTrue(actual == expected, 'Actual timestep does not match expected timestep.')
@assertTrue(actual_start == expected_start, 'Actual timestep start does not match expected timestep start.')
call ESMF_HConfigDestroy(hconfig, _RC)

! Test with incorrect key for timestep; should return without setting actual (invalid)
content = 'run_dmc: ' // iso_duration
hconfig = ESMF_HConfigCreate(content=content, _RC)
deallocate(actual)
call parse_timestep(hconfig, actual, _RC)
deallocate(actual_start)
call parse_timestep(hconfig, actual, actual_start, _RC)
@assert_that(allocated(actual), is(false()))
call ESMF_HConfigDestroy(hconfig, _RC)

Expand Down
Loading