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

Adds extra metadata to fields about their origin #241

Draft
wants to merge 7 commits into
base: develop
Choose a base branch
from
Draft
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
4 changes: 2 additions & 2 deletions src/addon/NUOPC/doc/NUOPC_FieldMirror.tex
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

The field mirror capability is also useful with NUOPC Mediators since these components often exactly reflect, in separate States, the sets of fields of each of the connected components. The field mirroring capability, therefore, can be used to ensure that a Mediator is always capable of accepting fields from connected components, and removes the need to specify field lists in multiple places, i.e., both within a set of Model components connected to a Mediator and within the Mediator itself.

To access the field mirror capability, a component sets the {\tt FieldTransferPolicy} attribute during {\tt label\_Advertise}. The attribute is set on the Import- and/or Export- States to trigger field mirroring for each state, respectively. The default value of "TransferNone" indicates that no fields should be mirrored. The other option, "TransferAll", indicates that fields should be mirrored in the State of a connected component.
To access the field mirror capability, a component sets the {\tt FieldTransferPolicy} attribute during {\tt label\_Advertise}. The attribute is set on the Import- and/or Export- States to trigger field mirroring for each state, respectively. The default value of "TransferNone" indicates that no fields should be mirrored. The other options, "TransferAll", indicates that fields should be mirrored in the State of a connected component and "TransferAllAsNests", also indicates that fields should be mirrored in the State of a connected component but in this case, fields are added to nested state for each provider component.

Each Connector consider the {\tt FieldTransferPolicy} Attribute on both its import and export States. If {\em both} States have a {\tt FieldTransferPolicy} of "TransferAll", then fields are transferred between the States in both directions (i.e., import to export and export to import). The transfer process works as follows: First, the {\tt TransferOfferGoemObject} attribute is reversed between the providing side and accepting side. Intuitively, if a field from the providing component is to be mirrored and it can provide its own geometric object, then the mirrored field on the accepting side should be set to accept a geometric object. Then, the field to be mirrored is advertised in the accepting State using a call to {\tt NUOPC\_Advertise()} such that the mirrored field shares the same Standard Name.
Each Connector consider the {\tt FieldTransferPolicy} Attribute on both its import and export States. If {\em both} States have a {\tt FieldTransferPolicy} of "TransferAll" or "TransferAllAsNests", then fields are transferred between the States in both directions (i.e., import to export and export to import). In case of "TransferAllAsNests", the received State by acceptor will have nested states for each provider. The transfer process works as follows: First, the {\tt TransferOfferGoemObject} attribute is reversed between the providing side and accepting side. Intuitively, if a field from the providing component is to be mirrored and it can provide its own geometric object, then the mirrored field on the accepting side should be set to accept a geometric object. Then, the field to be mirrored is advertised in the accepting State using a call to {\tt NUOPC\_Advertise()} such that the mirrored field shares the same Standard Name. The accepting State will have nested states if {\tt FieldTransferPolicy} is set to "TransferAllAsNests".

Components have the opportunity, using specialiozation point {\tt label\_ModifyAdvertised}, to modify any of the mirrored Fields in their Import/ExportState. After this the initialization sequence continues as usual. Since fields to be mirrored have been advertised with matching Standard Names, the field pairing algorithm will now match them in the usual way thereby establishing a connection between the original and mirrored fields.
1 change: 1 addition & 0 deletions src/addon/NUOPC/doc/NUOPC_Field_metadata.tex
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@
{\tt MaxIndex} & Integer value list. If present equals the {\tt maxIndex} (of tile 1) of the provider field.during a GeomObject transfer. & {\em no restriction}\\ \hline
{\tt TypeKind} & Integer value. If present equals the integer representation of {\tt typekind} of the provider field.during a GeomObject transfer. & {\em implementation dependent range}\\ \hline
{\tt GeomLoc} & Integer value. If present equals the integer representation of {\tt staggerloc} (for Grid) or {\tt meshloc} (for Mesh) of the provider field.during a GeomObject transfer. & {\em implementation dependent range}\\ \hline
{\tt ProviderCompName} & String value holding the name of provider component that is indicated in run sequence\\ \hline
\hline
\end{longtable}
1 change: 1 addition & 0 deletions src/addon/NUOPC/doc/NUOPC_State_metadata.tex
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
\hline\hline
{\tt Namespace} & String value holding the namespace of all the objects contained in the State.& {\em no restriction}\\ \hline
{\tt FieldTransferPolicy} & String value indicating to Connector to transfer/mirror Fields. & transferNone,\newline transferAll\\ \hline
{\tt CompName} & String value holding the name of provider component that is indicated in run sequence\\ \hline
\hline
\end{longtable}
59 changes: 59 additions & 0 deletions src/addon/NUOPC/src/NUOPC_Connector.F90
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ subroutine InitializeIPDv05p1(connector, importState, exportState, clock, rc)
integer :: i, j
character(ESMF_MAXSTR) :: importCplSet, exportCplSet
character(len=240) :: msgString
character(ESMF_MAXSTR) :: importProvider, exportProvider

rc = ESMF_SUCCESS

