ESMF_ReconcileSingleCompCase Subroutine

private subroutine ESMF_ReconcileSingleCompCase(state, vm, vmId, vmIntId, attreconflag, siwrap, vmintids_send, rc)

Arguments

Type IntentOptional Attributes Name
type(ESMF_State), intent(inout) :: state
type(ESMF_VM), intent(in) :: vm
type(ESMF_VMId), intent(in), pointer :: vmId
integer, intent(in) :: vmIntId
type(ESMF_AttReconcileFlag), intent(in) :: attreconflag
type(ESMF_StateItemWrap), intent(in), pointer :: siwrap(:)
integer, intent(in), pointer :: vmintids_send(:)
integer, intent(out) :: rc

Calls

proc~~esmf_reconcilesinglecompcase~~CallsGraph proc~esmf_reconcilesinglecompcase ESMF_ReconcileSingleCompCase interface~esmf_vmbroadcast ESMF_VMBroadcast proc~esmf_reconcilesinglecompcase->interface~esmf_vmbroadcast interface~esmf_vmget ESMF_VMGet proc~esmf_reconcilesinglecompcase->interface~esmf_vmget proc~esmf_logfounderror ESMF_LogFoundError proc~esmf_reconcilesinglecompcase->proc~esmf_logfounderror proc~esmf_logseterror ESMF_LogSetError proc~esmf_reconcilesinglecompcase->proc~esmf_logseterror proc~esmf_reconciledeserializeall ESMF_ReconcileDeserializeAll proc~esmf_reconcilesinglecompcase->proc~esmf_reconciledeserializeall proc~esmf_reconcileserializeall ESMF_ReconcileSerializeAll proc~esmf_reconcilesinglecompcase->proc~esmf_reconcileserializeall proc~esmf_vmidget ESMF_VMIdGet proc~esmf_reconcilesinglecompcase->proc~esmf_vmidget

Called by

proc~~esmf_reconcilesinglecompcase~~CalledByGraph proc~esmf_reconcilesinglecompcase ESMF_ReconcileSingleCompCase proc~esmf_reconcilemulticompcase ESMF_ReconcileMultiCompCase proc~esmf_reconcilemulticompcase->proc~esmf_reconcilesinglecompcase proc~esmf_statereconcile_driver ESMF_StateReconcile_driver proc~esmf_statereconcile_driver->proc~esmf_reconcilemulticompcase proc~esmf_statereconcile ESMF_StateReconcile proc~esmf_statereconcile->proc~esmf_statereconcile_driver

Source Code

  subroutine ESMF_ReconcileSingleCompCase(state, vm, vmId, vmIntId, &
    attreconflag, siwrap, vmintids_send, rc)
!
! !ARGUMENTS:
    type(ESMF_State),                     intent(inout) :: state
    type(ESMF_VM),                        intent(in)    :: vm
    type(ESMF_VMId),             pointer, intent(in)    :: vmId
    integer,                              intent(in)    :: vmIntId
    type(ESMF_AttReconcileFlag),          intent(in)    :: attreconflag
    type(ESMF_StateItemWrap),    pointer, intent(in)    :: siwrap(:)
    integer,                     pointer, intent(in)    :: vmintids_send(:)
    integer,                              intent(out)   :: rc
!
! !DESCRIPTION:
!
!   Handle the single component reconciliation case. This is the expected
!   situation under NUOPC rules.
!
!   The arguments are:
!   \begin{description}
!   \item[state]
!     The {\tt ESMF\_State} to reconcile.
!   \item[vm]
!     The {\tt ESMF\_VM} object across which to reconcile {\tt state}.
!   \item[vmId]
!     The {\tt ESMF\_VMId} of the objects in {\tt state} to reconcile.
!   \item[vmIntId]
!     The integer VMId of the objects in {\tt state} to reconcile.
!   \item[attreconflag]
!     Flag indicating whether attributes need to be reconciled.
!   \item[siwrap]
!     List of local state items.
!   \item[vmintids_send]
!     The integer VMId for each local state item.
!   \item[rc]
!     Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!   \end{description}
!EOPI

    integer               :: localrc, i
    integer               :: petCount, localPet, rootVas, rootPet, vas
    integer               :: sizeBuffer(1), itemCount
    logical               :: isFlag
    character, pointer    :: buffer(:)
    integer, allocatable  :: itemList(:)

    rc = ESMF_SUCCESS

