Skip to content

Commit

Permalink
Implement ESMF_StateLog() method.
Browse files Browse the repository at this point in the history
  • Loading branch information
theurich committed Jan 18, 2024
1 parent 609c811 commit 0d51f81
Show file tree
Hide file tree
Showing 5 changed files with 370 additions and 56 deletions.
3 changes: 3 additions & 0 deletions src/Superstructure/State/src/ESMF_State.F90
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ module ESMF_StateMod
public ESMF_StateAdd, ESMF_StateAddReplace
public ESMF_StateGet
public ESMF_StateIsReconcileNeeded

public ESMF_StateLog

public ESMF_StateRemove
public ESMF_StateReplace

Expand Down
255 changes: 255 additions & 0 deletions src/Superstructure/State/src/ESMF_StateAPI.cppF90
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ module ESMF_StateAPIMod
public ESMF_StateIsCreated
public ESMF_StateIsReconcileNeeded

public ESMF_StateLog

public ESMF_StateWriteRestart
public ESMF_StateReadRestart

Expand Down Expand Up @@ -1821,6 +1823,259 @@ type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
end function ESMF_StateIsReconcileNeeded


! -------------------------- ESMF-public method -----------------------------
^undef ESMF_METHOD
^define ESMF_METHOD "ESMF_StateLog()"
!BOP
! !IROUTINE: ESMF_StateLog - Log

! !INTERFACE:
subroutine ESMF_StateLog(state, prefix, logMsgFlag, nestedFlag, deepFlag, rc)
!
! !ARGUMENTS:
type(ESMF_State), intent(in) :: state
character(len=*), intent(in), optional :: prefix
type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag
logical, intent(in), optional :: nestedFlag
logical, intent(in), optional :: deepFlag
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
! Log the State.
!
! The arguments are:
! \begin{description}
! \item[state]
! {\tt ESMF\_State} object logged.
! \item [{[prefix]}]
! String to prefix the log message. Default is no prefix.
! \item [{[logMsgFlag]}]
! Type of log message generated. See section \ref{const:logmsgflag} for
! a list of valid message types. Default is {\tt ESMF\_LOGMSG\_INFO}.
! \item[{[nestedFlag]}]
! When set to {\tt .false.} (default), only log information about the
! current State level.
! When set to {\tt .true.}, additionally log information for each nested
! State.
! \item[{[deepFlag]}]
! When set to {\tt .false.} (default), only log top level information for
! each item contained in the State.
! When set to {\tt .true.}, additionally log information for each item.
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOP
!------------------------------------------------------------------------------
integer :: localrc ! local return code
type(ESMF_LogMsg_Flag) :: logMsg
character(len=:), allocatable :: prefixStr
logical :: nestedLog, deepLog

! initialize return code; assume routine not implemented
localrc = ESMF_RC_NOT_IMPL
if (present(rc)) rc = ESMF_RC_NOT_IMPL

! optional prefix
if (present(prefix)) then
prefixStr = trim(prefix)
else
prefixStr = ""
endif

! optional nestedFlag and deepFlag
nestedLog = .false. ! default
if (present(nestedFlag)) nestedLog = nestedFlag
deepLog = .false. ! default
if (present(deepFlag)) deepLog = deepFlag

! deal with optionl logMsgFlag
logMsg = ESMF_LOGMSG_INFO ! default
if (present(logMsgFlag)) logMsg = logMsgFlag

