subroutine SetServices(xdata, rc)
! arguments
type(ESMF_GridComp) :: xdata
integer, intent(out) :: rc
! local variables
integer :: stat
type(xstate_wrap) :: is
type(xdata_state), pointer :: xstate
character(len=64) :: value
type(ESMF_Config) :: config
type(ESMF_HConfig) :: hconfig, hconfigNode
character(80) :: compLabel
character(:), allocatable :: badKey
logical :: isFlag
rc = ESMF_SUCCESS
! derive generic model phases
call NUOPC_CompDerive(xdata, modelSS, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
! allocate memory for this internal state and set it in the component
allocate(is%ptr, stat=stat)
if (ESMF_LogFoundAllocError(statusToCheck=stat, &
msg='XDATA: Memory allocation failed.', &
line=__LINE__, &
file=__FILE__, &
rcToReturn=rc)) return
call ESMF_GridCompSetInternalState(xdata, is, rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
xstate => is%ptr
if (.not. associated(xstate)) then
call ESMF_LogSetError(ESMF_RC_PTR_NOTALLOC, &
msg='XDATA: xstate has not been associated', &
line=__LINE__, file=__FILE__, rcToReturn=rc)
return
endif
! query component for information
call NUOPC_CompGet(xdata, name=xstate%cname, &
verbosity=xstate%verbosity, diagnostic=xstate%diagnostic, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
! specialize model
call NUOPC_CompSpecialize(xdata, specLabel=label_Advertise, &
specRoutine=Advertise, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
call NUOPC_CompSpecialize(xdata, specLabel=label_RealizeProvided, &
specRoutine=Realize, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
call NUOPC_CompSpecialize(xdata, specLabel=label_DataInitialize, &
specRoutine=DataInitialize, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
call NUOPC_CompSpecialize(xdata, specLabel=label_CheckImport, &
specRoutine=CheckImport, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
call NUOPC_CompSpecialize(xdata, specLabel=label_Advance, &
specRoutine=ModelAdvance, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
call NUOPC_CompSpecialize(xdata, specLabel=label_Finalize, &
specRoutine=ModelFinalize, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
! query component for vm and local pet
call ESMF_GridCompGet(xdata, vm=xstate%vm, &
localPet=xstate%myid, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
! validate config
call ESMF_GridCompGet(xdata, name=compLabel, configIsPresent=isFlag, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
if (isFlag) then
! Config present, assert it is in the ESMX YAML format
call ESMF_GridCompGet(xdata, config=config, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
call ESMF_ConfigGet(config, hconfig=hconfig, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
hconfigNode = ESMF_HConfigCreateAt(hconfig, keyString=compLabel, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
! component responsibility to validate ESMX handled options here, and
! potentially locally handled options
isFlag = ESMF_HConfigValidateMapKeys(hconfigNode, &
vocabulary=["model ", & ! ESMX_Driver handled option
"petList ", & ! ESMX_Driver handled option
"ompNumThreads", & ! ESMX_Driver handled option
"attributes ", & ! ESMX_Driver handled option
"output ", & ! ESMX_Data handled option
"geom ", & ! ESMX_Data handled option
"importFields ", & ! ESMX_Data handled option
"exportFields " & ! ESMX_Data handled option
], badKey=badKey, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return ! bail out
if (.not.isFlag) then
call ESMF_LogSetError(ESMF_RC_ARG_WRONG, &
msg="An invalid key was found in config under "//trim(compLabel)// &
" (maybe a typo?): "//badKey, &
line=__LINE__, file=__FILE__, rcToReturn=rc)
return
endif
endif
endsubroutine SetServices