recursive subroutine ESMF_CompConstruct(compp, compType, name, &
dirPath, configFile, config, clock, petlist, devlist, contextflag, rc)
!
! !ARGUMENTS:
type(ESMF_CompClass), pointer :: compp
type(ESMF_CompType_Flag), intent(in) :: compType
character(len=*), intent(in), optional :: name
character(len=*), intent(in), optional :: dirPath
character(len=*), intent(in), optional :: configFile
type(ESMF_Config), intent(in), optional :: config
type(ESMF_Clock), intent(in), optional :: clock
integer, intent(in), optional :: petlist(:)
integer, intent(in), optional :: devlist(:)
type(ESMF_Context_Flag), intent(in), optional :: contextflag
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
! Take a new component datatype and fill in the contents.
!
! The arguments are:
! \begin{description}
! \item[compp]
! Component internal structure to be filled in.
! \item[compType]
! Component type, where type is {\tt ESMF\_GRIDCOMP} or {\tt ESMF\_CPLCOMP}.
! \item[{[name]}]
! Component name.
! \item[{[dirPath]}]
! Directory where component-specfic configuration or data files
! are located.
! \item[{[configFile]}]
! File containing configuration information, either absolute filename
! or relative to {\tt dirPath}.
! \item[{[config]}]
! Already created {\tt config} object.
! \item[{[clock]}]
! Private {\tt clock} for this {\tt Component}.
! \item[{[petlist]}]
! List of {\tt PET}s for this component. The default is to use all PETs.
! \item[{[devlist]}]
! List of {\tt DEV}s for this component. By default no devices are associated.
! \item[{[contextflag]}]
! Specify the component's VM context. The default context is
! {\tt ESMF\_CONTEXT\_OWN\_VM}. See section \ref{const:contextflag} for a
! complete list of options.
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOPI
!------------------------------------------------------------------------------
integer :: localrc ! local return code
integer :: npets, mypet, i, petCount
integer, pointer :: petlist_loc(:), devlist_loc(:)
character(len=ESMF_MAXPATHLEN) :: fullpath ! config file + dirPath
character(len=ESMF_MAXSTR) :: msgbuf
type(ESMF_VM):: vm
! Assume not implemented until success
if (present(rc)) rc = ESMF_RC_NOT_IMPL
localrc = ESMF_RC_NOT_IMPL
! Test incoming compp object
if (.not.associated(compp)) then
call ESMF_LogSetError(ESMF_RC_OBJ_BAD, &
msg="Not a valid pointer to ESMF Component object", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
! Set values for the derived type members
compp%ftable = ESMF_NULL_POINTER
compp%base%this = ESMF_NULL_POINTER
compp%compType = compType
compp%compTunnel%this = ESMF_NULL_POINTER
compp%configFile = "uninitialized"
compp%dirPath = "uninitialized"
compp%npetlist = 0
compp%ndevlist = 0
nullify(compp%compw%compp)
nullify(compp%petlist)
nullify(compp%devlist)
compp%vm_info = ESMF_NULL_POINTER
compp%vm_cargo = ESMF_NULL_POINTER
compp%vm_recursionCount = 0
nullify(compp%is%statep)
nullify(compp%es%statep)
compp%vm_released = .false.
compp%contextflag = ESMF_CONTEXT_OWN_VM
compp%compStatus = ESMF_COMPSTATUS_ALL_NOTPRESENT
! parent VM
call ESMF_VMGetCurrent(vm=compp%vm_parent, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! own VM
call ESMF_VMSetThis(compp%vm, ESMF_NULL_POINTER, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_VMSetInitCreated(compp%vm, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! for config files, store a directory path and subsequent opens can
! be relative to this or absolute.
if (present(dirPath)) then
compp%dirPath = dirPath
else
compp%dirPath = "."
endif
! config handling
if (present(config)) then
compp%config = config
compp%compStatus%configIsPresent = .true.
if (present(configFile)) then
! a config object gets priority over a name if both are specified.
call ESMF_LogWrite("Ignoring configFile because config object given.", &
ESMF_LOGMSG_WARNING)
endif
else if (present(configFile)) then
! name of a specific config file. open it and store the config object.
compp%configFile = configFile
compp%compStatus%configFileIsPresent = .true.
compp%config = ESMF_ConfigCreate(rc=localrc)
compp%compStatus%configIsPresent = .true.
call ESMF_ConfigLoadFile(compp%config, configFile, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
! try again with the dirPath concatinated on front
fullpath = trim(compp%dirPath) // '/' // trim(configFile)
call ESMF_ConfigLoadFile(compp%config, fullpath, rc=localrc)
! TODO: construct a msg string and then call something here.
! if (ESMF_LogFoundError(status, msgstr, rc)) return
if (localrc /= ESMF_SUCCESS) then
write(msgbuf, *) &
"ERROR: loading config file, unable to open either", &
" name = ", trim(configFile), " or name = ", trim(fullpath)
call ESMF_LogSetError(ESMF_RC_ARG_VALUE, &
msg=msgbuf, &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
endif
endif
! clock
if (present(clock)) then
compp%clock = clock
compp%compStatus%clockIsPresent = .true.
endif
! petlist
if (present(petlist)) then
compp%npetlist = size(petlist)
allocate(petlist_loc(compp%npetlist), stat=localrc)
if (ESMF_LogFoundAllocError(localrc, msg="local petlist", &
ESMF_CONTEXT, rcToReturn=rc)) return
compp%petlist => petlist_loc
compp%petlist = petlist ! copy contents of petlist
else
compp%npetlist = 0
allocate(compp%petlist(1), stat=localrc)
if (ESMF_LogFoundAllocError(localrc, msg="local petlist", &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
! devlist
if (present(devlist)) then
compp%ndevlist = size(devlist)
allocate(devlist_loc(compp%ndevlist), stat=localrc)
if (ESMF_LogFoundAllocError(localrc, msg="local devlist", &
ESMF_CONTEXT, rcToReturn=rc)) return
compp%devlist => devlist_loc
compp%devlist = devlist ! copy contents of devlist
else
compp%ndevlist = 0
allocate(compp%devlist(1), stat=localrc)
if (ESMF_LogFoundAllocError(localrc, msg="local devlist", &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
! check for consistency between contextflag and petlist
call ESMF_VMGet(vm=compp%vm_parent, localPet=mypet, petCount=npets, &
rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (present(contextflag)) then
if (contextflag==ESMF_CONTEXT_PARENT_VM) then
if ((compp%npetlist .gt. 0) .and. (compp%npetlist .lt. npets)) then
! conflict between contextflag and petlist -> bail out
deallocate(compp%petlist) ! local garbage collection for bail-on-error
call ESMF_LogSetError(ESMF_RC_ARG_VALUE, &
msg="Conflict between contextflag and petlist arguments", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
endif
compp%contextflag = contextflag
else
compp%contextflag = ESMF_CONTEXT_OWN_VM ! default
endif
! check for conflict between petlist and current VM petCount
if (compp%npetlist .gt. 0) then
call ESMF_VMGetCurrent(vm, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_VMGet(vm, petCount=petCount, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! see if pets in the petlist are negative or if they exist
do i=1, compp%npetlist
if ((compp%petlist(i) .ge. petCount) .or. (compp%petlist(i) .lt. 0)) then
deallocate(compp%petlist) ! local garbage collection for bail-on-error
call ESMF_LogSetError(ESMF_RC_ARG_VALUE, &
msg="Conflict between petlist and global pet count", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
enddo
endif
! initialize base class, including component name
call ESMF_BaseCreate(compp%base, "Component", name, 0, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! set the participation flag
compp%iAmParticipant = .false. ! reset
if (compp%npetlist .gt. 0) then
! see if mypet is in the petlist
do i=1, compp%npetlist
if (compp%petlist(i) == mypet) compp%iAmParticipant = .true. ! set
enddo
else
! no petlist -> all PETs participate
compp%iAmParticipant = .true. ! set
endif
! instantiate a default VMPlan
call ESMF_VMPlanConstruct(vmplan=compp%vmplan, vm=compp%vm_parent, &
npetlist=compp%npetlist, petlist=compp%petlist, &
ndevlist=compp%ndevlist, devlist=compp%devlist, &
contextflag=compp%contextflag, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! initialize the remaining VM members in compp
compp%vm_info = ESMF_NULL_POINTER
compp%vm_cargo = ESMF_NULL_POINTER
compp%vm_released = .false.
! Create an empty subroutine/internal state table.
call c_ESMC_FTableCreate(compp%ftable, localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! create methodTable object
call c_ESMC_MethodTableCreate(compp%methodTable, localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Set init code
ESMF_INIT_SET_CREATED(compp)
! Return successfully
if (present(rc)) rc = ESMF_SUCCESS
end subroutine ESMF_CompConstruct