call ESMF_LogWrite(trim(prefixStr)//"--- StateLog() start -----------------", &
logMsg, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return

call StateLog(stateR=state, prefix=prefixStr, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return

call ESMF_LogWrite(trim(prefixStr)//"--- StateLog() end -------------------", &
logMsg, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return

! return successfully
if (present(rc)) rc = ESMF_SUCCESS

contains

recursive subroutine StateLog(stateR, prefix, rc)
type(ESMF_State), intent(in) :: stateR
character(len=*), intent(in) :: prefix
integer, intent(out) :: rc
! - local variables
integer :: localrc
character(160) :: msgString
character(ESMF_MAXSTR) :: name, tempString
type(ESMF_StateIntent_Flag) :: stateIntent
integer :: itemCount, item
character(ESMF_MAXSTR), allocatable :: itemNameList(:)
type(ESMF_StateItem_Flag), allocatable :: itemTypeList(:)
type(ESMF_State) :: nestedState
type(ESMF_Field) :: field
type(ESMF_FieldBundle) :: fieldbundle
type(ESMF_Array) :: array
type(ESMF_ArrayBundle) :: arraybundle
type(ESMF_RouteHandle) :: routehandle

localrc = ESMF_RC_NOT_IMPL
if (.not. ESMF_StateIsCreated(stateR)) then
call ESMF_LogWrite(prefix//"State object is invalid!"//&
" Not created or deleted", logMsg, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else
! query
call ESMF_StateGet(stateR, name=name, stateIntent=stateIntent, &
itemCount=itemCount, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! <intent>
if (stateIntent==ESMF_STATEINTENT_IMPORT) then
tempString = "ESMF_STATEINTENT_IMPORT"
else if (stateIntent==ESMF_STATEINTENT_EXPORT) then
tempString = "ESMF_STATEINTENT_EXPORT"
else if (stateIntent==ESMF_STATEINTENT_INTERNAL) then
tempString = "ESMF_STATEINTENT_INTERNAL"
else if (stateIntent==ESMF_STATEINTENT_UNSPECIFIED) then
tempString = "ESMF_STATEINTENT_UNSPECIFIED"
else if (stateIntent==ESMF_STATEINTENT_INVALID) then
tempString = "ESMF_STATEINTENT_INVALID"
else
tempString = "Out or range STATEINTENT!!!"
endif

write (msgString,'(A,I4,A)') prefix//"State object is valid!"//&
" <name: "//trim(name)//"> <intent: "//trim(tempString)//">"//&
" <itemCount: ", itemCount, ">"
call ESMF_LogWrite(trim(msgString), logMsg, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return

if (itemCount > 0) then
allocate(itemNameList(itemCount))
allocate(itemTypeList(itemCount))
call ESMF_StateGet(stateR, itemNameList=itemNameList, &
itemtypeList=itemtypeList, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return

do item=1, itemCount
! basic item information
write (msgString,'(A,I4.4,A)') prefix//"+-<item: ", item, &
"> <itemType: "//ESMF_StateItemString(itemtypeList(item))// &
"> <itemName: "//trim(itemNameList(item))//">"
call ESMF_LogWrite(trim(msgString), logMsg, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! deep item logging, possibly recursion
if ((itemtypeList(item) == ESMF_STATEITEM_STATE) .and. &
nestedLog) then
! recursion into nested state
call ESMF_StateGet(stateR, itemName=itemNameList(item), &
nestedState=nestedState, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call StateLog(stateR=nestedState, prefix=prefix//"! ", &
rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else if (deepLog) then
! deep logging of all other item types
! TODO: activate the Log() method calls below when implemented!
if (itemtypeList(item) == ESMF_STATEITEM_FIELD) then
call ESMF_StateGet(stateR, itemName=itemNameList(item), &
field=field, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! call ESMF_FieldLog(field, prefix=prefix//"! ", &
! logMsgFlag=logMsg, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else if (itemtypeList(item) == ESMF_STATEITEM_FIELDBUNDLE) then
call ESMF_StateGet(stateR, itemName=itemNameList(item), &
fieldbundle=fieldbundle, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! call ESMF_FieldBundleLog(fieldbundle, prefix=prefix//"! ", &
! logMsgFlag=logMsg, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else if (itemtypeList(item) == ESMF_STATEITEM_ARRAY) then
call ESMF_StateGet(stateR, itemName=itemNameList(item), &
array=array, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! call ESMF_ArrayLog(array, prefix=prefix//"! ", &
! logMsgFlag=logMsg, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else if (itemtypeList(item) == ESMF_STATEITEM_ARRAYBUNDLE) then
call ESMF_StateGet(stateR, itemName=itemNameList(item), &
arraybundle=arraybundle, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! call ESMF_ArrayBundleLog(arraybundle, prefix=prefix//, &
! logMsgFlag=logMsg, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else if (itemtypeList(item) == ESMF_STATEITEM_ROUTEHANDLE) then
call ESMF_StateGet(stateR, itemName=itemNameList(item), &
routehandle=routehandle, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! call ESMF_RouteHandleLog(routehandle, prefix=prefix//"! ", &
! logMsgFlag=logMsg, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
endif
enddo

deallocate(itemNameList)
deallocate(itemTypeList)
endif

endif
end subroutine

end subroutine ESMF_StateLog
!------------------------------------------------------------------------------


!------------------------------------------------------------------------------
^undef ESMF_METHOD
^define ESMF_METHOD "ESMF_StatePrint"
Expand Down
70 changes: 68 additions & 2 deletions src/Superstructure/State/src/ESMF_StateItem.F90
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ module ESMF_StateItemMod
ESMF_STATEITEM_NAME, &
#endif
ESMF_STATEITEM_NOTFOUND
public ESMF_StateItemConstruct
public ESMF_StateItemConstruct, ESMF_StateItemString
public ESMF_StateIntent_Flag, ESMF_STATEINTENT_IMPORT, ESMF_STATEINTENT_EXPORT, &
ESMF_STATEINTENT_INTERNAL, &
ESMF_STATEINTENT_UNSPECIFIED
Expand Down Expand Up @@ -378,6 +378,72 @@ function ESMF_StateItemConstruct (name, itemtype, keywordEnforcer, &
if (present(rc)) rc = ESMF_SUCCESS

end function ESMF_StateItemConstruct
!------------------------------------------------------------------------------


! -------------------------- ESMF-internal method -----------------------------
#undef ESMF_METHOD
#define ESMF_METHOD "ESMF_StateItemString()"
!BOPI
! !IROUTINE: ESMF_StateItemString - Return StateItem Flag as string

! !INTERFACE:
function ESMF_StateItemString (itemtype, keywordEnforcer, rc) result (string)
!
! !RETURN VALUE:
character(len=:), allocatable :: string
!
! !ARGUMENTS:
type(ESMF_StateItem_Flag), intent(in) :: itemtype
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
! String of StateItem Flag.
! \item[itemtype]
! State item type code
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOPI
!------------------------------------------------------------------------------
integer :: localrc ! local return code

! Initialize return code; assume failure until success is certain
if (present(rc)) rc = ESMF_RC_NOT_IMPL

select case (itemtype%ot)
case (ESMF_STATEITEM_FIELD%ot)
string = "Field"
case (ESMF_STATEITEM_FIELDBUNDLE%ot)
string = "FieldBundle"
case (ESMF_STATEITEM_ARRAY%ot)
string = "Array"
case (ESMF_STATEITEM_ARRAYBUNDLE%ot)
string = "ArrayBundle"
case (ESMF_STATEITEM_ROUTEHANDLE%ot)
string = "RouteHandle"
case (ESMF_STATEITEM_STATE%ot)
string = "State"
case (ESMF_STATEITEM_UNKNOWN%ot)
string = "Unknown"
case (ESMF_STATEITEM_NOTFOUND%ot)
string = "NotFound"
case default
string = ""
call ESMF_LogSetError(rcToCheck=ESMF_RC_INTNRL_BAD, &
msg="- unsupported StateItemType", &
ESMF_CONTEXT, rcToReturn=rc)
return ! bail out
end select

! Return successfully
if (present(rc)) rc = ESMF_SUCCESS

end function ESMF_StateItemString
!------------------------------------------------------------------------------


! -------------------------- ESMF-internal method -----------------------------
#undef ESMF_METHOD
Expand Down Expand Up @@ -541,7 +607,7 @@ subroutine ESMF_StateItemPrint (stateItem, header, prefixstr, &
case (ESMF_STATEITEM_ARRAYBUNDLE%ot)
outbuf = trim (outbuf) // " ArrayBundle"
case (ESMF_STATEITEM_ROUTEHANDLE%ot)
outbuf = trim (outbuf) // " Route handle"
outbuf = trim (outbuf) // " RouteHandle"
case (ESMF_STATEITEM_STATE%ot)
outbuf = trim (outbuf) // " State"
#if 0
Expand Down
2 changes: 1 addition & 1 deletion src/Superstructure/State/src/ESMF_StateTypes.F90
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ module ESMF_StateTypesMod
#endif
ESMF_STATEITEM_NOTFOUND
public ESMF_StateItemWrap
public ESMF_StateItemConstruct
public ESMF_StateItemConstruct, ESMF_StateItemString
public ESMF_StateIntent_Flag, ESMF_STATEINTENT_IMPORT, ESMF_STATEINTENT_EXPORT, &
ESMF_STATEINTENT_INTERNAL, &
ESMF_STATEINTENT_UNSPECIFIED
Expand Down
Loading

0 comments on commit 0d51f81

Please sign in to comment.