MIT GEOS5PlugMod
From Maplcode.org
MIT_GEOS5PlugMod is the plug for connecting MITgcm into the MAPL GEOS-5 tree.
! are the same as MOM's. It may also be an adequate plug for HIM.
use ESMF_Mod
use MAPL_Mod
! Nothing on the MOM side is visible through this module.
implicit none
private
! Only public things are the IRF routines. Note that they don't use the standard
! ESMF interface for ESMF IRF methods.
public :: SetServices
contains
!BOP
! !IROUTINE: SetServices -- Sets ESMF services for this component
! !INTERFACE:
subroutine SetServices ( GC, RC )
! !ARGUMENTS:
type(ESMF_GridComp), intent(INOUT) :: GC ! gridded component
integer, optional :: RC ! return code
! !DESCRIPTION: The SetServices for the PhysicsGcm GC needs to register its
! Initialize and Run. It uses the GEOS_Generic construct for defining
! state specs and couplings among its children. In addition, it creates the
! children GCs (AGCM and OGCM) and runs their
! respective SetServices.
!EOP
!=============================================================================
!
! ErrLog Variables
character(len=ESMF_MAXSTR) :: IAm
integer :: STATUS
character(len=ESMF_MAXSTR) :: COMP_NAME
! Variables for setting MAPL import/export specs
TYPE MAPL_SPEC
CHARACTER(len=ESMF_MAXSTR) :: short_name
CHARACTER(len=ESMF_MAXSTR) :: long_name
CHARACTER(len=ESMF_MAXSTR) :: units
INTEGER :: dims
INTEGER :: vlocation
END TYPE
TYPE( MAPL_SPEC ), POINTER :: imports(:)
TYPE( MAPL_SPEC ), POINTER :: exports(:)
INTEGER nImports
INTEGER nExports
INTEGER I
! Locals
!=============================================================================
! Begin...
! Get my name and set-up traceback handle
! ---------------------------------------
Iam = 'SetServices'
call ESMF_GridCompGet( GC, NAME=COMP_NAME, RC=STATUS )
VERIFY_(STATUS)
Iam = trim(COMP_NAME) // Iam
! Imports and exports specification
! ---------------------------------
nimports = 7
allocate(imports(nimports))
! ---------------------------------------------
imports = (/ &
mstate('TAUX', 'Agrid_eastward_stress_on_skin', 'N m-2', MAPL_DimsHorzOnly,MAPL_VLocationNone), &
mstate('TAUY', 'Agrid_northward_stress_on_skin', 'N m-2', MAPL_DimsHorzOnly,MAPL_VLocationNone), &
mstate('PS', 'Surface Atmospheric Pressure', 'Pa', MAPL_DimsHorzOnly,MAPL_VLocationNone), &
mstate('SWHEAT','solar_heating_rate', 'W m-2', MAPL_DimsHorzVert,MAPL_VLocationCenter), &
mstate('QFLX', 'freshwater_flux_from_skin_to_ocean', 'kg m-2 s-1',MAPL_DimsHorzOnly,MAPL_VLocationNone), &
mstate('HFLX', 'turbulent_heat_flux_from_skin_to_ocean','W m-2', MAPL_DimsHorzOnly,MAPL_VLocationNone), &
mstate('SFLX', 'salt_flux_from_skin_to_ocean', 'N m-2', MAPL_DimsHorzOnly,MAPL_VLocationNone) &
/)
DO I=1,NIMPORTS
CALL MAPL_StateAddImportSpec(GC, &
SHORT_NAME = imports(i)%short_name, &
LONG_NAME = imports(i)%long_name, &
UNITS = imports(i)%units, &
DIMS = imports(i)%dims, &
VLOCATION = imports(i)%vlocation, &
RC =status); VERIFY_(STATUS)
ENDDO
! -------------------------
nexports =5
allocate(exports(nexports))
exports = (/ &
mstate('US', 'top_layer_Agrid_eastward_velocity', 'm s-1', MAPL_DimsHorzOnly,MAPL_VLocationNone), &
mstate('VS', 'top_layer_Agrid_northward_velocity', 'm s-1', MAPL_DimsHorzOnly,MAPL_VLocationNone), &
mstate('TS', 'top_layer_temperature', 'K', MAPL_DimsHorzOnly,MAPL_VLocationNone), &
mstate('SS', 'top_layer_salinity', 'psu', MAPL_DimsHorzOnly,MAPL_VLocationNone), &
mstate('MASK', 'ocean mask at t-points', '1', MAPL_DimsHorzVert,MAPL_VLocationCenter) &
/)
DO I=1,5
call MAPL_StateAddExportSpec(GC, &
SHORT_NAME = exports(i)%short_name, &
LONG_NAME = exports(i)%long_name, &
UNITS = exports(i)%units, &
DIMS = exports(i)%dims, &
VLOCATION = exports(i)%vlocation, &
RC=STATUS )
VERIFY_(STATUS)
ENDDO
deallocate(imports)
deallocate(exports)
!EOP
! Set the Initialize, Run, Finalize entry points
! ----------------------------------------------
call ESMF_GridCompSetEntryPoint ( GC, ESMF_SETINIT, Initialize, ESMF_SINGLEPHASE, status)
VERIFY_(STATUS)
call ESMF_GridCompSetEntryPoint ( GC, ESMF_SETRUN, Run, ESMF_SINGLEPHASE, status)
VERIFY_(STATUS)
call ESMF_GridCompSetEntryPoint ( GC, ESMF_SETFINAL, Finalize, ESMF_SINGLEPHASE, status)
VERIFY_(STATUS)
! Set the Profiling timers
! ------------------------
call MAPL_GenericStateClockAdd(GC, name="INITIALIZE" ,RC=STATUS)
VERIFY_(STATUS)
call MAPL_GenericStateClockAdd(GC, name="RUN" ,RC=STATUS)
VERIFY_(STATUS)
call MAPL_GenericStateClockAdd(GC, name="FINALIZE" ,RC=STATUS)
VERIFY_(STATUS)
! Generic SetServices
! -------------------
call MAPL_GenericSetServices ( GC, RC=STATUS )
VERIFY_(STATUS)
! All done
! --------
RETURN_(ESMF_SUCCESS)
end subroutine SetServices
!BOP
! !IROUTINE: INITIALIZE -- Initialize method for ExternalOcean wrapper
! !INTERFACE:
subroutine Initialize ( GC, IMPORT, EXPORT, CLOCK, RC )
USE MITGCM_STATE_MOD , ONLY : &
MITGCM_ISTATE_CONTAINER, &
MITGCM_ISTATE, &
MITGCM_ISTATE_WRAP_TYPE, &
GETDP
USE MITGCM_DRIVER_MOD , ONLY : &
DRIVER_INIT, &
DRIVER_RUN
USE STR4C_MOD
! !ARGUMENTS:
type(ESMF_GridComp), intent(INOUT) :: GC ! Gridded component
type(ESMF_State), intent(INOUT) :: IMPORT ! Import state
type(ESMF_State), intent(INOUT) :: EXPORT ! Export state
type(ESMF_Clock), intent(INOUT) :: CLOCK ! The clock
integer, optional, intent( OUT) :: RC ! Error code:
!EOP
! ErrLog Variables
character(len=ESMF_MAXSTR) :: IAm
integer :: STATUS
character(len=ESMF_MAXSTR) :: COMP_NAME
! Locals
! Locals with ESMF and MAPL types
type(MAPL_GenericState), pointer :: State
type(ESMF_Config) :: CF
type(ESMF_Grid) :: Grid
! Locals
! Variable to hold model state for each instance
TYPE(MITGCM_ISTATE_CONTAINER) :: mitgcmIState(1)
TYPE(MITGCM_ISTATE_WRAP_TYPE) wrap
! Variables for getting MPI communicator that component will use
type(ESMF_VM) :: vm
INTEGER myComm
! Variables for holding and setting run directory
character(len=ESMF_MAXSTR) :: ocean_dir
integer*1, pointer :: iarr(:), carr(:)
! Begin...
! Get the target components name and set-up traceback handle.
! -----------------------------------------------------------
Iam = "Initialize"
call ESMF_GridCompGet( gc, NAME=comp_name, RC=status )
VERIFY_(STATUS)
Iam = trim(comp_name) // trim(Iam)
CALL ESMF_GridCompGet(gc, vm=vm, RC=status); VERIFY_(STATUS)
CALL ESMF_VMGet(VM, mpiCommunicator=myComm, rc=RC)
! Get my internal MAPL_Generic state
!-----------------------------------
call MAPL_InternalStateGet ( GC, State, RC=STATUS)
VERIFY_(STATUS)
! Profilers
!----------
call MAPL_GenericStateClockOn(STATE,"TOTAL" )
call MAPL_GenericStateClockOn(STATE,"INITIALIZE")
! Get the grid, configuration
!----------------------------
call ESMF_GridCompGet( GC, grid=Grid, CONFIG = CF, RC=status )
VERIFY_(STATUS)
! Push directory
call ESMF_ConfigGetAttribute( cf, ocean_dir, label='OCEAN_DIR:', rc=status ) ; VERIFY_(STATUS)
CALL STR4C( iarr, TRIM(ocean_dir) )
CALL STR4C( carr, MAX_STRING_LENGTH )
CALL GETDIR(carr)
CALL SETDIR(iarr)
DEALLOCATE(iarr)
! Profilers
! ---------
call MAPL_GenericStateClockOff(STATE,"INITIALIZE")
call MAPL_GenericStateClockOff(STATE,"TOTAL" )
! Generic initialize
! ------------------
call MAPL_GenericInitialize( GC, IMPORT, EXPORT, CLOCK, RC=status )
VERIFY_(STATUS)
! Now do component specific initialization
! ----------------------------------------
CALL DRIVER_INIT( mitgcmIState(1)%p, myComm)
! Pop directory
CALL SETDIR(carr)
DEALLOCATE(carr)
wrap%ptr => mitgcmIState(1)%p
CALL ESMF_UserCompSetInternalState ( GC, 'MITgcm_istate',wrap,status )
VERIFY_(STATUS)
! Add calls to fill key exports
call MAPL_GetPointer(EXPORT, US, 'US' , ALLOC=.TRUE., RC=STATUS); VERIFY_(STATUS)
! All Done
!---------
RETURN_(ESMF_SUCCESS)
end subroutine Initialize
!=================================================================================
!=================================================================================
!BOP
! !IROUTINE: Run -- Run method for ExternalModel wrapper
! !INTERFACE:
subroutine Run ( gc, import, export, clock, rc )
USE MITGCM_STATE_MOD , ONLY : &
MITGCM_ISTATE_CONTAINER, &
MITGCM_ISTATE, &
MITGCM_ISTATE_WRAP_TYPE, &
GETDP
USE MITGCM_DRIVER_MOD , ONLY : &
DRIVER_INIT, &
DRIVER_RUN
USE STR4C_MOD
! !ARGUMENTS:
type(ESMF_GridComp), intent(INOUT) :: gc ! Gridded component
type(ESMF_State), intent(INOUT) :: import ! Import state
type(ESMF_State), intent(INOUT) :: export ! Export state
type(ESMF_Clock), intent(INOUT) :: clock ! The supervisor clock
integer, optional, intent( OUT) :: rc ! Error code:
!EOP
! ErrLog Variables
character(len=ESMF_MAXSTR) :: IAm
integer :: STATUS
character(len=ESMF_MAXSTR) :: COMP_NAME
! Locals
type(MAPL_GenericState), pointer :: State
type(ESMF_Config) :: CF
real, pointer :: TAUX(:,:)
real, pointer :: US(:,:)
REAL*8, POINTER :: uVel(:,:,:,:,:)
! type for getting internal state pointer
TYPE(MITGCM_ISTATE_WRAP_TYPE) wrap
! Variables for holding and setting run directory
character(len=ESMF_MAXSTR) :: ocean_dir
integer*1, pointer :: carr(:)
integer*1, pointer :: iarr(:)
! Begin
!------
! Get the component's name and set-up traceback handle.
! -----------------------------------------------------
WRITE(0,*) ' Starting plug run method '
Iam = "Run"
call ESMF_GridCompGet( gc, NAME=comp_name, RC=status )
VERIFY_(status)
Iam = trim(comp_name) // Iam
! Get my internal MAPL_Generic state
!-----------------------------------
call MAPL_InternalStateGet ( GC, STATE, RC=status)
VERIFY_(STATUS)
! Profilers
!----------
call MAPL_GenericStateClockOn (STATE,"TOTAL")
call MAPL_GenericStateClockOn (STATE,"RUN" )
! Get IMPORT pointers
!--------------------
call MAPL_GetPointer(IMPORT, TAUX, 'TAUX' , RC=STATUS); VERIFY_(STATUS)
IF ( ASSOCIATED(TAUX) ) THEN
WRITE(0,*) ' TAUX is associated '
ELSE
WRITE(0,*) ' TAUX is not associated '
ENDIF
call ESMF_GridCompGet( GC, CONFIG = CF, RC=status )
! Push directory
call ESMF_ConfigGetAttribute( cf, ocean_dir, label='OCEAN_DIR:', rc=status ) ; VERIFY_(STATUS)
call str4c( iarr, TRIM(ocean_dir) )
call str4c( carr, MAX_STRING_LENGTH )
call getdir(carr)
call setdir(iarr)
deallocate(iarr)
! Run component
CALL ESMF_UserCompGetInternalState ( GC, 'MITgcm_istate',wrap,status )
VERIFY_(STATUS)
CALL DRIVER_RUN( wrap%ptr, 1 )
! Pop directory
call setdir(carr)
deallocate(carr)
CALL GETDP( wrap%ptr, 'UVEL', uVel, rc )
! US(:,:)=uVEL(:,:,1,1,1)
WRITE(0,*) ' UBOUND US ', UBOUND(US,1), UBOUND(US,2)
WRITE(0,*) ' UBOUND UVEL ', UBOUND(UVEL,1), UBOUND(UVEL,2)
! Get EXPORT pointers
!--------------------
call MAPL_GetPointer(EXPORT, US, 'US' , ALLOC=.TRUE., RC=STATUS); VERIFY_(STATUS)
IF ( ASSOCIATED(US) ) THEN
WRITE(0,*) ' US is associated '
WRITE(0,*) ' LBOUND(US) = ', LBOUND(US)
WRITE(0,*) ' UBOUND(US) = ', UBOUND(US)
ELSE
WRITE(0,*) ' US is not associated '
ENDIF
call MAPL_GenericStateClockOff(STATE,"RUN" )
call MAPL_GenericStateClockOff(STATE,"TOTAL" )
! All Done
!---------
WRITE(0,*) ' Finished plug run method '
RETURN_(ESMF_SUCCESS)
end subroutine Run
!BOP
! !IROUTINE: Finalize -- Finalize method for GuestOcean wrapper
! !INTERFACE:
subroutine Finalize ( gc, import, export, clock, rc )
! !ARGUMENTS:
type(ESMF_GridComp), intent(INOUT) :: gc ! Gridded component
type(ESMF_State), intent(INOUT) :: import ! Import state
type(ESMF_State), intent(INOUT) :: export ! Export state
type(ESMF_Clock), intent(INOUT) :: clock ! The supervisor clock
integer, optional, intent( OUT) :: rc ! Error code:
!EOP
type(MAPL_GenericState), pointer :: State
! ErrLog Variables
character(len=ESMF_MAXSTR) :: IAm
integer :: STATUS
character(len=ESMF_MAXSTR) :: COMP_NAME
! Locals with MOM types
! Get the target components name and set-up traceback handle.
! -----------------------------------------------------------
Iam = "Finalize"
call ESMF_GridCompGet( gc, NAME=comp_name, RC=status )
VERIFY_(STATUS)
Iam = trim(comp_name) // Iam
! Get my internal MAPL_Generic state
!-----------------------------------
call MAPL_InternalStateGet ( GC, STATE, RC=status)
VERIFY_(STATUS)
! Profilers
!----------
call MAPL_GenericStateClockOn(STATE,"TOTAL" )
call MAPL_GenericStateClockOn(STATE,"FINALIZE")
call MAPL_GenericFinalize( GC, IMPORT, EXPORT, CLOCK, RC=status )
VERIFY_(STATUS)
! All Done
!---------
RETURN_(ESMF_SUCCESS)
end subroutine Finalize
!====================================================================
end module MIT_GEOS5PlugMod
