diff --git a/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/CMakeLists.txt b/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/CMakeLists.txt index 09ff7482e..9a4ccef2a 100644 --- a/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/CMakeLists.txt +++ b/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/CMakeLists.txt @@ -1,6 +1,35 @@ esma_set_this () +# First set alldirs to empty +set(alldirs) +# ... and srcs to the LandIceGridComp +set (srcs GEOS_LandIceGridComp.F90) + +# Then try to find ISSM +find_package (ISSM QUIET COMPONENTS Core) + +if(ISSM_FOUND) + # If ISSM is found, append the directory to alldirs + message(STATUS "ISSM found, building gridded component") + list (APPEND alldirs GEOSissm_GridComp) +else() + # If ISSM is not found, append the stub component to srcs + message(STATUS "ISSM not found, using stub component") + # For esma_create_stub_component, we need the name of the *module* + # that the landice gc is expecting, minus the mod. Also we + # have to use the variable srcs but not the ${srcs} because + # esma_create_stub_component is expecting the list itself, not the + # contents of the list. + esma_create_stub_component(srcs GEOS_IssmGridComp) +endif() + +# We have to do the above way because what esma_create_stub_component +# does is to append the stub component it creates in the build tree to a +# list of sources srcs. So if ISSM is found, we go into the subdir and +# build the real component, and if ISSM is not found, we create the stub +# component and append it to srcs. + esma_add_library (${this} - SRCS GEOS_LandIceGridComp.F90 - DEPENDENCIES MAPL GEOS_Shared GEOS_SurfaceShared ESMF::ESMF NetCDF::NetCDF_Fortran - ) + SRCS ${srcs} + SUBCOMPONENTS ${alldirs} + DEPENDENCIES MAPL GEOS_Shared GEOS_SurfaceShared ESMF::ESMF NetCDF::NetCDF_Fortran) diff --git a/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/GEOS_LandIceGridComp.F90 b/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/GEOS_LandIceGridComp.F90 index c22870a00..b0e78393c 100644 --- a/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/GEOS_LandIceGridComp.F90 +++ b/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/GEOS_LandIceGridComp.F90 @@ -43,6 +43,7 @@ module GEOS_LandiceGridCompMod use MAPL use GEOS_UtilsMod use DragCoefficientsMod + use GEOS_IssmGridCompMod, only : IssmSetServices => SetServices implicit none private @@ -100,6 +101,8 @@ module GEOS_LandiceGridCompMod public SetServices + integer :: ISSM + ! !DESCRIPTION: ! ! {\tt GEOS\_Landice} is a light-weight gridded component that updates @@ -149,6 +152,7 @@ subroutine SetServices ( GC, RC ) type(MAPL_MetaComp), pointer :: MAPL + integer :: DO_ISSM ! ISSM flag ! Begin... @@ -159,20 +163,29 @@ subroutine SetServices ( GC, RC ) VERIFY_(STATUS) Iam = trim(COMP_NAME) // 'SetServices' + ! Get my internal MAPL_Generic state +!----------------------------------- + + call MAPL_GetObjectFromGC ( GC, MAPL, RC=STATUS) + VERIFY_(STATUS) + ! Set the Run entry point ! ----------------------- + !add initialize method for child (ISSM) + call MAPL_GetResource (MAPL, DO_ISSM, label='DO_ISSM:', DEFAULT=0, __RC__ ) - call MAPL_GridCompSetEntryPoint ( GC, ESMF_METHOD_RUN, Run1, RC=STATUS ) - VERIFY_(STATUS) - call MAPL_GridCompSetEntryPoint ( GC, ESMF_METHOD_RUN, Run2, RC=STATUS ) - VERIFY_(STATUS) + + call MAPL_GridCompSetEntryPoint ( GC, ESMF_METHOD_INITIALIZE, Initialize, RC=STATUS ) + VERIFY_(STATUS) -! Get my internal MAPL_Generic state -!----------------------------------- - call MAPL_GetObjectFromGC ( GC, MAPL, RC=STATUS) - VERIFY_(STATUS) + call MAPL_GridCompSetEntryPoint ( GC, ESMF_METHOD_RUN, Run1, RC=STATUS ) + VERIFY_(STATUS) + call MAPL_GridCompSetEntryPoint ( GC, ESMF_METHOD_RUN, Run2, RC=STATUS ) + VERIFY_(STATUS) + ! Get resource parameters + ! ----------------------- call MAPL_GetResource (MAPL, SURFRC, label = 'SURFRC:', default = 'GEOS_SurfaceGridComp.rc', RC=STATUS) ; VERIFY_(STATUS) SCF = ESMF_ConfigCreate(rc=status) ; VERIFY_(STATUS) call ESMF_ConfigLoadFile(SCF,SURFRC,rc=status) ; VERIFY_(STATUS) @@ -188,6 +201,15 @@ subroutine SetServices ( GC, RC ) ! !Export state: + call MAPL_AddExportSpec(GC, & + SHORT_NAME = 'ICESMB', & + LONG_NAME = 'ice_surface_mass_balance', & + UNITS = 'kg m-2 s-1', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + call MAPL_AddExportSpec(GC, & SHORT_NAME = 'EMIS', & LONG_NAME = 'surface_emissivity', & @@ -1618,6 +1640,16 @@ subroutine SetServices ( GC, RC ) VERIFY_(STATUS) !EOS + + if (DO_ISSM==1) then + ! Add ISSM child gridcomp + ISSM = MAPL_AddChild(GC, NAME='ISSM', SS=IssmSetServices, RC=STATUS) + VERIFY_(STATUS) + + ! ISSM imports will be satisfied by landice + call MAPL_TerminateImport(GC, CHILD = ISSM, RC=STATUS) + VERIFY_(STATUS) + end if ! Set the Profiling timers ! ------------------------ @@ -1641,6 +1673,88 @@ end subroutine SetServices !BOP + + subroutine Initialize ( GC, IMPORT, EXPORT, CLOCK, RC ) + ! this is for ISSM to have access to to the tile locstream + + ! !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 + + ! !DESCRIPTION: The Initialize method of the Landice Gridded Component. + + !EOP + + ! ErrLog Variables + + character(len=ESMF_MAXSTR) :: IAm + integer :: STATUS + character(len=ESMF_MAXSTR) :: COMP_NAME + + ! Local derived type aliases + + type (MAPL_MetaComp ), pointer :: MAPL + type (MAPL_MetaComp ), pointer :: CHILD_MAPL + type (MAPL_LocStream ) :: LOCSTREAM + type (ESMF_Config ) :: CF + type (ESMF_GridComp ), pointer :: GCS(:) + + integer :: I + + !============================================================================= + + ! Begin... + + ! Get the target components name and set-up traceback handle. + ! ----------------------------------------------------------- + + call ESMF_GridCompGet ( GC, name=COMP_NAME, RC=STATUS ) + VERIFY_(STATUS) + Iam = trim(COMP_NAME) // "Initialize" + + ! Get my internal MAPL_Generic state + !----------------------------------- + + call MAPL_GetObjectFromGC ( GC, MAPL, RC=STATUS) + VERIFY_(STATUS) + + call MAPL_TimerOn(MAPL,"INITIALIZE", RC=STATUS ); VERIFY_(STATUS) + call MAPL_TimerOn(MAPL,"TOTAL", RC=STATUS ); VERIFY_(STATUS) + + ! Get the landice tilegrid and the child components + !----------------------------------------------- + + call MAPL_Get (MAPL, LOCSTREAM=LOCSTREAM, GCS=GCS, RC=STATUS ) + VERIFY_(STATUS) + + ! Place the land tilegrid in the generic state of each child component + !--------------------------------------------------------------------- + + do I = 1, SIZE(GCS) + call MAPL_GetObjectFromGC( GCS(I), CHILD_MAPL, RC=STATUS ) + VERIFY_(STATUS) + call MAPL_Set (CHILD_MAPL, LOCSTREAM=LOCSTREAM, RC=STATUS ) + VERIFY_(STATUS) + end do + + call MAPL_TimerOff(MAPL,"TOTAL", RC=STATUS ); VERIFY_(STATUS) + + ! Call Initialize for every Child + !-------------------------------- + + call MAPL_GenericInitialize ( GC, IMPORT, EXPORT, CLOCK, RC=STATUS) + VERIFY_(STATUS) + + call MAPL_TimerOff(MAPL,"INITIALIZE", RC=STATUS ); VERIFY_(STATUS) + + RETURN_(ESMF_SUCCESS) + end subroutine Initialize + + ! !IROUTINE: RUN1 -- First Run stage for the LandIce component !INTERFACE: @@ -2135,6 +2249,8 @@ subroutine RUN2 ( GC, IMPORT, EXPORT, CLOCK, RC ) !EOP + type (ESMF_State), pointer :: GIM(:) ! Import state ISSM + ! ErrLog Variables @@ -2155,6 +2271,7 @@ subroutine RUN2 ( GC, IMPORT, EXPORT, CLOCK, RC ) type(MAPL_SunOrbit) :: ORBIT integer :: LANDICE_OFFLINE + integer :: DO_ISSM ! ISSM flag !============================================================================= ! Begin... @@ -2172,6 +2289,13 @@ subroutine RUN2 ( GC, IMPORT, EXPORT, CLOCK, RC ) call MAPL_GetObjectFromGC ( GC, MAPL, RC=STATUS) VERIFY_(STATUS) + call MAPL_GetResource (MAPL, DO_ISSM, label='DO_ISSM:', DEFAULT=0, __RC__ ) + + ! Get import state of child (ISSM) + if (DO_ISSM == 1) then + call MAPL_Get(MAPL, GIM=GIM, RC=STATUS ) + VERIFY_(STATUS) + end if ! Start Total timer !------------------ @@ -2227,8 +2351,13 @@ subroutine LANDICECORE(RC) character(len=ESMF_MAXSTR) :: IAm integer :: STATUS -! pointers to export + ! pointer to child import (ISSM) + real, pointer, dimension(: ) :: ICESMB_ISSM + + +! pointers to export + real, pointer, dimension(: ) :: ICESMB real, pointer, dimension(: ) :: EMISS real, pointer, dimension(: ) :: ALBVF real, pointer, dimension(: ) :: ALBVR @@ -2460,7 +2589,6 @@ subroutine LANDICECORE(RC) real, parameter :: LANDICEDEPTH_ = 0.07 ! water equiv depth of top layer real, parameter :: LANDICECOND_ = 1.2 ! ice conductivity divided by depth of bottom layer real, parameter :: LANDICETDEEP_ = 230. ! deep ice temperature - ! Begin... !---------- @@ -2542,7 +2670,7 @@ subroutine LANDICECORE(RC) ! Pointers to outputs !-------------------- - + call MAPL_GetPointer(EXPORT,ICESMB , 'ICESMB' ,alloc=.true., RC=STATUS); VERIFY_(STATUS) call MAPL_GetPointer(EXPORT,EMISS , 'EMIS' , RC=STATUS); VERIFY_(STATUS) call MAPL_GetPointer(EXPORT,ALBVF , 'ALBVF' , RC=STATUS); VERIFY_(STATUS) call MAPL_GetPointer(EXPORT,ALBVR , 'ALBVR' , RC=STATUS); VERIFY_(STATUS) @@ -3241,8 +3369,20 @@ subroutine LANDICECORE(RC) if(associated(ASNOW)) ASNOW = FR(:,SNOW) if(associated(SMELT )) SMELT = PERC if(associated(RAINRFZ )) RAINRFZ = FR(:,ICE) * RAINRF + if(associated(MELTWTR )) MELTWTR = MELTWTR + MLT + + ! Calculate surface mass balance (SMB) for ISSM + if(associated(ICESMB)) ICESMB = ACCUM - RUNOFF + + ! Set child (ISSM) SMB import pointer to landice export values + if (DO_ISSM == 1) then + call MAPL_GetPointer(GIM(ISSM), ICESMB_ISSM, 'ICESMB' , RC=STATUS) + end if + + if(associated(ICESMB_ISSM)) ICESMB_ISSM(:) = ICESMB(:) + ! Update snow and landice albedos to anticipate ! next radiation calculation !----------------------------------------------- @@ -3376,6 +3516,12 @@ subroutine LANDICECORE(RC) WEBOT = WESNBOT / DT end if + ! Run ISSM (checks if ISSM_ALARM is ringing) + if (DO_ISSM==1) then + call MAPL_GenericRunChildren(GC, IMPORT, EXPORT, CLOCK, RC=STATUS) + VERIFY_(STATUS) + end if + if(allocated (MLT)) deallocate(MLT , STAT=STATUS); VERIFY_(STATUS) if(allocated (DTS)) deallocate(DTS , STAT=STATUS); VERIFY_(STATUS) if(allocated (DQS)) deallocate(DQS , STAT=STATUS); VERIFY_(STATUS) diff --git a/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/GEOSissm_GridComp/CMakeLists.txt b/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/GEOSissm_GridComp/CMakeLists.txt new file mode 100644 index 000000000..b240dacfa --- /dev/null +++ b/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/GEOSissm_GridComp/CMakeLists.txt @@ -0,0 +1,9 @@ +find_package (ISSM REQUIRED COMPONENTS Core) + +esma_set_this () + +esma_add_library (${this} + SRCS GEOS_ISSMGridComp.F90 + DEPENDENCIES MAPL GEOS_Shared GEOS_SurfaceShared ESMF::ESMF NetCDF::NetCDF_Fortran ISSM::Core + ) + diff --git a/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/GEOSissm_GridComp/GEOS_ISSMGridComp.F90 b/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/GEOSissm_GridComp/GEOS_ISSMGridComp.F90 new file mode 100644 index 000000000..83c4bdee4 --- /dev/null +++ b/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSlandice_GridComp/GEOSissm_GridComp/GEOS_ISSMGridComp.F90 @@ -0,0 +1,796 @@ +! $Id$ + +#include "MAPL_Generic.h" + +module GEOS_IssmGridCompMod + +!BOP +! !MODULE: GEOS_ISSM --- Runs ISSM (Ice-sheet and Sea-level System Model) +! +! +! !DESCRIPTION: +! +! {\tt GEOS\_ISSM} is a wrapper that calls ISSM (C++) IRF methods +! Imports: ICESMB (defined on landice tiles) +! Exports: ICESURF, ICETHICK, ICEVEL, ICESMB (defined on mesh) +! *** NOTES: +! (*) currently we run over all input files (*.bin) that are found in ISSM_EXPDIR +! (e.g., Greenland + Antarctica + any other glaciers that have been configured) +! (*) ISSM meshes are internal to ISSM (C++ source)--we create an ESMF_MESH version for regridding +! imports/exports that is the global combination of all ISSM meshes +! (*) we transform imports from landice tiles to attached grid, then regrid to the mesh +! (*) ISSM outputs are saved with HISTORY via a 'mesh tile space' developed by Weiyuan Jiang (GMAO SI Team) +! + +! !USES: +use iso_fortran_env, only: dp=>real64 +use iso_c_binding, only: c_ptr, c_double, c_f_pointer, c_null_char, c_char, c_loc, c_int +use ESMF +use MAPL +use GEOS_UtilsMod + +implicit none + +! declare interface to the ISSM C++ library (arguments described in Initialize & Run below) +interface +subroutine InitializeISSM(expdir, num_elements, num_nodes, comm) bind(c, name="InitializeISSM") + import :: c_char, c_int + character(c_char), dimension(*) :: expdir + integer(c_int) :: num_elements + integer(c_int) :: num_nodes + integer(c_int) :: comm +end subroutine InitializeISSM + +subroutine RunISSM(dt, gcm_forcings, issm_outputs) bind(C,NAME="RunISSM") + import :: c_ptr, c_double + real(c_double), value :: dt + type(c_ptr), value :: gcm_forcings + type(c_ptr), value :: issm_outputs +end subroutine RunISSM + +subroutine GetNodesISSM(nodeIds, nodeCoords) bind(C,NAME="GetNodesISSM") + import :: c_ptr + type(c_ptr), value :: nodeIds + type(c_ptr), value :: nodeCoords ! +end subroutine GetNodesISSM + +subroutine GetElementsISSM(elementIds, elementConn, elementCoords, glacIds) bind(C,NAME="GetElementsISSM") + import :: c_ptr + type(c_ptr), value :: elementIds + type(c_ptr), value :: elementConn + type(c_ptr), value :: elementCoords + type(c_ptr), value :: glacIds +end subroutine GetElementsISSM + +subroutine FinalizeISSM() bind(C,NAME="FinalizeISSM") +end subroutine FinalizeISSM + +end interface + + +private + + +public SetServices + +! !DESCRIPTION: +! +! {\tt GEOS\_ISSM} gridcomp runs NASA's Ice-sheet and Sea-level System Model (ISSM) +! + +! private internal state for regridding +type T_ISSM_STATE + private + type(ESMF_RouteHandle) :: routehandle_m2g ! routehandle for regridding mesh to grid + type(ESMF_RouteHandle) :: routehandle_g2m ! routehandle for regridding grid to mesh + type(ESMF_GRID) :: grid ! original grid + type(MAPL_LocStream) :: locstream ! original locstream +end type T_ISSM_STATE + +! Wrapper for extracting internal state +! ------------------------------------- +type ISSM_WRAP + type (T_ISSM_STATE), pointer :: ptr +end type ISSM_WRAP + +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: +! This version uses the MAPL\_GenericSetServices Here we set the initialize method, +! run method, and finalize method because we are interfacing with the external ISSM +! library IRF methods. We also add the state variable specifications (also generic) +! to our instance of the generic state. This is the way our true state variables get into +! the ESMF\_State INTERNAL, which is in the MAPL\_MetaComp. The import +! variables are allocated and initialized by generic. + +!EOP + +!============================================================================= + +! ErrLog Variables + + character(len=ESMF_MAXSTR) :: IAm + integer :: STATUS + character(len=ESMF_MAXSTR) :: COMP_NAME + +!============================================================================= + + type(MAPL_MetaComp), pointer :: MAPL + + type (ESMF_Config) :: CF + + real :: dt ! time step [s] (ISSM_DT set in AGCM.rc) + + ! Get my internal MAPL_Generic state + + ! Begin... + +! Get my name and set-up traceback handle +! --------------------------------------- + + call ESMF_GridCompGet( GC, NAME=COMP_NAME, RC=STATUS ) + VERIFY_(STATUS) + Iam = trim(COMP_NAME) // 'SetServices' + +! Set the Initialize, Run, and Finalize entry points +!----------------------------------- + + call MAPL_GridCompSetEntryPoint ( GC, ESMF_METHOD_INITIALIZE, Initialize, RC=STATUS) + VERIFY_(STATUS) + + call MAPL_GridCompSetEntryPoint ( GC, ESMF_METHOD_RUN, Run, RC=STATUS) + VERIFY_(STATUS) + + call MAPL_GridCompSetEntryPoint ( GC, ESMF_METHOD_FINALIZE, Finalize, RC=STATUS) + VERIFY_(STATUS) + +!----------------------------------- + + call MAPL_GetObjectFromGC (GC, MAPL, RC=STATUS) + VERIFY_(STATUS) + + call ESMF_GridCompGet(GC, CONFIG = CF, RC=STATUS) + VERIFY_(STATUS) + + ! get timestep for ISSM + call ESMF_ConfigGetAttribute(CF, dt, Label=trim(COMP_NAME)//"_DT:", DEFAULT=302400.0, RC=STATUS) + VERIFY_(STATUS) + + + ! Set the state variable specs. +!----------------------------------- + +! Import states: + call MAPL_AddImportSpec(GC, & + SHORT_NAME = 'ICESMB', & + LONG_NAME = 'ice_surface_mass_balance', & + UNITS = 'kg m-2 s-1', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + AVERAGING_INTERVAL = nint(dt), & + REFRESH_INTERVAL = nint(dt), & + RC=STATUS ) + VERIFY_(STATUS) + +! Export states: + call MAPL_AddExportSpec(GC, & + SHORT_NAME = 'ICESURF', & + LONG_NAME = 'ice_sheet_elevation', & + UNITS = 'm', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC, & + SHORT_NAME = 'ICEVEL', & + LONG_NAME = 'ice_flow_speed', & + UNITS = 'm s-1', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC, & + SHORT_NAME = 'ICETHICK', & + LONG_NAME = 'ice_thickness', & + UNITS = 'm', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC, & + SHORT_NAME = 'ICESMB', & + LONG_NAME = 'ice_surface_mass_balance', & + UNITS = 'kg m-2 s-1', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + + +! Set the Profiling timers +! ------------------------ + + call MAPL_TimerAdd(GC, name="RUN" ,RC=STATUS) + VERIFY_(STATUS) + + +! ---------------------------------- + call MAPL_GenericSetServices ( GC, RC=STATUS) + VERIFY_(STATUS) + + + RETURN_(ESMF_SUCCESS) + + end subroutine SetServices + + ! ! INITIALIZE: + + subroutine Initialize ( GC, IMPORT, EXPORT, CLOCK, RC ) + 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 + type(MAPL_MetaComp), pointer :: MAPL + + ! ErrLog Variables + character(len=ESMF_MAXSTR) :: IAm + integer :: STATUS + character(len=ESMF_MAXSTR) :: COMP_NAME + + ! virtual machine / mpi comm + type(ESMF_VM) :: vm + integer(c_int) :: comm ! mpi comm to pass to ISSM + + ! mesh information + type(ESMF_Mesh) :: mesh ! ESMF_Mesh representation of ISSM mesh + integer, allocatable :: elementTypes(:) ! element geometry type (triangles) + integer(c_int) :: num_elements ! number of elements on PET + integer(c_int) :: num_nodes ! number of nodes on PET + integer, pointer, dimension(:) :: elementIds => null() ! list of elements local to PET + integer, pointer, dimension(:) :: elementConn => null() ! element connectivity (nodes indices) + real(dp),pointer, dimension(:) :: elementCoords => null() ! element centroids + real(dp),pointer,dimension(:) :: nodeCoords => null() ! node coordinates (longitude,latitude) + integer, pointer, dimension(:) :: nodeIds => null() ! list of nodes local to PET + integer, pointer, dimension(:) :: glacIds => null() ! glacier ID for each element + + ! regridding + type(ESMF_Grid) :: grid ! atmospheric grid + type(ESMF_RouteHandle) :: routehandle_m2g ! routehandle for regridding mesh to grid + type(ESMF_RouteHandle) :: routehandle_g2m ! routehandle for regridding grid to mesh + type(ESMF_Field) :: meshField ! field on mesh + type(ESMF_Field) :: gridField ! field on grid + type(T_ISSM_STATE), pointer :: internal_state ! store the routehandles for access during run + type(ISSM_WRAP) :: wrap ! wrapper for routehandle container + + ! command-line arguments to initialize ISSM + integer :: i,j ! loop indices + character(len=ESMF_MAXSTR) :: ISSM_EXPDIR ! directory containing ISSM input file + character(len=ESMF_MAXSTR) :: EXPDIR ! C++ compatible ISSM_EXPDIR string + + ! variables for saving mesh output + type(ESMF_Field) :: field ! for fieldwrites + real(dp), pointer, dimension(:) :: field_saver => null() + real(dp), pointer, dimension(:) :: nodelons => null() + real(dp), pointer, dimension(:) :: nodelats => null() + integer, pointer, dimension(:) :: conn_slice => null() + character(len=16) :: varname + character(len=1) :: istr + + ! variables for mesh tile space + type(ESMF_Grid) :: mesh_grid + type(MAPL_LocStream) :: mesh_locstream + + ! 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) + + + ! Get my internal MAPL_Generic state + !----------------------------------- + + call MAPL_GetObjectFromGC ( GC, MAPL, RC=STATUS) + VERIFY_(STATUS) + + + call ESMF_VMGetCurrent(vm, rc=STATUS) + VERIFY_(STATUS) + + call ESMF_VMGet(vm,mpiCommunicator=comm,rc=STATUS) + VERIFY_(STATUS) + + ! **************************************************** + ! call ISSM initialize C++ code so we can set up mesh + + call MAPL_GetResource(MAPL, ISSM_EXPDIR, Label=trim(COMP_NAME)//"_EXPDIR:", RC=STATUS) + VERIFY_(STATUS) + + EXPDIR = trim(ISSM_EXPDIR)//c_null_char ! create string for C++ + + ! Call the C++ function for initializing ISSM + ! gets the number of elements and nodes of the mesh + call InitializeISSM(EXPDIR, num_elements, num_nodes, comm) + + !allocate mesh-related pointers + allocate(nodeCoords(2*num_nodes)) + allocate(nodeIds(num_nodes)) + allocate(elementTypes(num_elements)) + allocate(elementIds(num_elements)) + allocate(glacIds(num_elements)) + allocate(elementConn(3*num_elements)) + allocate(elementCoords(2*num_elements)) + + ! get information about nodes and elements + ! node coords and element coords (centroids) are in (lon,lat) + call GetNodesISSM(c_loc(nodeIds), c_loc(nodeCoords)) + call GetElementsISSM(c_loc(elementIds), c_loc(elementConn), c_loc(elementCoords),c_loc(glacIds)) + + elementTypes(:) = ESMF_MESHELEMTYPE_TRI ! triangular elements + + ! create the ESMF mesh from ISSM mesh properties + mesh = ESMF_MeshCreate(parametricDim=2, spatialDim=2, nodeIds=nodeIds, nodeCoords=nodeCoords, & + elementIds=elementIds, elementTypes=elementTypes, elementConn=elementConn,& + elementCoords=elementCoords,coordSys=ESMF_COORDSYS_SPH_DEG, rc=STATUS) + + VERIFY_(STATUS) + + ! associate ESMF_Mesh representation of ISSM mesh with GC for regridding imports/exports in run method + call ESMF_GridCompSet(GC,mesh=mesh,rc=STATUS) + VERIFY_(STATUS) + + ! Set up regridding next + !----------------------------------- + ! create source field on ISSM mesh + meshField = ESMF_FieldCreate(mesh=mesh,typekind=ESMF_TYPEKIND_R8,meshloc=ESMF_MESHLOC_ELEMENT,rc=STATUS) + VERIFY_(STATUS) + + ! get atmospheric grid + call ESMF_GridCompGet( GC, GRID=grid, RC=status ); VERIFY_(STATUS) + + ! create destination field on atmospheric grid + gridField = ESMF_FieldCreate(grid=grid,typekind=ESMF_TYPEKIND_R4,rc=STATUS); VERIFY_(STATUS) + + ! create routehandle for mesh-to-grid regridding + call ESMF_FieldRegridStore(srcField=meshField, dstField=gridField,routehandle=routehandle_m2g,unmappedaction=ESMF_UNMAPPEDACTION_IGNORE,rc=STATUS) + VERIFY_(STATUS) + + ! create routehandle for grid-to-mesh regridding + call ESMF_FieldRegridStore(srcField=gridField, dstField=meshField,routehandle=routehandle_g2m,unmappedaction=ESMF_UNMAPPEDACTION_IGNORE,rc=STATUS) + VERIFY_(STATUS) + + ! create pointer to routehandle for component's private internal state + ! also store attached/atmospheric grid and landice tile locstream in internal state + allocate(internal_state, stat=status) + VERIFY_(STATUS) + internal_state%routehandle_m2g = routehandle_m2g + internal_state%routehandle_g2m = routehandle_g2m + internal_state%grid = grid + call MAPL_Get(MAPL, LocStream = internal_state%locstream, _RC) + + wrap%ptr => internal_state + call ESMF_UserCompSetInternalState ( GC, 'ISSM_WRAP', wrap, status ) + VERIFY_(STATUS) + + ! ------------------------------ BEGIN SAVE MESH --------------------------- + allocate(field_saver(num_elements)) + allocate(nodelons(num_nodes)) + allocate(nodelats(num_nodes)) + allocate(conn_slice(num_elements)) + + nodelons = nodeCoords(1::2) + nodelats = nodeCoords(2::2) + + ! save nodes for reconstructing mesh output after running + ! looping over three nodes per triangle + do i = 1, 3 + conn_slice = [( elementConn(j), j=i, size(elementConn), 3 )] + + write(istr, '(I1)') i + + ! ---- longitude ---- + varname = "node" // istr // "lon" + field_saver = nodelons(conn_slice) + field = ESMF_FieldCreate(mesh=mesh,farrayPtr=field_saver,meshloc=ESMF_MESHLOC_ELEMENT, rc=STATUS) + VERIFY_(STATUS) + call ESMF_FieldWrite(field, trim(ISSM_EXPDIR)//"/"//"issm_mesh.nc", variableName=varname, rc=STATUS) + VERIFY_(STATUS) + call ESMF_FieldDestroy(field, rc=STATUS) + VERIFY_(STATUS) + + ! ---- latitude ---- + varname = "node" // istr // "lat" + field_saver = nodelats(conn_slice) + field = ESMF_FieldCreate(mesh=mesh, farrayPtr=field_saver,meshloc=ESMF_MESHLOC_ELEMENT, rc=STATUS) + VERIFY_(STATUS) + call ESMF_FieldWrite(field, trim(ISSM_EXPDIR)//"/"//"issm_mesh.nc", variableName=varname, rc=STATUS) + VERIFY_(STATUS) + call ESMF_FieldDestroy(field, rc=STATUS) + VERIFY_(STATUS) + end do + + ! ---- save element IDs ---- + varname = "elementIds" + field_saver = elementIds(:) + field = ESMF_FieldCreate(mesh=mesh, farrayPtr=field_saver,meshloc=ESMF_MESHLOC_ELEMENT, rc=STATUS) + VERIFY_(STATUS) + call ESMF_FieldWrite(field, trim(ISSM_EXPDIR)//"/"//"issm_mesh.nc", variableName=varname, rc=STATUS) + VERIFY_(STATUS) + call ESMF_FieldDestroy(field, rc=STATUS) + VERIFY_(STATUS) + + + ! ---- save glacier IDs ---- + varname = "glacIds" + field_saver = glacIds(:) + field = ESMF_FieldCreate(mesh=mesh, farrayPtr=field_saver,meshloc=ESMF_MESHLOC_ELEMENT, rc=STATUS) + VERIFY_(STATUS) + call ESMF_FieldWrite(field, trim(ISSM_EXPDIR)//"/"//"issm_mesh.nc", variableName=varname, rc=STATUS) + VERIFY_(STATUS) + call ESMF_FieldDestroy(field, rc=STATUS) + VERIFY_(STATUS) + ! ------------------------------ END SAVE MESH --------------------------- + + ! Create losctream that match mesh element id, then set it to this GC and MAPL + ! + ! note: original attached/atmospheric grid and landice tile locsstream have + ! been stored in the internal state + mesh_grid = create_mesh_grid(_RC) + call MAPL_LocstreamCreate(mesh_locstream, mesh_grid, local_id=elementIds, _RC) + call MAPL%grid%set(mesh_grid, _RC) + call ESMF_GridCompSet(gc, grid=mesh_grid, _RC) + Call MAPL_set(MAPL, locstream = mesh_locstream, _RC) + + ! deallocate pointers + deallocate(field_saver) + deallocate(nodelons) + deallocate(nodelats) + deallocate(conn_slice) + deallocate(nodeCoords) + deallocate(nodeIds) + deallocate(elementTypes) + deallocate(elementIds) + deallocate(elementConn) + deallocate(elementCoords) + deallocate(glacIds) + + ! generic initialize + call MAPL_GenericInitialize( GC, IMPORT, EXPORT, CLOCK, RC=STATUS ) + VERIFY_(STATUS) + RETURN_(ESMF_SUCCESS) + + contains + + function create_mesh_grid(rc) result(mesh_grid) + type (ESMF_Grid) :: mesh_grid + integer, optional, intent(out) :: rc + integer :: status, nDEs, num(1) + real(kind=8), pointer :: centers(:,:) + integer, allocatable :: IMs(:) + + + !comm, VM, num_elements are from containing subroutine + call ESMF_VMGet(vm, petcount=nDEs, _RC) + allocate(IMS(nDEs)) + num(1) = num_elements + call MAPL_CommsAllGather(vm, num, 1, IMs, 1, _RC) + + ! create a mesh-grid in 1D + mesh_grid = ESMF_GridCreate( & + name='MESH_GRID', & + countsPerDEDim1=IMs, & + countsPerDEDim2=[1], & + indexFlag=ESMF_INDEX_DELOCAL, & + coordDep1 = (/1,2/), & + coordDep2 = (/1,2/), & + gridEdgeLWidth = (/0,0/), & + gridEdgeUWidth = (/0,0/), & + _RC) + ! coord and centers are required for a valid grid, + ! even if their values don't make sense; + ! later on, the coord will be set to element's lat lon. + call ESMF_GridAddCoord(mesh_grid, _RC) + _VERIFY(status) + + call ESMF_GridGetCoord(mesh_grid, coordDim=1, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + farrayPtr=centers, _RC) + centers = 0 ! can assign element coord: elementCoords(1::2)? + call ESMF_GridGetCoord(mesh_grid, coordDim=2, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + farrayPtr=centers, _RC) + centers = 0 ! elementCoords(2::2)? + + _RETURN(_SUCCESS) + end function create_mesh_grid + + end subroutine Initialize + + !BOP + + +subroutine RUN ( GC, IMPORT, EXPORT, CLOCK, RC ) +! ! Run ISSM ice-sheet model +! !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 + type (ESMF_Alarm) :: ALARM ! run alarm for ISSM component + + ! ErrLog Variables + character(len=ESMF_MAXSTR) :: IAm + integer :: STATUS + character(len=ESMF_MAXSTR) :: COMP_NAME + + type(MAPL_MetaComp), pointer :: MAPL + type(ESMF_VM) :: vm + + ! regridding + type(ESMF_RouteHandle) :: routehandle_m2g ! mesh to grid routehandle + type(ESMF_RouteHandle) :: routehandle_g2m ! grid to mesh routehandle + type(ESMF_Field) :: srcField ! source field for regridding + type(ESMF_Field) :: dstField ! destination field for regridding + type(T_ISSM_STATE), pointer :: internal_state=>null() ! stores the routehandles + type(ISSM_WRAP) :: wrap ! wrapper for routehandle container + type(ESMF_Mesh) :: mesh ! ESMF version of ISSM mesh + integer(c_int) :: num_elements ! number of elements on each PET + integer :: IM, JM, local_dims(3) ! local grid size + + ! tile information + integer :: NT ! number of landice tiles + + ! surface mass balance on mesh, grid, tile + real(dp), pointer, dimension(:) :: ICESMB_MESH => null() ! surface mass balce on mesh elements + real, pointer, dimension(:,:) :: ICESMB_GRID => null() ! surface mass balance on grid + real, pointer, dimension(:) :: ICESMB_TILE => null() ! surface mass balance on landice tiles + real, pointer, dimension(:) :: ICESMB_IM => null() ! pointer to SMB import state (landice tiles) + real, pointer, dimension(:) :: ICESMB_EX => null() ! pointer to SMB export state (mesh) + + ! ISSM Outputs (all defined on mesh elements) + integer :: num_outputs = 3 ! number of outputs + real(dp), pointer, dimension(:) :: ISSM_OUTPUTS => null() ! pointer containing all outputs: + real(dp), pointer, dimension(:) :: ICETHICK => null() ! ice thickness on mesh + real(dp), pointer, dimension(:) :: ICEVEL => null() ! ice flow speed on mesh + real(dp), pointer, dimension(:) :: ICESURF => null() ! ice elevation on mesh + + ! need separate pointers for export states because ISSM expects double precision + real, pointer, dimension(:) :: ICESURF_EX => null() ! pointer to ice-sheet elevation export state + real, pointer, dimension(:) :: ICEVEL_EX => null() ! pointer to ice flow speed export state + real, pointer, dimension(:) :: ICETHICK_EX => null() ! pointer to ice thickness export state + + ! physical parameters + real(dp), parameter :: rho_ice = 917.0 ! pure ice density [kg m-3] + real(dp) :: dt ! time step [s] (ISSM_DT set in AGCM.rc) + + character(len=ESMF_MAXSTR) :: ISSM_EXPDIR ! directory containing ISSM input file + +! Get the target components name, mesh and vm +! ----------------------------------------------------------- + Iam = "Run" + call ESMF_GridCompGet( GC, name=COMP_NAME,mesh=mesh,vm=vm,RC=STATUS ) + VERIFY_(STATUS) + Iam = trim(COMP_NAME) // Iam + + ! Get my internal MAPL_Generic state +!---------------------------------- + call MAPL_GetObjectFromGC(GC, MAPL, STATUS) + VERIFY_(STATUS) + + ! Start Total timer +!------------------ + call MAPL_TimerOn(MAPL,"TOTAL") + call MAPL_TimerOn(MAPL,"RUN" ) + + call MAPL_Get(MAPL, RUNALARM = ALARM, RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_GetResource(MAPL, ISSM_EXPDIR, Label=trim(COMP_NAME)//"_EXPDIR:", RC=STATUS) + VERIFY_(STATUS) + + ! run ISSM at specified time steps + if ( ESMF_AlarmIsRinging (ALARM, RC=STATUS) ) then + + ! *************************************************************************** ! + ! BASIC SETUP + ! *************************************************************************** ! + + ! get timestep for ISSM + call MAPL_GetResource (MAPL, dt, Label=trim(COMP_NAME)//"_DT:",DEFAULT=302400.0, RC=STATUS) + VERIFY_(STATUS) + + ! get number of mesh elements + call ESMF_MeshGet(mesh,elementCount=num_elements) + + ! allocate ice-elevation output (export from ISSM) + allocate(ISSM_OUTPUTS(num_outputs*num_elements)) + allocate(ICESURF(num_elements)) + allocate(ICETHICK(num_elements)) + allocate(ICEVEL(num_elements)) + + call ESMF_VMBarrier(vm, rc=status) + VERIFY_(STATUS) + + ! initialize ISSM outputs to zero + ICESURF(:) = 0.0_dp + ICETHICK(:) = 0.0_dp + ICEVEL(:) = 0.0_dp + ISSM_OUTPUTS(:) = 0.0_dp + + ! get routehandles for regridding + call ESMF_UserCompGetInternalState(GC, 'ISSM_WRAP', wrap, status); VERIFY_(STATUS) + internal_state => wrap%ptr + routehandle_m2g = internal_state%routehandle_m2g ! mesh to grid + routehandle_g2m = internal_state%routehandle_g2m ! grid to mesh + call MAPL_LocStreamGet(internal_state%locstream, NT_LOCAL=NT, _RC) + call MAPL_GridGet(internal_state%grid, localCellCountPerDim=local_dims, _RC) + IM = local_dims(1) + JM = local_dims(2) + + ! *************************************************************************** ! + ! IMPORT SMB (surface mass balance) & REGRID FROM TILES [to grid] to MESH + ! *************************************************************************** ! + + call MAPL_GetPointer(IMPORT,ICESMB_IM, 'ICESMB' , RC=STATUS); VERIFY_(STATUS) + + ! allocate tiles for SMB (MKTILE) + if(associated(ICESMB_IM) .and. .not.associated(ICESMB_TILE)) then + allocate(ICESMB_TILE(NT), STAT=STATUS) + VERIFY_(STATUS) + ICESMB_TILE = MAPL_Undef + end if + + ! copy import values into tile array + ICESMB_TILE(:) = ICESMB_IM(:) + + ! allocate SMB on grid + allocate( ICESMB_GRID(IM,JM), STAT=STATUS ); VERIFY_(STATUS) + + ! transform ICESMB from tile to grid + ! NOTE: we use the "transpose" option with MAPL_LocStreamTransformG2T + ! (rather than MAPL_LocStreamTransformT2G) because the "default" value is zero + ! (rather than MAPL_UNDEF, which leads to errors when regridding onto mesh) + call MAPL_LocStreamTransform( internal_state%LOCSTREAM, ICESMB_TILE, ICESMB_GRID, TRANSPOSE=.true., RC=STATUS) + VERIFY_(STATUS) + + ! create source field: SMB on grid + srcField = ESMF_FieldCreate(grid=internal_state%grid,farrayPtr=ICESMB_GRID, datacopyflag=ESMF_DATACOPY_VALUE,rc=STATUS) + VERIFY_(STATUS) + + ! create destination field: SMB on mesh elements + dstField = ESMF_FieldCreate(mesh=mesh,typekind=ESMF_TYPEKIND_R8,meshloc=ESMF_MESHLOC_ELEMENT, rc=STATUS) + VERIFY_(STATUS) + + ! regrid SMB from grid to mesh + call ESMF_FieldRegrid(srcField, dstField, routehandle_g2m, RC=STATUS); VERIFY_(STATUS) + + ! get pointer to SMB on mesh + call ESMF_FieldGet(dstField,farrayPtr=ICESMB_MESH,RC=STATUS); VERIFY_(STATUS) + + ! save ICESMB on mesh elements + call MAPL_GetPointer(EXPORT , ICESMB_EX , 'ICESMB' , RC=STATUS); VERIFY_(STATUS) + if(associated(ICESMB_EX)) ICESMB_EX = ICESMB_MESH + + ! *************************************************************************** ! + ! RUN ISSM WITH SMB INPUT AND ICE-ELEVATION OUTPUT + ! *************************************************************************** ! + + ! convert SMB to units of [m/s] (ice-equivalent) before passing to ISSM + ICESMB_MESH = ICESMB_MESH/rho_ice + + ! NOTE: do we need the barriers before/after ISSM run? + call ESMF_VMBarrier(vm, rc=status); VERIFY_(STATUS) + + ! call run method from ISSM library + call RunISSM(dt, c_loc(ICESMB_MESH), c_loc(ISSM_OUTPUTS)) + + call ESMF_VMBarrier(vm, rc=status); VERIFY_(STATUS) + + ! *************************************************************************** ! + ! UNPACK AND EXPORT ISSM OUTPUTS + ! *************************************************************************** ! + + ! unpack ISSM output pointer + ICESURF(:) = ISSM_OUTPUTS(1:num_elements) + ICETHICK(:) = ISSM_OUTPUTS(num_elements+1:2*num_elements) + ICEVEL(:) = ISSM_OUTPUTS(2*num_elements+1:3*num_elements) + + ! get pointers to exports + call MAPL_GetPointer(EXPORT , ICESURF_EX , 'ICESURF' , RC=STATUS); VERIFY_(STATUS) + if(associated(ICESURF_EX)) ICESURF_EX = ICESURF + + call MAPL_GetPointer(EXPORT , ICEVEL_EX , 'ICEVEL' , RC=STATUS); VERIFY_(STATUS) + if(associated(ICEVEL_EX)) ICEVEL_EX = ICEVEL + + call MAPL_GetPointer(EXPORT , ICETHICK_EX , 'ICETHICK' , RC=STATUS); VERIFY_(STATUS) + if(associated(ICETHICK_EX)) ICETHICK_EX = ICETHICK + + ! destroy regridding fields + call ESMF_FieldDestroy(srcField,rc=STATUS); VERIFY_(STATUS) + call ESMF_FieldDestroy(dstField,rc=STATUS); VERIFY_(STATUS) + + end if + + call ESMF_VMBarrier(vm, rc=status) + VERIFY_(STATUS) + + if(associated(ICESURF)) deallocate(ICESURF) + if(associated(ISSM_OUTPUTS)) deallocate(ISSM_OUTPUTS) + if(associated(ICETHICK)) deallocate(ICETHICK) + if(associated(ICEVEL)) deallocate(ICEVEL) + if(associated(ICESMB_TILE)) deallocate(ICESMB_TILE) + if(associated(ICESMB_GRID)) deallocate(ICESMB_GRID) + + call MAPL_TimerOff(MAPL,"RUN" ) + call MAPL_TimerOff(MAPL,"TOTAL") + + RETURN_(ESMF_SUCCESS) + + end subroutine RUN + + !BOP + +!IROUTINE: Finalize -- Finalize method for ISSM + +!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_MetaComp), pointer :: MAPL + + ! ErrLog Variables + character(len=ESMF_MAXSTR) :: IAm + integer :: STATUS + character(len=ESMF_MAXSTR) :: COMP_NAME + + ! 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 + + ! call ISSM finalize (saves binary output .outbin file) + call FinalizeISSM() + +! Generic Finalize +! ------------------ + + call MAPL_GenericFinalize( GC, IMPORT, EXPORT, CLOCK, RC=status ) + VERIFY_(STATUS) + +! All Done +!--------- + + RETURN_(ESMF_SUCCESS) + end subroutine Finalize + +end module GEOS_IssmGridCompMod diff --git a/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/Shared/GEOS_SurfaceGridComp.rc b/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/Shared/GEOS_SurfaceGridComp.rc index 1ba28b70b..157b27f0d 100644 --- a/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/Shared/GEOS_SurfaceGridComp.rc +++ b/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/Shared/GEOS_SurfaceGridComp.rc @@ -249,3 +249,14 @@ # GEOSldas=>PRESCRIBE_DVG: 0 +#--------------------------------------------------------# +# Ice-Sheet and Sea-Level System Model (ISSM) # +# # +# * DO_ISSM is the run flag , turned off by default # +# * ISSM_DT is ISSM's time step, semiweekly by default # +#--------------------------------------------------------# +# GEOSagcm=>DO_ISSM: 0 +# GEOSagcm=>ISSM_DT: 302400 +# +# GEOSldas=>DO_ISSM: 0 +# GEOSldas=>ISSM_DT: 302400 \ No newline at end of file