MIT GEOS5PlugMod

From Maplcode.org

Jump to: navigation, search

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