Sequential CCSM – CCSM/ESMF Stage-1 Meeting

April 11th, 2006, 3:00-4:30pm

Chapman conference room

More on high level picture (Didn't finish)
Agenda:

  1. Briefly review Last meeting, Mar 3rd
  2. Initialization and allowance for components to ask driver for a change in coupling interval.
  3. Some changes to shr_inputinfo_mod and shr_timemgr_mod (part way)
  4. Options for time-averaging... (next time)
  5. (Note time-averaging needs to be done in components as well as driver [averaging ice/atm data up to daily for ocean])
  6. Next meeting? 4 weeks – May 10th
  7. Cam commits: Mariana's, shr_file_mod use, shr_timemgr and shr_inputinfo usage
  8. Who can help code-review of shr code? Brian and Tony
    Action items:
  • Get some examples of most current prototype code.
  • Tell ESMF we need to add time-objects to states.
  1. Initialization – allowance for components to ask driver for a change in coupling interval...
    No preference was shown by folks with either of these options
  • Driver sets coupling intervals with timemgr namelist as before
  • Components have the option to pass back a coupling_interval in their export state at initialization
  • Driver checks to make sure this coupling-interval is compatible with it's own time-step – if it is – it uses it and changes the given alarm.
  • If new coupling-interval is incompatible with the driver – the driver shuts down.
    The relevent part of the code is the following call after initialization...
         call eshr_EState_Get( Estate=a2x_a, Cpl_dt=atm_cpl_dt )
         call shr_timemgr_ChangeAlarm( CompType="atm", Cpl_dt=atm_cpl_dt,  SyncClock )
    
  • The name of the alarm to change is given in the input arguments.
  • The export state has an integer attribute added to it that is the coupling interval for the component (if the component doesn't change the coupling interval this will just be the alarm-interval of the components alarm).

Alturnatives:

  • You could use the above method to specify coupling intervals from the component – and not driver.
    So the drivers clock wouldn't be set until after the 1st phase initialization of components. The problem with this is that you couldn't give the component the start,stop, and reference times until the 2nd phase of initialization.
     ! Phase 1 initialization of all components...
     call ESMF_GridCompInitialize( gc_atm, import=x2a_a, export=a2x_a, phase=1, rc=rc )
     ...
     ! Get coupling intervals of all components
     call eshr_EState_Get( Estate=a2x_a, Cpl_dt=atm_cpl_dt )
     ...
     ! Setup clock
     if ( .not. shr_inputinfo_isRestart(        initinfo ) )then
       ! Set coupling intervals for all components
       call shr_timemgr_Change( ClockSetup, atm_cpl_dt=atm_cpl_dt )
       ...
       call shr_timemgr_SetupClock(     ClockSetup, log_print=masterproc, clock_out=SyncClock )
     end if
     call shr_timemgr_Get(  SyncClock, e_clock=ESyncClock, info=TimeMgrInfo )
     ! Phase 2 initialization of all components..
     ! Add time-manager clock data to import states of each component
     call eshr_timemgr_Info2EState( TimeMgrInfo, x2a_a )
     ...
     call ESMF_GridCompInitialize( gc_atm, import=x2a_a, export=a2x_a, phase=2, clock=ESyncClock, rc=rc )
     ...
    
  • Another alturnative – You could seperate the setting of the component alarms from the setting time-itself.
    The main clock could be set before init phase-1 of the components. Then after the components run their init phase-1 – you use the coupling interval given in their export states to set the component alarms. The problem with this is that you can't set the time-step – either, because you need to know the coupling intervals to set the driver time-step. Or you have to assume that the driver time-step is some reasonable value, or set the time-step on the namelist (and have the scripts set it in a consistent manner).
     ! Clock setup normally as outlined in longer initialization example below...
     if ( .not. shr_inputinfo_isRestart(        initinfo ) )then
        call shr_timemgr_SetupClock(     ClockSetup, log_print=masterproc, clock_out=SyncClock )
     end if
     ! Add time-manager clock data to import states of each component
     call eshr_timemgr_Info2EState( TimeMgrInfo, x2a_a )
     ...
     call shr_timemgr_Get(  SyncClock, e_clock=ESyncClock, info=TimeMgrInfo )
     ! Phase 1 initialization of all components...
     call ESMF_GridCompInitialize( gc_atm, import=x2a_a, export=a2x_a, phase=1, clock=ESyncClock, rc=rc )
      ! Get coupling intervals of all components
     call eshr_EState_Get( Estate=a2x_a, Cpl_dt=atm_cpl_dt )
     ...
     ! Setup clock component alarms...
     if ( .not. shr_inputinfo_isRestart(        initinfo ) )then
       ! Set coupling intervals for all components
       call shr_timemgr_SetClockAlarms( SyncClock, atm_cpl_dt=atm_cpl_dt )
       ...
     end if
     ! Phase 2 initialization of all components..
     call ESMF_GridCompInitialize( gc_atm, import=x2a_a, export=a2x_a, phase=2, rc=rc )
     ...
    
    Initialization:
    subroutine seq_ccsmInit( ESyncClock, initinfo, TimeMgrInfo )
      type(ESMF_Clock), intent(in) :: ESyncClock
      type(initinfo_t), intent(in)    :: initinfo
      type(TimeMgrInfo_t), intent(in) :: TimeMgrInfo
     !
     ! Clock rules: clocks sent to components are used read-only, information can be read 
     ! from them, but not added. Each component has it s own internal clock
     !
     call ESMF_VMGetGlobal( vm )
     call ESMF_VMGet(       vm, localpet=petid, mpicommunicator=mpicom ) 
     masterproc = (petid == 1)
     call seq_ccsm_esmfPrintLogHeader()
     ! Read namelist on masterproc and MPI broadcast to all MPI tasks (if MPI)
     call shr_inputinfo_SetDefaults(      initinfo )
     call shr_inputinfo_ReadNL(        nlfilename,   logprint=masterproc,  &
      mastertask=masterproc, &
                                      mpicom=mpicom, initinfo )
     call shr_inputinfo_Get( initinfo, perpetual_run=perpetual_run,  &
     perpetual_ymd=perpetual_ymd )
     call shr_timemgr_SetDefaults(           ClockSetup, perpetual_run, perpetual_ymd )
     call shr_timemgr_ReadNL( nlfilename, logprint=masterproc, & 
      mastertask=masterproc, &
                             mpicom=mpicom, Setup_Out=ClockSetup )
     if ( shr_inputinfo_isRestart(        initinfo ) )then
       call shr_inputinfo_ReadRPointer( mpicom, masterproc, initinfo, rest_file )
       call shr_inputinfo_ReadRestart(   rest_file, mpicom, masterproc, initinfo )
       call shr_timemgr_ReadRestart(     rest_file,     &
                                         mpicom=mpicom, mastertask=masterproc, setup=ClockSetup, clock_out=SyncClock )
    else
       call shr_timemgr_SetupClock(     ClockSetup, log_print=masterproc, clock_out=SyncClock )
    end if
    call shr_timemgr_ClockGet(  SyncClock, e_clock=ESyncClock, info=TimeMgrInfo )
     ! Create import/export states of all components
      cs_a = ESMF_StateCreate( type//"Atm composite state from each component on atm grid", rc )
      cs_l = ESMF_StateCreate( type//"Lnd composite state from each component on land grid", rc )
      cs_i = ESMF_StateCreate( type//"Ice composite state from each component on ice grid", rc )
      cs_o = ESMF_StateCreate( type//"Ocn composite state from each component on ocean grid", rc )
      a2x_a = ESMF_StateCreate( type//"Atm export on atmosphere grid/decomp export", rc )
      a2x_l = ESMF_StateCreate( type//"Atm export on land grid/decomp export", rc )
      a2x_i = ESMF_StateCreate( type//"Atm export on ice grid/decomp export", rc )
      a2x_o = ESMF_StateCreate( type//"Atm export on ocean grid/decomp export", rc )
      l2x_l = ESMF_StateCreate( type//"Lnd export on land grid/decomp export", rc )
      l2x_a = ESMF_StateCreate( type//"Lnd export on atmosphere grid/decomp export", rc )
      o2x_o = ESMF_StateCreate( type//"Ocn export on ocean grid/decomp export", rc )
      o2x_a = ESMF_StateCreate( type//"Ocn export on atmosphere grid/decomp export", rc )
      o2x_i = ESMF_StateCreate( type//"Ocn export on ice grid/decomp export", rc )
      i2x_i = ESMF_StateCreate( type//"Ice export on ice grid/decomp export", rc )
      i2x_a = ESMF_StateCreate( type//"Ice export on atmosphere grid/decomp export", rc )
      i2x_o = ESMF_StateCreate( type//"Ice export on ocean grid/decomp export", rc )
      x2a_a = ESMF_StateCreate( type//"All model output on atmosphere grid/decomp -- import to atm", rc )
      x2l_o = ESMF_StateCreate( type//"All model output on ocean grid/decomp -- import to land", rc )
      x2o_o = ESMF_StateCreate( type//"All model output on ocean grid/decomp -- import to ocean", rc )
      x2i_i = ESMF_StateCreate( type//"All model output on ice grid/decomp -- import to ocean", rc )
      !
      ! Create the composite states by adding nested states to composite states
      ! These are pointers to the nested states, and as such when the nested states  
      ! are updated the composite states are updated as well.
      !
      ! Atmosphere composite state
      call ESMF_StateAddState(cs_a, o2x_a, rc)
      call ESMF_StateAddState(cs_a, l2x_a, rc)
      call ESMF_StateAddState(cs_a, i2x_a, rc)
      ! Land composite state
      call ESMF_StateAddState(cs_l, a2x_l, rc)
      ! Ice composite state
      call ESMF_StateAddState(cs_i, o2x_i, rc)
      call ESMF_StateAddState(cs_i, a2x_i, rc)
      ! Ocean composite state
      call ESMF_StateAddState(cs_o, a2x_o, rc)
      call ESMF_StateAddState(cs_o, i2x_o, rc)
      ! Create components using global VM already gotten at high level
      gc_atm = ESMF_GridCompCreate(vm, name="Sequential CCSM atmosphere ESMF Gridded Component", &
                         gridcomptype=ESMF_ATM, contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc)
      call ESMF_GridCompSetServices(gc_atm, atm_comp_esmf_SetServices )
      gc_lnd = ESMF_GridCompCreate(vm, name="Sequential CCSM land ESMF Gridded Component", &
                         gridcomptype=ESMF_LAND, contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc)
      call ESMF_GridCompSetServices(gc_lnd, lnd_comp_esmf_SetServices )
      gc_ice = ESMF_GridCompCreate(vm, name="Sequential CCSM sea-ice ESMF Gridded Component", &
                         gridcomptype=ESMF_SEAICE, contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc)
      call ESMF_GridCompSetServices(gc_ice, ice_comp_esmf_SetServices )
      gc_ocn = ESMF_GridCompCreate(vm, name="Sequential CCSM ocean ESMF Gridded Component", &
                         gridcomptype=ESMF_OCEAN, contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc)
      call ESMF_GridCompSetServices(gc_ocn, ocn_comp_esmf_SetServices )
      gc_mrg_x2a = ESMF_GridCompCreate(vm, name="Sequential CCSM atmosphere merger ESMF Gridded Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc)
      call ESMF_GridCompSetServices(gc_mrg_x2a, seq_esmf_mrg_x2a_SetServices )
      gc_mrg_x2l = ESMF_GridCompCreate(vm, name="Sequential CCSM land merger ESMF Gridded Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc)
      call ESMF_GridCompSetServices(gc_mrg_x2l, seq_esmf_mrg_x2l_SetServices )
      gc_mrg_x2i = ESMF_GridCompCreate(vm, name="Sequential CCSM sea-ice merger ESMF Gridded Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc)
      call ESMF_GridCompSetServices(gc_mrg_x2i, seq_esmf_mrg_x2i_SetServices )
      gc_mrg_x2o = ESMF_GridCompCreate(vm, name="Sequential CCSM ocean merger ESMF Gridded Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc)
      call ESMF_GridCompSetServices(gc_mrg_x2o, seq_esmf_mrg_x2o_SetServices )
      cc_map_a2o = ESMF_CplCompCreate(vm, name="Sequential CCSM atmosphere to ocean ESMF Coupler Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc)
      call ESMF_GridCompSetServices(cc_map_a2o, seq_esmf_map_SetServices )
      cc_map_o2a = ESMF_CplCompCreate(vm, name="Sequential CCSM ocean to atmosphere ESMF Coupler Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc) 
      call ESMF_GridCompSetServices(cc_map_o2a, seq_esmf_map_SetServices )
      cc_map_a2l = ESMF_CplCompCreate(vm, name="Sequential CCSM atmosphere to land ESMF Coupler Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc) 
      call ESMF_GridCompSetServices(cc_map_a2l, seq_esmf_map_SetServices )
      cc_map_l2a = ESMF_CplCompCreate(vm, name="Sequential CCSM land to atmosphere ESMF Coupler Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc) 
      call ESMF_GridCompSetServices(cc_map_l2a, seq_esmf_map_SetServices )
      cc_map_a2i = ESMF_CplCompCreate(vm, name="Sequential CCSM atmosphere to sea-ice ESMF Coupler Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc) 
      call ESMF_GridCompSetServices(cc_map_a2i, seq_esmf_map_SetServices )
      cc_map_i2a = ESMF_CplCompCreate(vm, name="Sequential CCSM sea-ice to atmosphere ESMF Coupler Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc) 
      call ESMF_GridCompSetServices(cc_map_i2a, seq_esmf_map_SetServices )
      cc_map_o2i = ESMF_CplCompCreate(vm, name="Sequential CCSM ocean to sea-ice ESMF Coupler Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc) 
      call ESMF_GridCompSetServices(cc_map_o2i, seq_esmf_map_SetServices )
      cc_map_i2o = ESMF_CplCompCreate(vm, name="Sequential CCSM sea-ice to ocean ESMF Coupler Component", &
                         contextFlag=ESMF_CHILD_IN_PARENT_VM, rc=rc) 
      call ESMF_GridCompSetServices(cc_map_i2o, seq_esmf_map_SetServices )
      ! Call phase-1 initialization for each component (Setup states for each component)
      ! Components will also read in namelists (and possibly configuration file information)
      ! And they use the ESyncClock to set their internal clocks start and stop time
      ! They can also populate their export state with data if appropriate.
      ! At this stage every component is indepenent of each other. Hence
      ! order of the following calls is not important.
      ! Note that x2a_a, x2l_l, x2i_i, x2o_o will only have array control information filled in
      ! The fields and grids for these states will be defined in the following calls
      ! Add ccsm_init_data to import state as state on each import state
      call eshr_inputinfo_Info2EState( initinfo, x2a_a )
      call eshr_inputinfo_Info2EState( initinfo, x2l_l )
      call eshr_inputinfo_Info2EState( initinfo, x2i_i )
      call eshr_inputinfo_Info2EState( initinfo, x2o_o )
      ! Each component is given it s coupling interval by querying the alarms setup for each component
      ! Each component will create it s own internal clock, using ESyncClock to set start,
      ! stop, calendar  and ref time, as well as using the restart alarm
      call eshr_timemgr_Info2EState( TimeMgrInfo, x2a_a )
      call eshr_timemgr_Info2EState( TimeMgrInfo, x2l_l )
      call eshr_timemgr_Info2EState( TimeMgrInfo, x2i_i )
      call eshr_timemgr_Info2EState( TimeMgrInfo, x2o_o )
     {color:red}if ( shr_inputinfo_RunModel( initinfo,  atm  ) )then
         call ESMF_GridCompInitialize( gc_atm, import=x2a_a, export=a2x_a, phase=1, clock=ESyncClock, rc=rc )
         ! If export state has different coupling intervals on it -- change alarm interval
         call eshr_EState_Get( Estate=a2x_a, Cpl_dt=atm_cpl_dt )
         call eshr_timemgr_ChangeAlarm( CompType="atm", Cpl_Dt=atm_cpl_dt, SyncClock )
      end if
      if ( shr_inputinfo_RunModel( initinfo,  lnd  ) )then
         call ESMF_GridCompInitialize( gc_lnd, import=x2l_l, export=l2x_l, phase=1, clock=ESyncClock, rc=rc )
         ! If export state has different coupling interval on it -- change alarm interval
         call eshr_EState_Get( Estate=l2x_l, Cpl_dt=lnd_cpl_dt )
         call eshr_timemgr_ChangeAlarm( CompType="lnd", Cpl_Dt=lnd_cpl_dt, SyncClock )
      end if
      if ( shr_inputinfo_RunModel( initinfo,  ice  ) )then
         call ESMF_GridCompInitialize( gc_ice, import=x2i_i, export=i2x_i, phase=1, clock=ESyncClock, rc=rc )
         ! If export state has different coupling intervals on it -- change alarm interval
         call eshr_EState_Get( Estate=i2x_i, Cpl_dt=ice_cpl_dt )
         call eshr_timemgr_ChangeAlarm( CompType="ice", Cpl_Dt=ice_cpl_dt, SyncClock )
      end if
      if ( shr_inputinfo_RunModel( initinfo,  ocn  ) )then
         call ESMF_GridCompInitialize( gc_ocn, import=x2o_o, export=o2x_o, phase=1, clock=ESyncClock, rc=rc )
         ! If export state has different coupling interval on it -- change alarm interval
         call eshr_EState_Get( Estate=o2x_o, Cpl_dt=ocn_cpl_dt )
         call eshr_timemgr_ChangeAlarm( CompType="ocn", Cpl_Dt=ocn_cpl_dt, SyncClock )
      end if
    {color}
      ! Fill the following states (using grid and information from the input states)
      ! fill in a2x_l ! (this will be a2x on the atm grid on the lnd decomposition)
      ! get fields from a2x_a and grid from x2l_l and create a new state 
      call eshr_EState_Create(state=a2x_a, grid=x2l_l, out=a2x_l)
      ! fill in a2x_i ! (this will be a2x on the ocn grid on the ice decomposition)
      call eshr_EState_Create(state=a2x_a, grid=x2i_i, out=a2x_i)
      ! fill in a2x_o ! (this will be a2x on the ocn grid on the ocn decomposition)
      call eshr_EState_Create(state=a2x_a, grid=x2o_o, out=a2x_o)
      ! fill in l2x_a (this will be l2x on the atm grid and atm decomposition)
      call eshr_EState_Create( state=l2x_l, grid=x2a_a, out=l2x_a )
      ! fill in o2x_a (this will be o2x on the atm grid and atm decomposition)
      call eshr_EState_Create( state=o2x_o, grid=x2a_a, out=o2x_a )
      ! fill in o2x_i (this will be o2x on the ice grid and ice decomposition)
      call eshr_EState_Create( state=o2x_o, grid=x2i_i, out=o2x_i ) 
      ! fill in i2x_a (this will be i2x on the atm grid and atm decomposition)
      call eshr_EState_Create( state=i2x_i, grid=x2a_a, out=i2x_a )
      ! fill in i2x_o (this will be i2x on the ocn grid and ocn decomposition)
      call eshr_EState_Create( state=i2x_i, grid=x2o_o, out=i2x_o )
      !
      ! Initialize couplers - note that couplers don't need a sync clock
      !
      call ESMF_CplCompInitialize(  cc_map_a2l, import=a2x_a, export=a2x_l, rc=rc )
      call ESMF_CplCompInitialize(  cc_map_a2o, import=a2x_a, export=a2x_o, rc=rc )
      call ESMF_CplCompInitialize(  cc_map_a2i, import=a2x_a, export=a2x_i, rc=rc )
      call ESMF_CplCompInitialize(  cc_map_o2i, import=o2x_o, export=o2x_i, rc=rc )
      !
      ! 2nd phase of component initialization, fill export states with data, and use import data from couplers
      !
      if ( shr_inputinfo_RunModel( initinfo,  atm  )  )then
         call ESMF_GridCompInitialize( gc_atm, import=x2a_a, export=a2x_a, phase=2, rc=rc )
      else
         call eshr_EState_Zero( x2a_a )
         call eshr_EState_Zero( a2x_a )
      end if
      if ( shr_inputinfo_RunModel( initinfo,  lnd  ) )then
         call ESMF_GridCompInitialize( gc_lnd, import=x2l_l, export=l2x_l, phase=2, rc=rc )
      else
         call eshr_EState_Zero( x2l_l )
         call eshr_EState_Zero( l2x_l )
      end if
      if ( shr_inputinfo_RunModel( initinfo,  ice  ) )then
         call ESMF_GridCompInitialize( gc_ice, import=x2i_i, export=i2x_i, phase=2, rc=rc )
      else
         call eshr_EState_Zero( x2i_i )
         call eshr_EState_Zero( i2x_i )
      end if
      if ( shr_inputinfo_RunModel( initinfo,  ocn  ) )then
         call ESMF_GridCompInitialize( gc_ocn, import=x2o_o, export=o2x_o, phase=2, rc=rc )
      else
         call eshr_EState_Zero( x2o_o )
         call eshr_EState_Zero( o2x_o )
      end if
      !
      ! Couple back
      !
      call ESMF_CplCompInitialize(  cc_map_l2a, import=l2x_l, export=l2x_a, rc=rc )
      call ESMF_CplCompInitialize(  cc_map_o2a, import=o2x_o, export=o2x_a, rc=rc )
      call ESMF_CplCompInitialize(  cc_map_i2a, import=i2x_i, export=i2a_a, rc=rc )
      call ESMF_CplCompInitialize(  cc_map_i2o, import=i2x_i, export=i2x_o, rc=rc )
      !
      ! Run mergers to merge data
      !
      if ( shr_inputinfo_RunModel( initinfo,  atm  ) ) &
         call ESMF_GridCompInitialize( gc_mrg_x2a, import=cs_a, export=x2a_a, rc=rc )
      if ( shr_inputinfo_RunModel( initinfo,  lnd  ) ) &
         call ESMF_GridCompInitialize( gc_mrg_x2l, import=cs_l, export=x2l_l, rc=rc )
      if ( shr_inputinfo_RunModel( initinfo,  ice  ) ) &
         call ESMF_GridCompInitialize( gc_mrg_x2i, import=cs_i, export=x2i_i, rc=rc )
      if ( shr_inputinfo_RunModel( initinfo,  ocn  ) ) &
         call ESMF_GridCompInitialize( gc_mrg_x2o, import=cs_o, export=x2o_o, rc=rc )
    call ESMF_ClockGetAlarm( ESyncClock,  Restart alarm , restart ) ! Get restart alarm
     ! For Stage-2 you would also get alarms for each component (ocn,ice,lnd, and atm)
     ! The run method only calls components when their alarms are ringing
    call ESMF_ClockGetAlarm( ESyncClock,  Atmosphere component alarm , atm_alarm )
    call ESMF_ClockGetAlarm( ESyncClock,  Land component alarm , lnd_alarm )
    call ESMF_ClockGetAlarm( ESyncClock,  Oean component alarm , ocn_alarm )
    call ESMF_ClockGetAlarm( ESyncClock,  Sea-ice component alarm , ice_alarm )
    end subroutine seq_ccsm_esmfInit
    
  1. Changes to shr_timemgr_mod.F90 (See details of namelist behavior)
  • New inputinfo namelist item: restart_file_override "case_name" (if branch and not brnch_retain_casename) Colen delimited list of values to override on restart_file from namelist ("case_desc:case_name:mss_irt:mss_wpass")
  • New timemgr namelist item: restart_file_override blank Colen delimited list of options to overide from restart_file ("restart_option:restart_n") (Got to here)
    There were concerns about the override capability, we should examine the list again. One way is to not write out anything that you may want to override – simply require those on the namelist. The problem there is if you later want to change the status of something – you don't have it on the restart file. We thought the above mechanism is ok for Stage-1, we may need to revisit at Stage-II.
  • Do I update clocksetup when ReadRestart runs?
  • New inputinfo method: call shr_inputinfo_ArchiveRestart( MasterTask, CCSMInit, async=.false., remove=.true., &
    restart_file=restart_file )
  • Remove restart_none with restart_option="none"
  • Have restart alarm ring at last time-step so restarts are correctly written out (or ignored if restarts aren't on).
  • Add restart_option "end" to just do restart at end of simulation (this is always on, unless restart_option set to "none")
  • Replace: restart_* with restart_option, and restart_n
  • Same with: stop_* with stop_option and stop_n
  • Additional data on restart files
            int shr_timemgr_clock_info_orb_mode ;
                    shr_timemgr_clock_info_orb_mode:long_name = "Clock info orbital mode" ;
                    shr_timemgr_clock_info_orb_mode:units = "list" ;
                    shr_timemgr_clock_info_orb_mode:_FillValue = 2000000000 ;
                    shr_timemgr_clock_info_orb_mode:missing_value = 2000000000 ;
                    shr_timemgr_clock_info_orb_mode:type = "Integer list" ;
                    shr_timemgr_clock_info_orb_mode:Orb_mode_calculated_based_on_fixed_year = 1 ;
                    shr_timemgr_clock_info_orb_mode:Orb_mode_fixed_by_orbit_parameters = 2 ;
    
  1. Run loop alturnative – run driver at atm/lnd internal time-step
    In this case, we use the straightforward CAM component that just runs over a single time step and doesn't do time-averaging. At initialization, the time-step from atm and lnd would have to be sent up from the components, and used for the driver-time-step. Below I also assume that ice and ocean do not do any time-averaging. Adding time-averaging for ice and ocean should be done for completeness, but would add more complexity at the driver level.
    Assume:
  • Driver time-step – 20 min
  • Ice time-step – 1 hour
  • atm/land coupling interval – 1 hour
  • Ocean time-step and coupling interval – 1 day
    Pros for time-averaging in driver:
  • Components don't have to do it (but only active components need to).
    Cons for time-averaging in driver:
  • Driver has to know both coupling interval and component time-step
  • Information for any concurrent parts have to be passed at higher frequency.
  • More barriers.
  • Driver becomes more complex even when running components (such as data components) that don't need time-averaging.
  • Requires additional tavg components, rather than direct calls to eshr_EState time-averaging methods.
     !
     ! Time loop
     !
    do while( .not. ESMF_ClockIsStopTime( ESyncClock )  )
       if ( shr_inputinfo_RunModel( initinfo,  atm  ) .and. &
            ESMF_AlarmIsRinging( atm_alarm ) )then
            ! Run time-averager
     {color:red}call ESMF_CplCompRun( cc_tavg_atm, import=atm_export, &
                                  export=a2x_a, clock=ESyncClock, phase=3 )
    {color}
            ! Run coupler on atmosphere export state before running...
            call ESMF_CplCompRun ( cc_map_a2l, import=a2x_a, export=a2x_l, rc=rc )
            call ESMF_CplCompRun ( cc_map_a2i, import=a2x_a, export=a2x_i, rc=rc )
            call ESMF_CplCompRun ( cc_map_a2o, import=a2x_a, export=a2x_o, rc=rc )
     {color:red}! Zero out export state
            call ESMF_CplCompRun( cc_tavg_atm, import=atm_export, &
                                  export=a2x_a, clock=ESyncClock, phase=1 )
    {color}
       end if
       if ( shr_inputinfo_RunModel( initinfo,  atm  ) .and. &
     {color:red}ESMF_AlarmIsRinging( atm_int_alarm ) )then{color}
          call ESMF_GridCompRun( gc_atm,     import=x2a_a, export=atm_export, ESyncClock, phase=1 )
     {color:red}! Sum export state
          call ESMF_CplCompRun( cc_tavg_atm, import=atm_export, &
                                  export=a2x_a, clock=ESyncClock, phase=2 )
    {color}
       end if
       if ( shr_inputinfo_RunModel( initinfo,  lnd  ) .and. &
            ESMF_AlarmIsRinging( lnd_alarm ) )then
     {color:red}! Time-average land export data
           call ESMF_CplCompRun( cc_tavg_lnd, import=lnd_export, &
                                  export=l2x_l, clock=ESyncClock, phase=3 )
    {color}
           call ESMF_CplCompRun (  cc_map_l2a, import=l2x_l, export=l2x_a, rc=rc )
            call ESMF_AlarmRingerOff( lnd_alarm )
     {color:red}! Zero out land export data
           call ESMF_CplCompRun( cc_tavg_lnd, import=lnd_export, &
                                  export=l2x_l, clock=ESyncClock, phase=1 
    {color}
       end if
       if ( shr_inputinfo_RunModel( initinfo,  lnd  ) .and. &
     {color:red}ESMF_AlarmIsRinging( lnd_int_alarm ) )then
         ! Note: cs_l is the composite state pointing to: a2x_l
         call ESMF_GridCompRun ( gc_mrg_x2l, import=cs_l, export=x2l_l, rc=rc ) 
    {color}
         call ESMF_GridCompRun(	 gc_lnd,     import=x2l_l, export=l2x_l, ESyncClock, phase=1 )
         call ESMF_GridCompRun(	 gc_lnd,	                                      phase=2 )
     {color:red}! Sum up land export data
         call ESMF_CplCompRun( cc_tavg_lnd, import=lnd_export, &
                                  export=l2x_l, clock=ESyncClock, phase=2 
    {color}
       end if
       if ( shr_inputinfo_RunModel( initinfo,  ice  ) .and. &
            ESMF_AlarmIsRinging( ice_alarm ) )then
            call ESMF_CplCompRun (  cc_map_i2a, import=i2x_i, export=i2x_a, rc=rc )
            call ESMF_CplCompRun (  cc_map_i2o, import=i2o_i, export=i2o_o, rc=rc )
            ! Note: cs_i is the composite state pointing to: a2x_i, o2i_i
            call ESMF_GridCompRun ( gc_mrg_x2i, import=cs_i, export=x2i_i, rc=rc )
            call ESMF_GridCompRun(  gc_ice,     import=x2i_i, export=i2x_i, ESyncClock, phase=1 )
            call ESMF_GridCompRun(  gc_ice,	                                       phase=2 )
            call ESMF_AlarmRingerOff( ice_alarm )
       end if
       if ( shr_inputinfo_RunModel( initinfo,  ocn  ) .and. &
            ESMF_AlarmIsRinging( ocn_alarm )  )then
            call ESMF_CplCompRun(   cc_map_o2a, import=o2x_o, export=o2x_a, rc=rc)
            call ESMF_CplCompRun (  cc_map_o2i, import=o2x_o, export=o2x_i, rc=rc )
            ! Note: cs_o is the composite state pointing to: i2o_o and a2x_o
            call ESMF_GridCompRun ( gc_mrg_x2o, import=cs_o, export=x2o_o, rc=rc ) 
            call ESMF_GridCompRun(  gc_ocn,     import=x2o_o, export=o2x_o, ESyncClock, phase=1 )
            call ESMF_AlarmRingerOff( ocn_alarm )
       end if
       if ( shr_inputinfo_RunModel( initinfo,  atm  ) .and. &
            ESMF_AlarmIsRinging( atm_alarm ) )then
           ! Note: cs_a is the composite state pointing to: l2x_a, i2x_a, and o2x_a
           call ESMF_GridCompRun( gc_mrg_x2a, import=cs_a, export=x2a_a, rc=rc )
           call ESMF_GridCompRun(	gc_atm,     import=x2a_a,               phase=2 )
           call ESMF_AlarmRingerOff( atm_alarm )
       end if
       ! Advance the clock
       call ESMF_AdvanceClock( ESyncClock )
       ! Write restart information out
       if ( ESMF_AlarmIsRinging( restart ) )then
          call shr_inputinfo_WriteRPointer(  ymd, tod, mpicom, masterproc, initinfo, rest_file )
          call shr_inputinfo_WriteRestart(    rest_file, mpicom, masterproc, initinfo  )
          call shr_timemgr_WriteRestart(  rest_file, mpicom, masterproc, SyncClock )
     {color:red}call shr_inputinfo_ArchiveRestart( MasterTask, CCSMInit, &
                                             async, remove, rest_file )
    {color}
          call ESMF_AlarmRingerOff( restart )
       end if
    end do
    
  • No labels