Expand Down Expand Up @@ -607,6 +608,29 @@ subroutine InitializeIPDv05p1(connector, importState, exportState, clock, rc)
call doMirror(importState, exportState, acceptorVM=vm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
elseif (trim(exportXferPolicy)=="transferAllAsNests") then
! check name of provider component
call NUOPC_GetAttribute(importState, name="CompName", &
value=importProvider, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! create nested state
exportNestedState = ESMF_StateCreate(name=trim(importProvider)//"-NestedState", rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! set FieldTransferPolicy metadata for nested state
call NUOPC_SetAttribute(exportNestedState, "FieldTransferPolicy", "transferAll", rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! define namespace and nested state
call NUOPC_AddNamespace(exportState, namespace=trim(importProvider), &
nestedState=exportNestedState, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! top level mirroring into exportState
call doMirror(importState, exportNestedState, acceptorVM=vm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
elseif (importHasNested .and. exportHasNested) then
! loop through the nested states inside of the exportState and see if
! any of them request mirroring
Expand Down Expand Up @@ -682,6 +706,29 @@ subroutine InitializeIPDv05p1(connector, importState, exportState, clock, rc)
call doMirror(exportState, importState, acceptorVM=vm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
elseif (trim(importXferPolicy)=="transferAllAsNests") then
! check name of provider component
call NUOPC_GetAttribute(exportState, name="CompName", &
value=exportProvider, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! create nested state
importNestedState = ESMF_StateCreate(name=trim(exportProvider)//"-NestedState", rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! set FieldTransferPolicy metadata for nested state
call NUOPC_SetAttribute(importNestedState, "FieldTransferPolicy", "transferAll", rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! define namespace and nested state
call NUOPC_AddNamespace(importState, namespace=trim(exportProvider), &
nestedState=importNestedState, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! top level mirroring into exportState
call doMirror(exportState, importNestedState, acceptorVM=vm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
elseif (importHasNested .and. exportHasNested) then
! loop through the nested states inside of the importState and see if
! any of them request mirroring
Expand Down Expand Up @@ -798,6 +845,7 @@ recursive subroutine doMirror(providerState, acceptorState, acceptorVM, rc)
integer :: item, itemCount
character(ESMF_MAXSTR) :: providerTransferOffer, acceptorTransferOffer
character(ESMF_MAXSTR) :: acceptorStateName
character(ESMF_MAXSTR) :: providerCompName
type(ESMF_State) :: providerNestedState
type(ESMF_State) :: acceptorNestedState
character(ESMF_MAXSTR) :: nestedStateName
Expand Down Expand Up @@ -832,6 +880,11 @@ recursive subroutine doMirror(providerState, acceptorState, acceptorVM, rc)
if (vmThis == ESMF_NULL_POINTER) then
actualFlag = .false. ! local PET is not for an actual member
endif

call NUOPC_GetAttribute(providerState, name="CompName", &
value=providerCompName, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out

call ESMF_StateGet(acceptorState, name=acceptorStateName, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
Expand Down Expand Up @@ -1008,6 +1061,12 @@ recursive subroutine doMirror(providerState, acceptorState, acceptorVM, rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
endif

! Add extra metadata to the field in acceptor side about provider
call NUOPC_SetAttribute(fieldAdv, name="ProviderCompName", &
value=trim(providerCompName), rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
end do
endif

Expand Down
45 changes: 44 additions & 1 deletion src/addon/NUOPC/src/NUOPC_Driver.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,8 @@ recursive subroutine loopModelComps(phase, rc)
logical :: areServicesSet
character(ESMF_MAXSTR) :: iString, pLabel
logical :: mustAttributeUpdate(1:is%wrap%modelCount)
logical :: isPresent
type(ESMF_Info) :: info
rc = ESMF_SUCCESS
mustAttributeUpdate = .false.
! loop through all the model components first time to execute
Expand Down Expand Up @@ -1642,7 +1644,48 @@ recursive subroutine loopModelComps(phase, rc)
return ! bail out
endif
enddo
! loop through all the model components second time to update Attributes
! loop through all the model components second time to add extra metadata
do i=1, is%wrap%modelCount
call ESMF_GridCompGet(is%wrap%modelComp(i), name=compName, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME, rcToReturn=rc)) &
return ! bail out
! add metadata to import state
call ESMF_InfoGetFromHost(is%wrap%modelIS(i), info=info, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME, rcToReturn=rc)) &
return ! bail out
call ESMF_InfoGet(info, key="/NUOPC/Instance/CompName", &
isPresent=isPresent, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME, rcToReturn=rc)) &
return ! bail out
if (.not. isPresent) then
call ESMF_InfoSet(info, key="/NUOPC/Instance/CompName", &
value=trim(compName), rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME, rcToReturn=rc)) &
return ! bail out
end if
! add metadata to export state
call ESMF_InfoGetFromHost(is%wrap%modelES(i), info=info, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME, rcToReturn=rc)) &
return ! bail out
call ESMF_InfoGet(info, key="/NUOPC/Instance/CompName", &
isPresent=isPresent, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME, rcToReturn=rc)) &
return ! bail out
if (.not. isPresent) then
call ESMF_InfoSet(info, key="/NUOPC/Instance/CompName", &
value=trim(compName), rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME, rcToReturn=rc)) &
return ! bail out
end if
end do
! loop through all the model components third time to update Attributes
do i=1, is%wrap%modelCount
if (mustAttributeUpdate(i)) then
! need to update the Component attributes across all PETs
Expand Down
Loading