#ifdef RECONCILE_LOG_on
    block
      character(ESMF_MAXSTR)  :: stateName
      call ESMF_StateGet(state, name=stateName, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
      call ESMF_LogWrite("ESMF_ReconcileSingleCompCase() for State: "//trim(stateName), &
        ESMF_LOGMSG_DEBUG, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
    end block
#endif

    call ESMF_VMGet(vm, petCount=petCount, localPet=localPet, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return

    call ESMF_VMIdGet(vmId, leftMostOnBit=rootVas, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return

    ! search for first PET in VM that executes on rootVas -> use as rootPet
    do rootPet=0, petCount-1
      call ESMF_VMGet(vm, pet=rootPet, vas=vas, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
      if (vas==rootVas) exit  ! found
    enddo
    if (rootPet==petCount) then
      call ESMF_LogSetError(ESMF_RC_INTNRL_INCONS, &
        msg="Could not find PET that executes on the identified VAS", &
        ESMF_CONTEXT, rcToReturn=rc)
      return
    endif

#ifdef RECONCILE_LOG_on
    block
      character(160)  :: msgStr
      write(msgStr,*) "SingleCompCase rootVas=", rootVas
      call ESMF_LogWrite(msgStr, ESMF_LOGMSG_DEBUG, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
      write(msgStr,*) "SingleCompCase rootPet=", rootPet
      call ESMF_LogWrite(msgStr, ESMF_LOGMSG_DEBUG, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
      write(msgStr,*) "SingleCompCase size(siwrap)=", size(siwrap)
      call ESMF_LogWrite(msgStr, ESMF_LOGMSG_DEBUG, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
    end block
#endif

    ! On rootPet: construct itemList and serialize
    if (localPet==rootPet) then
      ! itemList to hold indices into siwrap(:) of objects that need to be sent
      allocate(itemList(ubound(vmintids_send,1)))   ! max number of items possible
      itemCount=0
      do i=1, size(itemList)
        if (vmintids_send(i)==vmIntId) then
          ! the integer VMId of object "i" matches that of handled single comp
          itemCount = itemCount+1
          itemList(itemCount) = i
        endif
      enddo
      ! serialize all items in itemList
      call ESMF_ReconcileSerializeAll(state, itemList, itemCount, &
        attreconflag, siwrap, buffer, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
      sizeBuffer(1) = size(buffer)
      ! cleanup
      deallocate(itemList)
    endif

    ! Broadcast buffer across all PETs
    call ESMF_VMBroadcast(vm, sizeBuffer, count=1, rootPet=rootPet, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
      rcToReturn=rc)) return

#ifdef RECONCILE_LOG_on
    block
      character(160)  :: msgStr
      write(msgStr,*) "SingleCompCase sizeBuffer=", sizeBuffer(1)
      call ESMF_LogWrite(msgStr, ESMF_LOGMSG_DEBUG, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
    end block
#endif

    if (localPet/=rootPet) allocate(buffer(0:sizeBuffer(1)-1))

    call ESMF_VMBroadcast(vm, buffer, count=sizeBuffer(1), rootPet=rootPet, &
      rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
      rcToReturn=rc)) return

    ! determine if local PET is active under the vmId
    call ESMF_VMIdGet(vmId, isLocalPetActive=isFlag, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
      rcToReturn=rc)) return

#ifdef RECONCILE_LOG_on
    block
      character(160)  :: msgStr
      write(msgStr,*) "SingleCompCase PET active isFlag=", isFlag
      call ESMF_LogWrite(msgStr, ESMF_LOGMSG_DEBUG, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
    end block
#endif

    ! only inactive PETs deserialize the buffer received from rootPet
    if (.not.isFlag) then
      call ESMF_ReconcileDeserializeAll(state, vm, attreconflag, buffer, &
        rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
    endif

    ! Get rid of buffer
    deallocate(buffer)

  end subroutine ESMF_ReconcileSingleCompCase