MODULE PRMTop USE EEsmf_Mod ! Internal state type for a PRMTop component ! cTab :: Generic information held about a component. ! :: Includes how many children, basic start/end/base time ! :: information etc... TYPE PRMTopInternalState TYPE(EEsmfCattr) :: cTab END TYPE CONTAINS SUBROUTINE ComponentsInit( theComponents ) ! ! Set up the components for this experiment. ! This is done by allocating a series of combined component and state ! derived type objects. The returned list of components is then assigned ! to point to this set of objects. ! Routine arguments ! theComponents :: Pointer to components that are created and initialized. ! :: The pointer should not be "associated" on entry to ! :: ComponentsInit. On return from ComponentsInit the ! :: pointer will reference the components that have been ! :: created. TYPE( EEsmfComponentList ), POINTER :: theComponents ! Local variables ! internalState :: Type that collects together all the internal state ! :: associated with a PRM configuration. The PRM component ! :: ESMF internal state could be set to point to this ! :: location so that subsequent calls to the PRM run ! :: routines have access to the PRM state. ! coarseGridOcean :: Holds the reference to the PRM coarse grid ocean ! :: component. ! fineGridOceans :: Holds the references to the PRM fine grid ocean ! :: components. ! coarse2fine :: Holds references to the coarse2fine "couplers". ! fine2coarse :: Holds references to the fine2coarse "coupler". ! TYPE( PRMTopInternalState ), POINTER :: internalState TYPE( EEsmfGridComp ), ALLOCATABLE :: coarseGridOcean(:) TYPE( EEsmfGridComp ), ALLOCATABLE :: fineGridOceans(:) TYPE( EEsmfCplComp ), ALLOCATABLE :: coarse2fine(:) TYPE( EEsmfCplComp ), ALLOCATABLE :: fine2coarse(:) TYPE( EEsmfGridComp ), POINTER :: gcArr(:) TYPE( EEsmfCplComp ), POINTER :: ccArr(:) ! ! o Boot up top PRM component ! First read in table of prmTop setup and put that information ! into the prmTop internal state. ! This table specifies one or more sets of child components to create. ! Each component set corresponds to a specific set of Init(), Run() and ! Finalize() (IRF) routines. The IRF routines need to be known at link time. ! Which IRF routines are used for which component set is based on the prefix ! given in the "preflist: line" entry for that component set that is read ! from the table of components. CALL PRMBoot( 'prmtop.rc', internalState ) ! Allocate requested numbers of child gridded and coupler components. ! This involves calling the ESMF component create functions which, amongst ! other things binds the components to certain PETs. CALL EEsmfAllocChildren( internalState%cTab ) ! For a PRM setup ! The coarse grid ocean is the first set in the list of children. ! The fine grid oceans are the second set in the list of children. ! The coarse2fine couplers are the third set in the list of children. ! The fine2coarse couplers are the fourth set in the list of children. ! ! Setup the components ! We now set the IRF functions for each component and ! then carry out the initialize stage. ! First PRM component set is cg. There is only one of these. ! Second PRM component set are the fg's. There are n of these. ! Third PRM component set are the cg2fg couplers. There are n of these. ! Fourth PRM component set are the fg2cg couplers. There is 1 of these. CALL EEsmfMakeGridComp(coarseGridOcean, I 'cg.rc') CALL EEsmfMakeGridComp( fineGridOceans, & 'fg.rc') CALL EEsmfMakeCplComp( fine2coarse, fineGridOceans, & coarseGridOcean, I 'f2c.rc') CALL EEsmfMakeCplComp( coarse2fine, coarseGridOcean, & fineGridOceans, I 'c2f.rc') END SUBROUTINE ComponentsInit SUBROUTINE ComponentsRun( theComponents ) TYPE( EEsmfComponentList ), POINTER :: theComponents END SUBROUTINE ComponentsRun SUBROUTINE ComponentsFinalize( theComponents ) TYPE( EEsmfComponentList ), POINTER :: theComponents END SUBROUTINE ComponentsFinalize SUBROUTINE PRMBoot( theResourceFile, theState ) ! Routine arguments CHARACTER*(*) :: theResourceFile TYPE( PRMTopInternalState ), POINTER :: theState ! Local variables INTEGER rc TYPE (ESMF_Config) :: cf INTEGER :: nSets, nComps, I CHARACTER(len=1024) :: fPref CHARACTER(len=1024) :: cType ! Boot PRMTop ! Allocate a PRMTop internal state object ALLOCATE( theState ) ! Read PRM config cf = ESMF_ConfigCreate(rc) CALL ESMF_ConfigLoadFile( cf, theResourceFile, rc = rc) ! Find how many sets of components have been requested. ! If the number requested is less than 1 it is an error. CALL EEsmf_ReadConfig( cf, label='nsets:', default=1, & rVal=theState%cTab%nSets, rc=rc ) IF ( theState%cTab%nSets <= 0 ) THEN STOP 'ABNORMAL END:: PRMTop - nSets <= 0' ENDIF ! Get basic details for each components set ALLOCATE( theState%cTab%cTypeArr(theState%cTab%nSets) ) ALLOCATE( theState%cTab%cPrefArr(theState%cTab%nSets) ) ALLOCATE( theState%cTab%nComps(theState%cTab%nSets) ) theState%cTab%nCTypeArr = 0 theState%cTab%nCPrefArr = 0 theState%cTab%nNComps = 0 DO I=1,theState%cTab%nSets ! Get the component type for each component set. CALL EEsmf_ReadConfig( cf, label='ctype:', default='gridded', index=I, & rVal=theState%cTab%cTypeArr(I), rc=rc ) IF ( rc .EQ. ESMF_SUCCESS ) theState%cTab%nCTypeArr = & theState%cTab%nCTypeArr+1 ! Get the number of components to create for each component set. CALL EEsmf_ReadConfig( cf, label='counts:', default=1, index=I, & rVal=theState%cTab%nComps(I), rc=rc ) IF ( rc .EQ. ESMF_SUCCESS ) theState%cTab%nNComps = & theState%cTab%nNComps+1 ! Get the prefix label used to distinguish each component set. CALL EEsmf_ReadConfig( cf, label='preflist:', default='cg', index=I, & rVal=theState%cTab%cPrefArr(I), rc=rc ) IF ( rc .EQ. ESMF_SUCCESS ) theState%cTab%nCPrefArr = & theState%cTab%nCPrefArr+1 ENDDO CALL EEsmf_ReadConfig( cf, label='topStartTime:', default=0., & rVal=theState%cTab%startTime, rc=rc ) IF ( theState%cTab%nCPrefArr .NE. theState%cTab%nSets ) THEN STOP 'ABNORMAL END: PRMTop.PRMBoot found too few file prefix entries.' ENDIF IF ( theState%cTab%nCTypeArr .NE. theState%cTab%nSets ) THEN STOP 'ABNORMAL END: PRMTop.PRMBoot found too few component type entries.' ENDIF IF ( theState%cTab%nNComps .NE. theState%cTab%nSets ) THEN STOP 'ABNORMAL END: PRMTop.PRMBoot found too few component count entries.' ENDIF END SUBROUTINE PRMBoot SUBROUTINE PRMShut( theState ) ! Routine arguments TYPE( PRMTopInternalState ), POINTER :: theState ! Free PRM internal data DEALLOCATE( theState%cTab%cPrefArr ) DEALLOCATE( theState%cTab%cTypeArr ) DEALLOCATE( theState%cTab%nComps ) ! Free PRMTop internal state object DEALLOCATE( theState ) END SUBROUTINE PRMShut END MODULE PRMTop