LCOV - code coverage report
Current view: | top level - cpl/nuopc - atm_comp_nuopc.F90 (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 643 | 783 | 82.1 %
Date: | 2025-01-13 21:54:50 |  | Functions: | 12 | 14 | 85.7 %

              Line data    Source code
           1             : module atm_comp_nuopc
           2             :
           3             :   !----------------------------------------------------------------------------
           4             :   ! This is the NUOPC cap for CAM
           5             :   !----------------------------------------------------------------------------
           6             :
           7             :    use ESMF                , only : operator(<=), operator(>), operator(==), operator(+)
           8             :    use ESMF                , only : ESMF_MethodRemove
           9             :    use ESMF                , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_State, ESMF_StateGet
          10             :    use ESMF                , only : ESMF_Grid, ESMF_GridCreateNoPeriDimUfrm, ESMF_Field, ESMF_FieldGet
          11             :    use ESMF                , only : ESMF_DistGrid, ESMF_DistGridCreate
          12             :    use ESMF                , only : ESMF_Mesh, ESMF_MeshCreate, ESMF_MeshGet, ESMF_FILEFORMAT_ESMFMESH
          13             :    use ESMF                , only : ESMF_Clock, ESMF_ClockGet, ESMF_ClockSet, ESMF_ClockGetNextTime, ESMF_ClockAdvance
          14             :    use ESMF                , only : ESMF_Time, ESMF_TimeGet
          15             :    use ESMF                , only : ESMF_Alarm, ESMF_ClockGetAlarm, ESMF_AlarmRingerOff, ESMF_AlarmIsRinging
          16             :    use ESMF                , only : ESMF_ClockGetAlarmList, ESMF_ALARMLIST_ALL, ESMF_AlarmSet
          17             :    use ESMF                , only : ESMF_TimeInterval, ESMF_TimeIntervalGet
          18             :    use ESMF                , only : ESMF_CalKind_Flag, ESMF_MAXSTR, ESMF_KIND_I8
          19             :    use ESMF                , only : ESMF_CALKIND_NOLEAP, ESMF_CALKIND_GREGORIAN
          20             :    use ESMF                , only : ESMF_GridCompSetEntryPoint
          21             :    use ESMF                , only : ESMF_VM, ESMF_VMGetCurrent, ESMF_VMGet
          22             :    use ESMF                , only : ESMF_LOGMSG_INFO, ESMF_LOGERR_PASSTHRU
          23             :    use ESMF                , only : ESMF_LogWrite, ESMF_LogSetError, ESMF_LogFoundError
          24             :    use ESMF                , only : ESMF_SUCCESS, ESMF_METHOD_INITIALIZE, ESMF_FAILURE, ESMF_RC_NOT_VALID
          25             :    use ESMF                , only : ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER
          26             :    use NUOPC               , only : NUOPC_CompDerive, NUOPC_CompSetEntryPoint, NUOPC_CompSpecialize
          27             :    use NUOPC               , only : NUOPC_CompFilterPhaseMap, NUOPC_IsUpdated, NUOPC_IsAtTime
          28             :    use NUOPC               , only : NUOPC_CompAttributeGet, NUOPC_Advertise
          29             :    use NUOPC               , only : NUOPC_SetAttribute, NUOPC_CompAttributeGet, NUOPC_CompAttributeSet
          30             :    use NUOPC_Model         , only : model_routine_SS           => SetServices
          31             :    use NUOPC_Model         , only : SetVM
          32             :    use NUOPC_Model         , only : model_label_Advance        => label_Advance
          33             :    use NUOPC_Model         , only : model_label_DataInitialize => label_DataInitialize
          34             :    use NUOPC_Model         , only : model_label_SetRunClock    => label_SetRunClock
          35             :    use NUOPC_Model         , only : model_label_Finalize       => label_Finalize
          36             :    use NUOPC_Model         , only : NUOPC_ModelGet
          37             :    use shr_kind_mod        , only : r8=>shr_kind_r8, i8=>shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs
          38             :    use shr_sys_mod         , only : shr_sys_abort
          39             :    use shr_log_mod         , only : shr_log_getlogunit, shr_log_setlogunit
          40             :    use shr_cal_mod         , only : shr_cal_noleap, shr_cal_gregorian, shr_cal_ymd2date
          41             :    use shr_const_mod       , only : shr_const_pi
          42             :    use shr_orb_mod         , only : shr_orb_decl, shr_orb_params, SHR_ORB_UNDEF_REAL, SHR_ORB_UNDEF_INT
          43             :    use cam_instance        , only : cam_instance_init, inst_suffix, inst_index
          44             :    use cam_comp            , only : cam_init, cam_run1, cam_run2, cam_run3, cam_run4, cam_final
          45             :    use camsrfexch          , only : cam_out_t, cam_in_t
          46             :    use radiation           , only : nextsw_cday
          47             :    use cam_logfile         , only : iulog
          48             :    use spmd_utils          , only : spmdinit, masterproc, iam, mpicom
          49             :    use time_manager        , only : get_curr_calday, advance_timestep, get_curr_date, get_nstep, get_step_size
          50             :    use atm_import_export   , only : read_surface_fields_namelists, advertise_fields, realize_fields
          51             :    use atm_import_export   , only : import_fields, export_fields
          52             :    use nuopc_shr_methods   , only : chkerr, state_setscalar, state_getscalar, state_diagnose, alarmInit
          53             :    use nuopc_shr_methods   , only : set_component_logging, get_component_instance, log_clock_advance
          54             :    use perf_mod            , only : t_startf, t_stopf
          55             :    use ppgrid              , only : pcols, begchunk, endchunk
          56             :    use dyn_grid            , only : get_horiz_grid_dim_d
          57             :    use phys_grid           , only : get_ncols_p, get_gcol_p, get_rlon_all_p, get_rlat_all_p
          58             :    use phys_grid           , only : ngcols=>num_global_phys_cols
          59             :    use cam_control_mod     , only : cam_ctrl_set_orbit
          60             :    use cam_pio_utils       , only : cam_pio_createfile, cam_pio_openfile, cam_pio_closefile, pio_subsystem
          61             :    use cam_initfiles       , only : cam_initfiles_get_caseid, cam_initfiles_get_restdir
          62             :    use cam_history_support , only : fillvalue
          63             :    use filenames           , only : interpret_filename_spec
          64             :    use pio                 , only : file_desc_t, io_desc_t, var_desc_t, pio_double, pio_def_dim, PIO_MAX_NAME
          65             :    use pio                 , only : pio_closefile, pio_put_att, pio_enddef, pio_nowrite
          66             :    use pio                 , only : pio_inq_dimid, pio_inq_varid, pio_inquire_dimension, pio_def_var
          67             :    use pio                 , only : pio_initdecomp, pio_freedecomp
          68             :    use pio                 , only : pio_read_darray, pio_write_darray
          69             :    use pio                 , only : pio_noerr, pio_bcast_error, pio_internal_error, pio_seterrorhandling
          70             :    use pio                 , only : pio_def_var, pio_get_var, pio_put_var, PIO_INT
          71             :    use ioFileMod
          72             :    !$use omp_lib           , only : omp_set_num_threads
          73             :
          74             :   implicit none
          75             :   private ! except
          76             :
          77             :   public :: SetServices
          78             :   public :: SetVM
          79             :
          80             :   !--------------------------------------------------------------------------
          81             :   ! Private interfaces
          82             :   !--------------------------------------------------------------------------
          83             :
          84             :   private :: InitializeP0
          85             :   private :: InitializeAdvertise
          86             :   private :: InitializeRealize
          87             :   private :: ModelAdvance
          88             :   private :: ModelSetRunClock
          89             :   private :: ModelFinalize
          90             :   private :: cam_read_srfrest
          91             :   private :: cam_write_srfrest
          92             :   private :: cam_orbital_init
          93             :   private :: cam_orbital_update
          94             :   private :: cam_set_mesh_for_single_column
          95             :   private :: cam_pio_checkerr
          96             :
          97             :   !--------------------------------------------------------------------------
          98             :   ! Private module data
          99             :   !--------------------------------------------------------------------------
         100             :
         101             :   character(len=CL)            :: flds_scalar_name = ''
         102             :   integer                      :: flds_scalar_num = 0
         103             :   integer                      :: flds_scalar_index_nx = 0
         104             :   integer                      :: flds_scalar_index_ny = 0
         105             :   integer                      :: flds_scalar_index_nextsw_cday = 0
         106             :   integer                      :: nthrds
         107             :   integer         , parameter  :: dbug_flag = 0
         108             :   type(cam_in_t)  , pointer    :: cam_in(:)
         109             :   type(cam_out_t) , pointer    :: cam_out(:)
         110             :   integer         , pointer    :: dof(:)              ! global index space decomposition
         111             :   character(len=256)           :: rsfilename_spec_cam ! Filename specifier for restart surface file
         112             :   character(*)    ,parameter   :: modName =  "(atm_comp_nuopc)"
         113             :   character(*)    ,parameter   :: u_FILE_u = &
         114             :        __FILE__
         115             :
         116             :   logical                      :: dart_mode = .false.
         117             :   logical                      :: mediator_present
         118             :
         119             :   character(len=CL)            :: orb_mode            ! attribute - orbital mode
         120             :   integer                      :: orb_iyear           ! attribute - orbital year
         121             :   integer                      :: orb_iyear_align     ! attribute - associated with model year
         122             :   real(R8)                     :: orb_obliq           ! attribute - obliquity in degrees
         123             :   real(R8)                     :: orb_mvelp           ! attribute - moving vernal equinox longitude
         124             :   real(R8)                     :: orb_eccen           ! attribute and update-  orbital eccentricity
         125             :
         126             :   character(len=*) , parameter :: orb_fixed_year       = 'fixed_year'
         127             :   character(len=*) , parameter :: orb_variable_year    = 'variable_year'
         128             :   character(len=*) , parameter :: orb_fixed_parameters = 'fixed_parameters'
         129             :
         130             :   real(R8) , parameter         :: grid_tol = 1.e-2_r8 ! tolerance for calculated lat/lon vs read in
         131             :
         132             :   type(ESMF_Mesh)  :: model_mesh     ! model_mesh
         133             :   type(ESMF_Clock) :: model_clock    ! model_clock
         134             :
         135             : !===============================================================================
         136             : contains
         137             : !===============================================================================
         138             :
         139        1536 :   subroutine SetServices(gcomp, rc)
         140             :     type(ESMF_GridComp)  :: gcomp
         141             :     integer, intent(out) :: rc
         142             :
         143             :     ! local variables
         144             :     character(len=*),parameter  :: subname=trim(modName)//':(SetServices) '
         145             :
         146        1536 :     rc = ESMF_SUCCESS
         147             :
         148             :     ! the NUOPC gcomp component will register the generic methods
         149             :
         150        1536 :     call NUOPC_CompDerive(gcomp, model_routine_SS, rc=rc)
         151        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         152             :
         153             :     ! switching to IPD version v03
         154             :
         155             :     call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, &
         156        1536 :          userRoutine=InitializeP0, phase=0, rc=rc)
         157        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         158             :
         159             :     ! set entry point for methods that require specific implementation
         160             :
         161             :     call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, &
         162        3072 :          phaseLabelList=(/"IPDv03p1"/), userRoutine=InitializeAdvertise, rc=rc)
         163        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         164             :
         165             :     call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, &
         166        3072 :          phaseLabelList=(/"IPDv03p3"/), userRoutine=InitializeRealize, rc=rc)
         167        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         168             :
         169             :     ! attach specializing method(s)
         170             :
         171             :     call NUOPC_CompSpecialize(gcomp, specLabel=model_label_Advance, &
         172        1536 :          specRoutine=ModelAdvance, rc=rc)
         173        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         174             :
         175             :     call NUOPC_CompSpecialize(gcomp, specLabel=model_label_DataInitialize, &
         176        1536 :          specRoutine=DataInitialize, rc=rc)
         177        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         178             :
         179        1536 :     call ESMF_MethodRemove(gcomp, label=model_label_SetRunClock, rc=rc)
         180        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         181             :     call NUOPC_CompSpecialize(gcomp, specLabel=model_label_SetRunClock, &
         182        1536 :          specRoutine=ModelSetRunClock, rc=rc)
         183        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         184             :
         185             :     call NUOPC_CompSpecialize(gcomp, specLabel=model_label_Finalize, &
         186        1536 :          specRoutine=ModelFinalize, rc=rc)
         187        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         188             :
         189             :   end subroutine SetServices
         190             :
         191             :   !===============================================================================
         192        1536 :   subroutine InitializeP0(gcomp, importState, exportState, clock, rc)
         193             :     type(ESMF_GridComp)   :: gcomp
         194             :     type(ESMF_State)      :: importState, exportState
         195             :     type(ESMF_Clock)      :: clock
         196             :     integer, intent(out)  :: rc
         197             :     !-------------------------------------------------------------------------------
         198             :
         199        1536 :     rc = ESMF_SUCCESS
         200             :
         201             :     ! Switch to IPDv03 by filtering all other phaseMap entries
         202        3072 :     call NUOPC_CompFilterPhaseMap(gcomp, ESMF_METHOD_INITIALIZE, acceptStringList=(/"IPDv03p"/), rc=rc)
         203        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         204             :
         205             :   end subroutine InitializeP0
         206             :
         207             :   !===============================================================================
         208       12288 :   subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
         209             :
         210             :     ! intput/output variables
         211             :     type(ESMF_GridComp)  :: gcomp
         212             :     type(ESMF_State)     :: importState, exportState
         213             :     type(ESMF_Clock)     :: clock
         214             :     integer, intent(out) :: rc
         215             :
         216             :     ! local variables
         217             :     type(ESMF_VM)     :: vm
         218             :     integer           :: n
         219             :     integer           :: localpet
         220             :     character(len=CL) :: cvalue
         221             :     character(len=CL) :: logmsg
         222             :     logical           :: isPresent, isSet
         223             :     integer           :: shrlogunit          ! original log unit
         224             :     character(len=*), parameter :: subname=trim(modName)//':(InitializeAdvertise) '
         225             :     !-------------------------------------------------------------------------------
         226             :
         227        1536 :     rc = ESMF_SUCCESS
         228             :     if (dbug_flag > 5) then
         229             :        call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO)
         230             :     end if
         231             :
         232        1536 :     call ESMF_VMGetCurrent(vm, rc=rc)
         233        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         234        1536 :     call ESMF_VmGet(vm, localPet=localPet, rc=rc)
         235        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         236             :
         237             :     !----------------------------------------------------------------------------
         238             :     ! reset shr logging to my log file
         239             :     !----------------------------------------------------------------------------
         240             :
         241        1536 :     call set_component_logging(gcomp, localpet==0, iulog, shrlogunit, rc)
         242        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         243             :
         244        1536 :     call shr_log_setLogUnit (iulog)
         245             :
         246             :     !----------------------------------------------------------------------------
         247             :     ! advertise import/export fields
         248             :     !----------------------------------------------------------------------------
         249             :
         250        1536 :     call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldName", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc)
         251        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         252        1536 :     if (isPresent .and. isSet) then
         253        1536 :        flds_scalar_name = trim(cvalue)
         254        1536 :        call ESMF_LogWrite(trim(subname)//' flds_scalar_name = '//trim(flds_scalar_name), ESMF_LOGMSG_INFO)
         255        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         256             :     else
         257           0 :        call shr_sys_abort(subname//'Need to set attribute ScalarFieldName')
         258             :     endif
         259             :
         260        1536 :     call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldCount", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc)
         261        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         262        1536 :     if (isPresent .and. isSet) then
         263        1536 :        read(cvalue, *) flds_scalar_num
         264        1536 :        write(logmsg,*) flds_scalar_num
         265        1536 :        call ESMF_LogWrite(trim(subname)//' flds_scalar_num = '//trim(logmsg), ESMF_LOGMSG_INFO)
         266        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         267             :     else
         268           0 :        call shr_sys_abort(subname//'Need to set attribute ScalarFieldCount')
         269             :     endif
         270             :
         271        1536 :     call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldIdxGridNX", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc)
         272        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         273        1536 :     if (isPresent .and. isSet) then
         274        1536 :        read(cvalue,*) flds_scalar_index_nx
         275        1536 :        write(logmsg,*) flds_scalar_index_nx
         276        1536 :        call ESMF_LogWrite(trim(subname)//' : flds_scalar_index_nx = '//trim(logmsg), ESMF_LOGMSG_INFO)
         277        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         278             :     else
         279           0 :        call shr_sys_abort(subname//'Need to set attribute ScalarFieldIdxGridNX')
         280             :     endif
         281             :
         282        1536 :     call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldIdxGridNY", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc)
         283        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         284        1536 :     if (isPresent .and. isSet) then
         285        1536 :        read(cvalue,*) flds_scalar_index_ny
         286        1536 :        write(logmsg,*) flds_scalar_index_ny
         287        1536 :        call ESMF_LogWrite(trim(subname)//' : flds_scalar_index_ny = '//trim(logmsg), ESMF_LOGMSG_INFO)
         288        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         289             :     else
         290           0 :        call shr_sys_abort(subname//'Need to set attribute ScalarFieldIdxGridNY')
         291             :     endif
         292             :
         293        1536 :     call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldIdxNextSwCday", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc)
         294        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         295        1536 :     if (isPresent .and. isSet) then
         296        1536 :        read(cvalue,*) flds_scalar_index_nextsw_cday
         297        1536 :        write(logmsg,*) flds_scalar_index_nextsw_cday
         298        1536 :        call ESMF_LogWrite(trim(subname)//' : flds_scalar_index_nextsw_cday = '//trim(logmsg), ESMF_LOGMSG_INFO)
         299        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         300             :     else
         301           0 :        call shr_sys_abort(subname//'Need to set attribute ScalarFieldIdxNextSwCday')
         302             :     endif
         303             :
         304             :     ! read mediator fields namelists
         305        1536 :     call read_surface_fields_namelists()
         306             :
         307        1536 :     call NUOPC_CompAttributeGet(gcomp, name="mediator_present", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc)
         308        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         309        1536 :     if (isPresent .and. isSet) then
         310        1536 :        read (cvalue,*) mediator_present
         311        1536 :        if (mediator_present) then
         312        1536 :           call advertise_fields(gcomp, flds_scalar_name, rc)
         313        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         314             :        end if
         315             :     else
         316           0 :        call shr_sys_abort(subname//'Need to set attribute mediator_present')
         317             :     endif
         318             :
         319             :     if (dbug_flag > 5) then
         320             :        call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO)
         321             :     end if
         322        1536 :   end subroutine InitializeAdvertise
         323             :
         324             :   !===============================================================================
         325        1536 :   subroutine InitializeRealize(gcomp, importState, exportState, clock, rc)
         326             :
         327             :     use ESMF, only : ESMF_VMGet
         328             :
         329             :     ! input/output variables
         330             :     type(ESMF_GridComp)  :: gcomp
         331             :     type(ESMF_State)     :: importState
         332             :     type(ESMF_State)     :: exportState
         333             :     type(ESMF_Clock)     :: clock
         334             :     integer, intent(out) :: rc
         335             :
         336             :     ! local variables
         337             :     type(ESMF_VM)           :: vm
         338             :     type(ESMF_Time)         :: currTime                          ! Current time
         339             :     type(ESMF_Time)         :: startTime                         ! Start time
         340             :     type(ESMF_Time)         :: stopTime                          ! Stop time
         341             :     type(ESMF_Time)         :: refTime                           ! Ref time
         342             :     type(ESMF_TimeInterval) :: timeStep
         343             :     type(ESMF_CalKind_Flag) :: esmf_caltype                      ! esmf calendar type
         344             :     type(ESMF_DistGrid)     :: distGrid
         345             :     integer                 :: spatialDim
         346             :     integer                 :: numOwnedElements
         347        1536 :     real(R8), pointer       :: ownedElemCoords(:)
         348        1536 :     real(r8), pointer       :: lat(:), latMesh(:)
         349        1536 :     real(r8), pointer       :: lon(:), lonMesh(:)
         350             :     real(r8)                :: lats(pcols)                       ! array of chunk latitudes
         351             :     real(r8)                :: lons(pcols)                       ! array of chunk longitude
         352             :     integer                 :: hdim1_d, hdim2_d                  ! dims of rect horizontal grid data (If 1D data struct, hdim2_d==1)
         353             :     integer                 :: ncols                             ! number of local columns
         354             :     integer                 :: start_ymd                         ! Start date (YYYYMMDD)
         355             :     integer                 :: start_tod                         ! Start time of day (sec)
         356             :     integer                 :: curr_ymd                          ! Start date (YYYYMMDD)
         357             :     integer                 :: curr_tod                          ! Start time of day (sec)
         358             :     integer                 :: stop_ymd                          ! Stop date (YYYYMMDD)
         359             :     integer                 :: stop_tod                          ! Stop time of day (sec)
         360             :     integer                 :: ref_ymd                           ! Reference date (YYYYMMDD)
         361             :     integer                 :: ref_tod                           ! Reference time of day (sec)
         362             :     character(len=cs)       :: calendar                          ! Calendar type
         363             :     integer                 :: dtime                             ! time step increment (sec)
         364             :     integer                 :: atm_cpl_dt                        ! driver atm coupling time step
         365             :     integer                 :: nstep                             ! CAM nstep
         366             :     real(r8)                :: caldayp1                          ! CAM calendar day for for next cam time step
         367             :     integer                 :: yy,mm,dd                          ! Temporaries for time query
         368             :     logical                 :: perpetual_run                     ! If in perpetual mode or not
         369             :     integer                 :: perpetual_ymd                     ! Perpetual date (YYYYMMDD)
         370             :     character(CL)           :: cvalue
         371             :     character(ESMF_MAXSTR)  :: convCIM, purpComp
         372             :     integer                 :: lsize                             ! local size ofarrays
         373             :     integer                 :: n,c,g,i,j                         ! indices
         374             :     character(len=cs)       :: start_type                        ! infodata start type
         375             :     character(len=cl)       :: caseid                            ! case ID
         376             :     character(len=cl)       :: ctitle                            ! case title
         377             :     character(len=cl)       :: model_doi_url                     ! DOI for CESM model run
         378             :     logical                 :: aqua_planet                       ! Flag to run model in "aqua planet" mode
         379             :     logical                 :: brnch_retain_casename             ! true => branch run has same caseid as run being branched from
         380             :     logical                 :: single_column = .false.
         381             :     character(len=cl)       :: single_column_lnd_domainfile
         382             :     real(r8)                :: scol_lon
         383             :     real(r8)                :: scol_lat
         384             :     real(r8)                :: scol_spval
         385             :     real(r8)                :: eccen
         386             :     real(r8)                :: obliqr
         387             :     real(r8)                :: lambm0
         388             :     real(r8)                :: mvelpp
         389             :     !character(len=cl)      :: atm_resume_all_inst(num_inst_atm) ! atm resume file
         390             :     integer                 :: lbnum
         391             :     character(CS)           :: inst_name
         392             :     integer                 :: inst_index
         393             :     character(CS)           :: inst_suffix
         394             :     integer                 :: lmpicom
         395             :     logical                 :: isPresent, isSet
         396             :     character(len=512)      :: diro
         397             :     character(len=512)      :: logfile
         398             :     integer                 :: compid                            ! component id
         399             :     integer                 :: localPet, localPeCount
         400             :     logical                 :: initial_run                       ! startup mode which only requires a minimal initial file
         401             :     logical                 :: restart_run                       ! continue a previous run; requires a restart file
         402             :     logical                 :: branch_run                        ! branch from a previous run; requires a restart file
         403             :     character(len=CL)       :: tempc1,tempc2
         404             :     integer                 :: shrlogunit          ! original log unit
         405             :     real(r8)        , parameter :: radtodeg = 180.0_r8/shr_const_pi
         406             :     integer         , parameter :: aqua_perpetual_ymd = 321
         407             :     character(len=*), parameter :: subname=trim(modName)//':(InitializeRealize) '
         408             :     character(len=*), parameter :: format = "('("//trim(subname)//") :',A)"
         409             :     !-------------------------------------------------------------------------------
         410             :
         411        1536 :     rc = ESMF_SUCCESS
         412             :     if (dbug_flag > 5) then
         413             :        call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO)
         414             :     end if
         415             :
         416        1536 :     call shr_log_setLogUnit (iulog)
         417             :
         418             :     !----------------------------------------------------------------------------
         419             :     ! generate local mpi comm
         420             :     !----------------------------------------------------------------------------
         421             :
         422        1536 :     call ESMF_GridCompGet(gcomp, vm=vm, localpet=localPet, rc=rc)
         423        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         424             :
         425        1536 :     call ESMF_VMGet(vm, mpiCommunicator=lmpicom, rc=rc)
         426        1536 :     if (chkerr(rc,__LINE__,u_FILE_u)) return
         427             :
         428        1536 :     call ESMF_VMGet(vm, pet=localPet, peCount=localPeCount, rc=rc)
         429        1536 :     if (chkerr(rc,__LINE__,u_FILE_u)) return
         430             :
         431        1536 :     if(localPeCount == 1) then
         432        1536 :        call NUOPC_CompAttributeGet(gcomp, "nthreads", value=cvalue, rc=rc)
         433        1536 :        if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return
         434        1536 :        read(cvalue,*) nthrds
         435             :     else
         436           0 :        nthrds = localPeCount
         437             :     endif
         438             :
         439             : !$  call omp_set_num_threads(nthrds)
         440             :
         441             :     !----------------------------------------------------------------------------
         442             :     ! determine instance information
         443             :     !----------------------------------------------------------------------------
         444        1536 :     call get_component_instance(gcomp, inst_suffix, inst_index, rc)
         445        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         446             :
         447        1536 :     inst_name = 'ATM'//inst_suffix
         448             :     ! Set filename specifier for restart surface file
         449             :     ! (%c=caseid, $y=year, $m=month, $d=day, $s=seconds in day)
         450        1536 :     rsfilename_spec_cam = '%c.cam' // trim(inst_suffix) // '.rs.%y-%m-%d-%s.nc'
         451             :
         452             :     !----------------------------------------------------------------------------
         453             :     ! initialize cam mpi (needed for masterproc below)
         454             :     !----------------------------------------------------------------------------
         455             :
         456        1536 :     call spmdinit(lmpicom)
         457             :
         458             :     !----------------------
         459             :     ! Initialize cam - needed in realize phase to get grid information
         460             :     !----------------------
         461             :
         462        1536 :     call NUOPC_CompAttributeGet(gcomp, name='MCTID', value=cvalue, rc=rc)
         463        1536 :     if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return
         464        1536 :     read(cvalue,*) compid
         465        1536 :     call cam_instance_init(compid, inst_name, inst_index, inst_suffix)
         466             :
         467             :     !----------------------
         468             :     ! Initialize cam - needed in realize phase to get grid information
         469             :     !----------------------
         470             :
         471        1536 :     if (masterproc) then
         472           2 :        write(iulog,format) "CAM atm model initialization"
         473             :     end if
         474             :
         475             : #if (defined _MEMTRACE)
         476             :     if(masterproc) then
         477             :        lbnum=1
         478             :        call memmon_dump_fort('memmon.out','atm_comp_nuopc_InitializeRealize:start::',lbnum)
         479             :     endif
         480             : #endif
         481             :
         482             :     !----------------------
         483             :     ! Obtain and load orbital values
         484             :     !----------------------
         485             :
         486        1536 :     call cam_orbital_init(gcomp, iulog, masterproc, rc)
         487        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         488             :
         489        1536 :     call cam_orbital_update(clock, iulog, masterproc, eccen, obliqr, lambm0, mvelpp, rc)
         490        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         491             :
         492        1536 :     call cam_ctrl_set_orbit(eccen, obliqr, lambm0, mvelpp)
         493             :
         494             :     !----------------------
         495             :     ! Obtain attributes
         496             :     !----------------------
         497             :
         498        1536 :     call NUOPC_CompAttributeGet(gcomp, name='case_name', value=cvalue, rc=rc)
         499        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         500        1536 :     read(cvalue,*) caseid
         501        1536 :     ctitle=caseid
         502             :
         503             :     ! starting info
         504        1536 :     call NUOPC_CompAttributeGet(gcomp, name='start_type', value=cvalue, rc=rc)
         505        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         506        1536 :     read(cvalue,*) start_type
         507        1536 :     call NUOPC_CompAttributeGet(gcomp, name='brnch_retain_casename', value=cvalue, rc=rc)
         508        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         509        1536 :     read(cvalue,*) brnch_retain_casename
         510             :
         511             :     ! single column input
         512        1536 :     call NUOPC_CompAttributeGet(gcomp, name='scol_lon', value=cvalue, rc=rc)
         513        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         514        1536 :     read(cvalue,*) scol_lon
         515        1536 :     call NUOPC_CompAttributeGet(gcomp, name='scol_lat', value=cvalue, rc=rc)
         516        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         517        1536 :     read(cvalue,*) scol_lat
         518        1536 :     call NUOPC_CompAttributeGet(gcomp, name='scol_spval', value=cvalue, rc=rc)
         519        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         520        1536 :     read(cvalue,*) scol_spval
         521             :
         522             :     ! For single column mode in cam need to have a valid single_column_lnd_domainfile for the mask
         523        1536 :     call NUOPC_CompAttributeGet(gcomp, name='single_column_lnd_domainfile', value=single_column_lnd_domainfile, rc=rc)
         524        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         525        1536 :     if (scol_lon > scol_spval .and. scol_lat > scol_spval) then
         526           0 :        if (trim(single_column_lnd_domainfile) /= 'UNSET') then
         527           0 :           single_column = .true.
         528             :        else
         529           0 :           call shr_sys_abort('single_column_lnd_domainfile cannot be null for single column mode')
         530             :        end if
         531             :     else
         532        1536 :        single_column = .false.
         533             :     end if
         534             :
         535             :     ! aqua planet input
         536        1536 :     call NUOPC_CompAttributeGet(gcomp, name='aqua_planet', value=cvalue, rc=rc)
         537        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         538        1536 :     read(cvalue,*) aqua_planet
         539             :
         540             :     ! perpetual input
         541        1536 :     call NUOPC_CompAttributeGet(gcomp, name='perpetual', value=cvalue, rc=rc)
         542        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         543        1536 :     read(cvalue,*) perpetual_run
         544        1536 :     call NUOPC_CompAttributeGet(gcomp, name='perpetual_ymd', value=cvalue, rc=rc)
         545        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         546        1536 :     read(cvalue,*) perpetual_ymd
         547             :
         548             :     ! TODO: query the config attributes for the number of instances - ASSUMES multi-driver
         549             :
         550             :     ! TODO: must obtain model_doi_url from gcomp - for now hardwire to 'not_set'
         551        1536 :     model_doi_url = 'not_set'
         552             :
         553             :     ! Initialize CAM, allocate cam_in and cam_out and determine
         554             :     ! atm decomposition (needed to initialize gsmap)
         555             :     ! for an initial run, cam_in and cam_out are allocated in cam_init
         556             :     ! for a restart/branch run, cam_in and cam_out are allocated in restart
         557             :     !
         558             :     !TODO: the following strings must not be hard-wired - must have module variables
         559             :     ! like seq_infodata_start_type_type - maybe another entry in flds_mod?
         560             :
         561        1536 :     initial_run = .false.
         562        1536 :     restart_run = .false.
         563        1536 :     branch_run  = .false.
         564        1536 :     if (trim(start_type) == trim('startup')) then
         565         768 :        initial_run = .true.
         566         768 :     else if (trim(start_type) == trim('continue') ) then
         567         768 :        restart_run = .true.
         568           0 :     else if (trim(start_type) == trim('branch')) then
         569           0 :        branch_run = .true.
         570             :     else
         571           0 :        call shr_sys_abort( subname//' ERROR: unknown start_type' )
         572             :     end if
         573             :
         574             :     ! DART always starts up as an initial run.
         575             :     call NUOPC_CompAttributeGet(gcomp, name='data_assimilation_atm', value=cvalue, &
         576        1536 :          isPresent=isPresent, isSet=isSet, rc=rc)
         577        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         578        1536 :     if (isPresent .and. isSet) then
         579        1536 :        read(cvalue,*) dart_mode
         580             :     end if
         581        1536 :     if (dart_mode) then
         582           0 :        initial_run = .true.
         583           0 :        restart_run = .false.
         584           0 :        branch_run  = .false.
         585             :     end if
         586             :
         587             :     ! Get properties from clock
         588             :     call ESMF_ClockGet( clock, &
         589             :          currTime=currTime, startTime=startTime, stopTime=stopTime, refTime=RefTime, &
         590        1536 :          timeStep=timeStep, rc=rc)
         591        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         592             :
         593        1536 :     call ESMF_TimeGet( currTime, yy=yy, mm=mm, dd=dd, s=curr_tod, rc=rc )
         594        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         595        1536 :     call shr_cal_ymd2date(yy,mm,dd,curr_ymd)
         596             :
         597        1536 :     call ESMF_TimeGet( startTime, yy=yy, mm=mm, dd=dd, s=start_tod, rc=rc )
         598        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         599        1536 :     call shr_cal_ymd2date(yy,mm,dd,start_ymd)
         600             :
         601        1536 :     call ESMF_TimeGet( stopTime, yy=yy, mm=mm, dd=dd, s=stop_tod, rc=rc )
         602        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         603        1536 :     call shr_cal_ymd2date(yy,mm,dd,stop_ymd)
         604             :
         605        1536 :     call ESMF_TimeGet( refTime, yy=yy, mm=mm, dd=dd, s=ref_tod, rc=rc )
         606        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         607        1536 :     call shr_cal_ymd2date(yy,mm,dd,ref_ymd)
         608             :
         609        1536 :     call ESMF_TimeIntervalGet( timeStep, s=dtime, rc=rc )
         610        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         611             :
         612        1536 :     call ESMF_TimeGet( currTime, calkindflag=esmf_caltype, rc=rc )
         613        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         614             :
         615        1536 :     if (esmf_caltype == ESMF_CALKIND_NOLEAP) then
         616        1536 :        calendar = shr_cal_noleap
         617           0 :     else if (esmf_caltype == ESMF_CALKIND_GREGORIAN) then
         618           0 :        calendar = shr_cal_gregorian
         619             :     else
         620           0 :        call shr_sys_abort( subname//'ERROR:: bad calendar for ESMF' )
         621             :     end if
         622             :
         623             :     ! Initialize module orbital values and update orbital
         624        1536 :     call cam_orbital_init(gcomp, iulog, masterproc, rc)
         625        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         626        1536 :     call cam_orbital_update(clock, iulog, masterproc, eccen, obliqr, lambm0, mvelpp, rc)
         627        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         628             :
         629             :     ! Initialize CAM
         630        1536 :     if (aqua_planet) then
         631        1536 :        perpetual_run = .true.
         632        1536 :        perpetual_ymd = aqua_perpetual_ymd
         633             :     end if
         634             :
         635             :     call cam_init( &
         636             :          caseid=caseid, ctitle=ctitle, model_doi_url=model_doi_url, &
         637             :          initial_run_in=initial_run, restart_run_in=restart_run, &
         638             :          branch_run_in=branch_run, post_assim_in=dart_mode, &
         639             :          calendar=calendar, brnch_retain_casename=brnch_retain_casename, aqua_planet=aqua_planet, &
         640             :          single_column=single_column, scmlat=scol_lat, scmlon=scol_lon, &
         641             :          eccen=eccen, obliqr=obliqr, lambm0=lambm0, mvelpp=mvelpp,  &
         642             :          perpetual_run=perpetual_run, perpetual_ymd=perpetual_ymd, &
         643             :          dtime=dtime, start_ymd=start_ymd, start_tod=start_tod, ref_ymd=ref_ymd, ref_tod=ref_tod, &
         644             :          stop_ymd=stop_ymd, stop_tod=stop_tod, curr_ymd=curr_ymd, curr_tod=curr_tod, &
         645        1536 :          cam_out=cam_out,  cam_in=cam_in)
         646             :
         647        1536 :     if (mediator_present) then
         648             :
         649        1536 :        if (single_column) then
         650             :
         651           0 :           call cam_set_mesh_for_single_column(scol_lon, scol_lat, model_mesh, rc)
         652           0 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         653           0 :           allocate(dof(1))
         654           0 :           dof(1) = 1
         655             :
         656             :        else
         657             :
         658             :           ! generate the dof
         659        1536 :           lsize = 0
         660        7728 :           do c = begchunk, endchunk
         661      104928 :              do i = 1, get_ncols_p(c)
         662      103392 :                 lsize = lsize + 1
         663             :              end do
         664             :           end do
         665        4608 :           allocate(dof(lsize))
         666        1536 :           n = 0
         667        7728 :           do c = begchunk, endchunk
         668      104928 :              do i = 1, get_ncols_p(c)
         669       97200 :                 n = n+1
         670      103392 :                 dof(n) = get_gcol_p(c,i)
         671             :              end do
         672             :           end do
         673             :
         674             :           ! create distGrid from global index array
         675        1536 :           DistGrid = ESMF_DistGridCreate(arbSeqIndexList=dof, rc=rc)
         676        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         677             :
         678             :           ! read in the mesh
         679        1536 :           call NUOPC_CompAttributeGet(gcomp, name='mesh_atm', value=cvalue, rc=rc)
         680        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         681             :
         682             :           model_mesh = ESMF_MeshCreate(filename=trim(cvalue), fileformat=ESMF_FILEFORMAT_ESMFMESH, &
         683        1536 :                elementDistgrid=Distgrid, rc=rc)
         684        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         685        1536 :           if (masterproc) then
         686           2 :              write(iulog,*)'mesh file for cam domain is ',trim(cvalue)
         687             :           end if
         688             :
         689             :           ! obtain mesh lats and lons
         690        1536 :           call ESMF_MeshGet(model_mesh, spatialDim=spatialDim, numOwnedElements=numOwnedElements, rc=rc)
         691        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         692        1536 :           if (numOwnedElements /= lsize) then
         693           0 :              write(tempc1,'(i10)') numOwnedElements
         694           0 :              write(tempc2,'(i10)') lsize
         695             :              call ESMF_LogWrite(trim(subname)//": ERROR numOwnedElements "// trim(tempc1) // &
         696           0 :                   " not equal to local size "// trim(tempc2), ESMF_LOGMSG_INFO, rc=rc)
         697           0 :              rc = ESMF_FAILURE
         698           0 :              return
         699             :           end if
         700        4608 :           allocate(ownedElemCoords(spatialDim*numOwnedElements))
         701        6144 :           allocate(lonMesh(lsize), latMesh(lsize))
         702        1536 :           call ESMF_MeshGet(model_mesh, ownedElemCoords=ownedElemCoords)
         703        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         704       98736 :           do n = 1,lsize
         705       97200 :              lonMesh(n) = ownedElemCoords(2*n-1)
         706       98736 :              latMesh(n) = ownedElemCoords(2*n)
         707             :           end do
         708             :
         709             :           ! obtain internally generated cam lats and lons
         710      101808 :           allocate(lon(lsize)); lon(:) = 0._r8
         711      100272 :           allocate(lat(lsize)); lat(:) = 0._r8
         712        1536 :           n=0
         713        7728 :           do c = begchunk, endchunk
         714        6192 :              ncols = get_ncols_p(c)
         715             :              ! latitudes and longitudes returned in radians
         716        6192 :              call get_rlat_all_p(c, ncols, lats)
         717        6192 :              call get_rlon_all_p(c, ncols, lons)
         718      104928 :              do i=1,ncols
         719       97200 :                 n = n+1
         720       97200 :                 lat(n) = lats(i)*radtodeg
         721      103392 :                 lon(n) = lons(i)*radtodeg
         722             :              end do
         723             :           end do
         724             :
         725             :           ! error check differences between internally generated lons and those read in
         726       98736 :           do n = 1,lsize
         727       97200 :              if (abs(lonMesh(n) - lon(n)) > grid_tol .and. .not. &
         728             :                   abs(abs(lonMesh(n) - lon(n))- 360._r8) < grid_tol) then
         729           0 :                 write(6,100)n,lon(n),lonMesh(n), abs(lonMesh(n)-lon(n))
         730             : 100             format('ERROR: CAM n, lonmesh(n), lon(n), diff_lon = ',i6,2(f21.13,3x),d21.5)
         731           0 :                 call shr_sys_abort()
         732             :              end if
         733       98736 :              if (abs(latMesh(n) - lat(n)) > grid_tol) then
         734           0 :                 write(6,100)n,lat(n),latMesh(n), abs(latMesh(n)-lat(n))
         735             : 101             format('ERROR: CAM n, latmesh(n), lat(n), diff_lat = ',i6,2(f21.13,3x),d21.5)
         736           0 :                 call shr_sys_abort()
         737             :              end if
         738             :           end do
         739             :
         740             :           ! deallocate memory
         741        1536 :           deallocate(ownedElemCoords)
         742        1536 :           deallocate(lon, lonMesh)
         743        3072 :           deallocate(lat, latMesh)
         744             :
         745             :        end if ! end of if single_column
         746             :
         747             :        ! realize the actively coupled fields
         748        1536 :        call realize_fields(gcomp, model_mesh, flds_scalar_name, flds_scalar_num, single_column, rc)
         749        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         750             :
         751             :        ! Create model_clock as a module variable - needed for generating streams
         752        1536 :        model_clock = clock
         753             :
         754             :        ! Create cam export array and set the state scalars
         755        1536 :        call export_fields( gcomp, model_mesh, model_clock, cam_out, rc=rc )
         756        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         757             :
         758        1536 :        call get_horiz_grid_dim_d(hdim1_d, hdim2_d)
         759             :        call State_SetScalar(dble(hdim1_d), flds_scalar_index_nx, exportState, &
         760        1536 :             flds_scalar_name, flds_scalar_num, rc)
         761        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         762             :        call State_SetScalar(dble(hdim2_d), flds_scalar_index_ny, exportState, &
         763        1536 :             flds_scalar_name, flds_scalar_num, rc)
         764        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         765             :
         766             :        ! diagnostics
         767             :        if (dbug_flag > 1) then
         768             :           call State_diagnose(exportState,subname//':ES',rc=rc)
         769             :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         770             :        endif
         771             :
         772             :     end if ! end of mediator_present if-block
         773             :
         774        1536 :     call shr_log_setLogUnit (shrlogunit)
         775             :
         776             : #if (defined _MEMTRACE)
         777             :     if(masterproc) then
         778             :        write(iulog,*) TRIM(Sub) // ':end::'
         779             :        lbnum=1
         780             :        call memmon_dump_fort('memmon.out','atm_comp_nuopc_InitializeRealize:end::',lbnum)
         781             :        call memmon_reset_addr()
         782             :     endif
         783             : #endif
         784             :
         785             :     if (dbug_flag > 5) then
         786             :        call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO)
         787             :     end if
         788             :
         789       69120 :   end subroutine InitializeRealize
         790             :
         791             :   !===============================================================================
         792        3072 :   subroutine DataInitialize(gcomp, rc)
         793             :
         794             :     type(ESMF_GridComp)  :: gcomp
         795             :     integer, intent(out) :: rc
         796             :
         797             :     ! local variables
         798             :     type(ESMF_Clock)                   :: clock
         799             :     type(ESMF_State)                   :: importState, exportState
         800             :     type(ESMF_Time)                    :: currTime      ! Current time
         801             :     type(ESMF_TimeInterval)            :: timeStep
         802             :     type(ESMF_Field)                   :: field
         803        3072 :     character(ESMF_MAXSTR),allocatable :: fieldNameList(:)
         804             :     character(ESMF_MAXSTR)             :: fieldName
         805             :     integer                            :: n, fieldCount
         806             :     integer                            :: shrlogunit    ! original log unit
         807             :     integer(ESMF_KIND_I8)              :: stepno        ! time step
         808             :     integer                            :: atm_cpl_dt    ! driver atm coupling time step
         809             :     logical                            :: importDone    ! true => import data is valid
         810             :     logical                            :: atCorrectTime ! true => field is at correct time
         811             :     character(CL)                      :: cvalue
         812             :     character(len=*),parameter         :: subname=trim(modName)//':(DataInitialize) '
         813             :     !-------------------------------------------------------------------------------
         814             :
         815        3072 :     rc = ESMF_SUCCESS
         816             :     if (dbug_flag > 5) then
         817             :        call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO)
         818             :     end if
         819             :
         820        3072 :     call shr_log_getLogUnit (shrlogunit)
         821        3072 :     call shr_log_setLogUnit (iulog)
         822             :
         823             : #if (defined _MEMTRACE)
         824             :     if (masterproc) then
         825             :        lbnum=1
         826             :        call memmon_dump_fort('memmon.out','atm_comp_nuopc_DataInitialize:start::',lbnum)
         827             :     endif
         828             : #endif
         829             :
         830             :     !--------------------------------
         831             :     ! Query the Component for its clock, importState and exportState
         832             :     !--------------------------------
         833             :
         834        3072 :     call ESMF_GridCompGet(gcomp, clock=clock, importState=importState, exportState=exportState, rc=rc)
         835        4608 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         836             :
         837             :     ! get the current time out of the clock
         838        3072 :     call ESMF_ClockGet(clock, currTime=currTime, rc=rc)
         839        3072 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
         840             :
         841             :     if (dbug_flag > 1) then
         842             :        call log_clock_advance(clock, 'CAM', iulog, rc)
         843             :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         844             :     endif
         845             :
         846             :     !---------------------------------------------------------------
         847        3072 :     if (mediator_present) then
         848             :     !---------------------------------------------------------------
         849             :
         850             :        ! Determine if all the import state has been initialized
         851             :        ! And if not initialized, then return
         852             :
         853        3072 :        call ESMF_StateGet(importState, itemCount=fieldCount, rc=rc)
         854        3072 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         855             :
         856        9216 :        allocate(fieldNameList(fieldCount))
         857        3072 :        call ESMF_StateGet(importState, itemNameList=fieldNameList, rc=rc)
         858        3072 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         859        3072 :        importDone = .true.
         860       44544 :        do n=1, fieldCount
         861       43008 :           call ESMF_StateGet(importState, itemName=fieldNameList(n), field=field, rc=rc)
         862       43008 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         863             :
         864       43008 :           atCorrectTime = NUOPC_IsAtTime(field, currTime, rc=rc)
         865       43008 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         866             :
         867       87552 :           if (.not. atCorrectTime) then
         868        1536 :              call ESMF_LogWrite("CAM - Initialize-Data-Dependency NOT YET SATISFIED!!!", ESMF_LOGMSG_INFO, rc=rc)
         869        1536 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
         870             :
         871             :              importDone = .false.
         872             :              exit  ! break out of the loop when first not satisfied found
         873             :           end if
         874             :        end do
         875        3072 :        deallocate(fieldNameList)
         876             :
         877             :        ! *** Import state has not been initialized - RETURN ****
         878             :
         879        3072 :        if (.not. importDone) then
         880             :           ! Simply return if the import has not been initialized
         881             :           call ESMF_LogWrite("CAM - Initialize-Data-Dependency Returning to mediator without doing tphysbc", &
         882        1536 :                ESMF_LOGMSG_INFO, rc=rc)
         883        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         884             :           RETURN
         885             :        end if
         886             :
         887             :        ! *** Import state has been initialized - continue with tphysbc ***
         888             :
         889        1536 :        call ESMF_LogWrite("CAM - Initialize-Data-Dependency doing tphysbc", ESMF_LOGMSG_INFO, rc=rc)
         890        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         891             :
         892             :        ! get the current step number and coupling interval
         893        1536 :        call ESMF_ClockGet( clock, TimeStep=timeStep, advanceCount=stepno, rc=rc )
         894        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         895        1536 :        call ESMF_TimeIntervalGet( timeStep, s=atm_cpl_dt, rc=rc )
         896        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         897             :
         898             :        ! For initial run, unpack the import state, run cam radiation/clouds and return
         899             :        ! For restart run, read the import state from the restart and run radiation/clouds and return
         900             :
         901             :        ! Note - cam_run1 is called only for the purposes of finishing the
         902             :        ! flux averaged calculation to compute cam-out
         903             :        ! Note - cam_run1 is called on restart only to have cam internal state consistent with the
         904             :        ! cam_out state sent to the coupler
         905             :
         906        1536 :        if (stepno == 0) then
         907         768 :           call import_fields( gcomp, cam_in, rc=rc )
         908         768 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         909         768 :           call cam_run1 ( cam_in, cam_out )
         910         768 :           call export_fields( gcomp, model_mesh, model_clock, cam_out, rc=rc )
         911         768 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         912             :        else
         913         768 :           call cam_read_srfrest( gcomp, clock, rc=rc )
         914         768 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         915         768 :           call import_fields( gcomp, cam_in, restart_init=.true., rc=rc )
         916         768 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         917         768 :           call cam_run1 ( cam_in, cam_out )
         918         768 :           call export_fields( gcomp, model_mesh, model_clock, cam_out, rc=rc )
         919         768 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         920             :        end if
         921             :
         922             :        ! Compute time of next radiation computation
         923             :        call State_SetScalar(nextsw_cday, flds_scalar_index_nextsw_cday, exportState, &
         924        1536 :             flds_scalar_name, flds_scalar_num, rc)
         925        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         926             :
         927             :        ! diagnostics
         928             :        if (dbug_flag > 1) then
         929             :           call State_diagnose(exportState,subname//':ES',rc=rc)
         930             :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         931             :        endif
         932             :
         933             :        ! CAM data is now fully initialized
         934             :
         935        1536 :        call ESMF_StateGet(exportState, itemCount=fieldCount, rc=rc)
         936        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         937             :
         938        4608 :        allocate(fieldNameList(fieldCount))
         939        1536 :        call ESMF_StateGet(exportState, itemNameList=fieldNameList, rc=rc)
         940        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         941             :
         942       46080 :        do n=1, fieldCount
         943       44544 :           call ESMF_StateGet(exportState, itemName=fieldNameList(n), field=field, rc=rc)
         944       44544 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         945             :
         946       44544 :           call NUOPC_SetAttribute(field, name="Updated", value="true", rc=rc)
         947       90624 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         948             :        end do
         949        1536 :        deallocate(fieldNameList)
         950             :
         951             :        ! check whether all Fields in the exportState are "Updated"
         952        9216 :        if (NUOPC_IsUpdated(exportState)) then
         953        1536 :           call NUOPC_CompAttributeSet(gcomp, name="InitializeDataComplete", value="true", rc=rc)
         954        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         955             :
         956        1536 :           call ESMF_LogWrite("CAM - Initialize-Data-Dependency SATISFIED!!!", ESMF_LOGMSG_INFO, rc=rc)
         957        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
         958             :        end if
         959             :
         960             :     !---------------------------------------------------------------
         961             :     else  ! mediator is not present
         962             :     !---------------------------------------------------------------
         963             :
         964           0 :        call cam_run1 ( cam_in, cam_out )
         965             :
         966           0 :        call NUOPC_CompAttributeSet(gcomp, name="InitializeDataComplete", value="true", rc=rc)
         967           0 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
         968             :
         969             :     end if
         970             :
         971             :     ! End redirection of share output to cam log
         972        1536 :     call shr_log_setLogUnit (shrlogunit)
         973             :
         974             : #if (defined _MEMTRACE)
         975             :     if(masterproc) then
         976             :        lbnum=1
         977             :        call memmon_dump_fort('memmon.out','atm_comp_nuopc_DataInitialize:end::',lbnum)
         978             :     endif
         979             : #endif
         980             :
         981             :     if (dbug_flag > 5) then
         982             :        call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO)
         983             :     end if
         984             :
         985       84480 :   end subroutine DataInitialize
         986             :
         987             :   !===============================================================================
         988      368640 :   subroutine ModelAdvance(gcomp, rc)
         989             :
         990             :     use ESMF, only : ESMF_GridCompGet, esmf_vmget, esmf_vm
         991             :     ! Run CAM
         992             :
         993             :     ! Input/output variables
         994             :     type(ESMF_GridComp)  :: gcomp
         995             :     integer, intent(out) :: rc
         996             :
         997             :     ! local variables
         998             :     type(ESMF_VM)           :: vm
         999             :     type(ESMF_Clock)        :: clock
        1000             :     type(ESMF_Alarm)        :: alarm
        1001             :     type(ESMF_Time)         :: time
        1002             :     type(ESMF_Time)         :: currTime    ! Current time
        1003             :     type(ESMF_Time)         :: nextTime    ! Next timestep time
        1004             :     type(ESMF_TimeInterval) :: timeStep    ! Clock, time-step
        1005             :     type(ESMF_State)        :: importState
        1006             :     type(ESMF_State)        :: exportState
        1007             :     character(CL)           :: cvalue
        1008             :     integer                 :: shrlogunit  ! original log unit
        1009             :     character(CL)           :: case_name   ! case name
        1010             :     real(r8)                :: eccen
        1011             :     real(r8)                :: obliqr
        1012             :     real(r8)                :: lambm0
        1013             :     real(r8)                :: mvelpp
        1014             :     logical                 :: dosend      ! true => send data back to driver
        1015             :     integer                 :: dtime       ! time step increment (sec)
        1016             :     integer                 :: ymd_sync    ! Sync ymd
        1017             :     integer                 :: yr_sync     ! Sync current year
        1018             :     integer                 :: mon_sync    ! Sync current month
        1019             :     integer                 :: day_sync    ! Sync current day
        1020             :     integer                 :: tod_sync    ! Sync current time of day (sec)
        1021             :     integer                 :: ymd         ! CAM current date (YYYYMMDD)
        1022             :     integer                 :: yr          ! CAM current year
        1023             :     integer                 :: mon         ! CAM current month
        1024             :     integer                 :: day         ! CAM current day
        1025             :     integer                 :: tod         ! CAM current time of day (sec)
        1026             :     logical                 :: rstwr       ! .true. ==> write restart file before returning
        1027             :     logical                 :: nlend       ! Flag signaling last time-step
        1028             :     integer                 :: lbnum
        1029             :     integer                 :: localPet, localPeCount
        1030             :     logical                 :: first_time = .true.
        1031             :     character(len=*),parameter  :: subname=trim(modName)//':(ModelAdvance) '
        1032             :     !-------------------------------------------------------------------------------
        1033             :
        1034      368640 :     rc = ESMF_SUCCESS
        1035             :
        1036             : !$  call omp_set_num_threads(nthrds)
        1037             :
        1038      368640 :     call shr_log_getLogUnit (shrlogunit)
        1039      368640 :     call shr_log_setLogUnit (iulog)
        1040             :
        1041             : #if (defined _MEMTRACE)
        1042             :     if(masterproc) then
        1043             :        lbnum=1
        1044             :        call memmon_dump_fort('memmon.out','atm_comp_nuopc_ModelAdvance:start::',lbnum)
        1045             :     endif
        1046             : #endif
        1047             :
        1048             :     !--------------------------------
        1049             :     ! Query the Component for its clock, importState and exportState
        1050             :     !--------------------------------
        1051             :
        1052      368640 :     call NUOPC_ModelGet(gcomp, modelClock=clock, importState=importState, exportState=exportState, rc=rc)
        1053      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1054             :
        1055             :     if (dbug_flag > 1) then
        1056             :        call log_clock_advance(clock, 'CAM', iulog, rc)
        1057             :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1058             :     endif
        1059             :
        1060             :     !--------------------------------
        1061             :     ! Determine current time
        1062             :     !--------------------------------
        1063             :
        1064      368640 :     call ESMF_ClockGet( clock, currTime=currTime)
        1065      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1066             :
        1067      368640 :     call ESMF_ClockGetNextTime(clock, nextTime=nextTime, rc=rc)
        1068      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1069      368640 :     call ESMF_TimeGet(nexttime, yy=yr_sync, mm=mon_sync, dd=day_sync, s=tod_sync, rc=rc)
        1070      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1071             :
        1072             :     !----------------------
        1073             :     ! Update and load orbital parameters
        1074             :     !----------------------
        1075             :
        1076      368640 :     if (trim(orb_mode) == trim(orb_variable_year) .or. first_time) then
        1077        1536 :        call cam_orbital_update(clock, iulog, masterproc, eccen, obliqr, lambm0, mvelpp, rc)
        1078        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1079        1536 :        call cam_ctrl_set_orbit(eccen, obliqr, lambm0, mvelpp)
        1080             :     end if
        1081      368640 :     first_time = .false.
        1082             :
        1083             :     !--------------------------------
        1084             :     ! Run cam
        1085             :     !--------------------------------
        1086             :
        1087             :     ! Unpack import state
        1088      368640 :     if (mediator_present) then
        1089      368640 :        call t_startf ('CAM_import')
        1090      368640 :        call State_diagnose(importState, string=subname//':IS', rc=rc)
        1091      368640 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1092             :
        1093      368640 :        call import_fields( gcomp, cam_in, rc=rc)
        1094      368640 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1095      368640 :        call t_stopf  ('CAM_import')
        1096             :     end if
        1097             :
        1098             :     dosend = .false.
        1099      738048 :     do while (.not. dosend)
        1100             :
        1101             :        ! TODO: This is currently hard-wired - is there a better way for nuopc?
        1102             :        ! Need to not return when nstep = 0 and return when nstep = 1
        1103             :        ! Note that the model clock is updated at the end of the time step not at the beginning
        1104      369408 :        if (get_nstep() > 0) then
        1105      368640 :           dosend = .true.
        1106             :        end if
        1107             :
        1108             :        ! Determine if time to write restart
        1109             :
        1110      369408 :        call ESMF_ClockGetAlarm(clock, alarmname='alarm_restart', alarm=alarm, rc=rc)
        1111      369408 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1112             :
        1113      369408 :        if (ESMF_AlarmIsRinging(alarm, rc=rc)) then
        1114        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1115        1536 :           rstwr = .true.
        1116        1536 :           call ESMF_AlarmRingerOff( alarm, rc=rc )
        1117        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1118             :        else
        1119      367872 :           rstwr = .false.
        1120             :        endif
        1121             :
        1122             :        ! Determine if time to stop
        1123             :
        1124      369408 :        call ESMF_ClockGetAlarm(clock, alarmname='alarm_stop', alarm=alarm, rc=rc)
        1125      369408 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1126             :
        1127      369408 :        if (ESMF_AlarmIsRinging(alarm, rc=rc)) then
        1128        1536 :           nlend = .true.
        1129             :        else
        1130      367872 :           nlend = .false.
        1131             :        endif
        1132             :
        1133             :        ! Run CAM (run2, run3, run4)
        1134             :
        1135      369408 :        call t_startf ('CAM_run2')
        1136      369408 :        call cam_run2( cam_out, cam_in )
        1137      369408 :        call t_stopf  ('CAM_run2')
        1138             :
        1139      369408 :        call t_startf ('CAM_run3')
        1140      369408 :        call cam_run3( cam_out )
        1141      369408 :        call t_stopf  ('CAM_run3')
        1142             :
        1143      369408 :        call t_startf ('CAM_run4')
        1144             :        call cam_run4( cam_out, cam_in, rstwr, nlend, &
        1145      369408 :             yr_spec=yr_sync, mon_spec=mon_sync, day_spec=day_sync, sec_spec=tod_sync)
        1146      369408 :        call t_stopf  ('CAM_run4')
        1147             :
        1148             :        ! Advance cam time step
        1149             :
        1150      369408 :        call t_startf ('CAM_adv_timestep')
        1151      369408 :        call advance_timestep()
        1152      369408 :        call t_stopf  ('CAM_adv_timestep')
        1153             :
        1154             :        ! Run cam radiation/clouds (run1)
        1155             :
        1156      369408 :        call t_startf ('CAM_run1')
        1157      369408 :        call cam_run1 ( cam_in, cam_out )
        1158      369408 :        call t_stopf  ('CAM_run1')
        1159             :
        1160             :     end do
        1161             :
        1162      368640 :     if (mediator_present) then
        1163             :        ! Set export fields
        1164      368640 :        call t_startf ('CAM_export')
        1165      368640 :        call export_fields( gcomp, model_mesh, model_clock, cam_out, rc )
        1166      368640 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1167      368640 :        call t_stopf ('CAM_export')
        1168             :
        1169             :        ! Set the coupling scalars
        1170             :        ! Return time of next radiation calculation - albedos will need to be
        1171             :        ! calculated by each surface model at this time
        1172             :        call State_SetScalar(nextsw_cday, flds_scalar_index_nextsw_cday, exportState, &
        1173      368640 :             flds_scalar_name, flds_scalar_num, rc)
        1174      368640 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1175             :
        1176             :        ! diagnostics
        1177             :        if (dbug_flag > 1) then
        1178             :           call State_diagnose(exportState, string=subname//':ES',rc=rc)
        1179             :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1180             :           if (masterproc) then
        1181             :              call log_clock_advance(clock, 'CAM', iulog, rc)
        1182             :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1183             :           end if
        1184             :        endif
        1185             :
        1186             :        ! Write merged surface data restart file if appropriate
        1187      368640 :        if (rstwr) then
        1188             :           call cam_write_srfrest( gcomp, &
        1189        1536 :                yr_spec=yr_sync, mon_spec=mon_sync, day_spec=day_sync, sec_spec=tod_sync, rc=rc)
        1190        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1191             :        end if
        1192             :
        1193             :     else
        1194             :
        1195             :        ! if there is no mediator, then write the clock info to a driver restart file
        1196           0 :        if (rstwr) then
        1197           0 :           call cam_write_clockrest( clock, yr_sync, mon_sync, day_sync, tod_sync, rc=rc)
        1198           0 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1199             :        end if
        1200             :
        1201             :     end if
        1202             :
        1203             :     ! Check for consistency of internal cam clock with master sync clock
        1204             :     ! Note that the driver clock has not been updated yet - so at this point
        1205             :     ! CAM is actually 2 coupling intervals (or physics time steps) ahead of the driver clock
        1206      368640 :     dtime = get_step_size()
        1207      368640 :     call get_curr_date( yr, mon, day, tod, offset=-2*dtime )
        1208      368640 :     ymd = yr*10000 + mon*100 + day
        1209             :     tod = tod
        1210             :
        1211      368640 :     call ESMF_ClockGet( clock, currTime=currTime, rc=rc)
        1212      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1213      368640 :     call ESMF_TimeGet( currTime, yy=yr_sync, mm=mon_sync, dd=day_sync, s=tod_sync, rc=rc )
        1214      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1215      368640 :     call shr_cal_ymd2date(yr_sync, mon_sync, day_sync, ymd_sync)
        1216             :
        1217      368640 :     if ( (ymd /= ymd_sync) .and. (tod /= tod_sync) )then
        1218           0 :        write(iulog,*)' cam ymd=',ymd     ,'  cam tod= ',tod
        1219           0 :        write(iulog,*)'sync ymd=',ymd_sync,' sync tod= ',tod_sync
        1220           0 :        call shr_sys_abort( subname//': CAM clock is not in sync with master Sync Clock' )
        1221             :     end if
        1222             :
        1223             : #if (defined _MEMTRACE)
        1224             :     if(masterproc) then
        1225             :        lbnum=1
        1226             :        call memmon_dump_fort('memmon.out','atm_comp_nuopc_ModelAdvance:end::',lbnum)
        1227             :     endif
        1228             : #endif
        1229             :
        1230             :     !--------------------------------
        1231             :     ! Reset shr logging to my original values
        1232             :     !--------------------------------
        1233             :
        1234      368640 :     call shr_log_setLogUnit (shrlogunit)
        1235             :
        1236     5160960 :   end subroutine ModelAdvance
        1237             :
        1238             :   !===============================================================================
        1239             :
        1240      368640 :   subroutine ModelSetRunClock(gcomp, rc)
        1241             :
        1242             :     ! input/output variables
        1243             :     type(ESMF_GridComp)  :: gcomp
        1244             :     integer, intent(out) :: rc
        1245             :
        1246             :     ! local variables
        1247             :     type(ESMF_Clock)         :: mclock, dclock
        1248             :     type(ESMF_Time)          :: mcurrtime, dcurrtime
        1249             :     type(ESMF_Time)          :: mstoptime
        1250             :     type(ESMF_TimeInterval)  :: mtimestep, dtimestep
        1251             :     character(len=256)       :: cvalue
        1252             :     character(len=256)       :: restart_option ! Restart option units
        1253             :     integer                  :: restart_n      ! Number until restart interval
        1254             :     integer                  :: restart_ymd    ! Restart date (YYYYMMDD)
        1255             :     type(ESMF_ALARM)         :: restart_alarm
        1256             :     character(len=256)       :: stop_option    ! Stop option units
        1257             :     integer                  :: stop_n         ! Number until stop interval
        1258             :     integer                  :: stop_ymd       ! Stop date (YYYYMMDD)
        1259             :     type(ESMF_ALARM)         :: stop_alarm
        1260             :     character(len=128)       :: name
        1261             :     integer                  :: alarmcount
        1262             :     character(len=*),parameter :: subname=trim(modName)//':(ModelSetRunClock) '
        1263             :     !-------------------------------------------------------------------------------
        1264             :
        1265      368640 :     rc = ESMF_SUCCESS
        1266             :
        1267             :     ! query the Component for its clocks
        1268      368640 :     call NUOPC_ModelGet(gcomp, driverClock=dclock, modelClock=mclock, rc=rc)
        1269      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1270             :
        1271      368640 :     call ESMF_ClockGet(dclock, currTime=dcurrtime, timeStep=dtimestep, rc=rc)
        1272      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1273             :
        1274      368640 :     call ESMF_ClockGet(mclock, currTime=mcurrtime, timeStep=mtimestep, rc=rc)
        1275      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1276             :
        1277             :     !--------------------------------
        1278             :     ! force model clock currtime and timestep to match driver and set stoptime
        1279             :     !--------------------------------
        1280             :
        1281      368640 :     mstoptime = mcurrtime + dtimestep
        1282      368640 :     call ESMF_ClockSet(mclock, currTime=dcurrtime, timeStep=dtimestep, stopTime=mstoptime, rc=rc)
        1283      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1284             :
        1285             :     !--------------------------------
        1286             :     ! set restart and stop alarms
        1287             :     !--------------------------------
        1288             :
        1289      368640 :     call ESMF_ClockGetAlarmList(mclock, alarmlistflag=ESMF_ALARMLIST_ALL, alarmCount=alarmCount, rc=rc)
        1290      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1291             :
        1292      368640 :     if (alarmCount == 0) then
        1293             :
        1294        1536 :        call ESMF_GridCompGet(gcomp, name=name, rc=rc)
        1295        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1296        1536 :        call ESMF_LogWrite(subname//'setting alarms for' // trim(name), ESMF_LOGMSG_INFO)
        1297             :
        1298             :        !----------------
        1299             :        ! Restart alarm
        1300             :        !----------------
        1301        1536 :        call NUOPC_CompAttributeGet(gcomp, name="restart_option", value=restart_option, rc=rc)
        1302        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1303             :
        1304        1536 :        call NUOPC_CompAttributeGet(gcomp, name="restart_n", value=cvalue, rc=rc)
        1305        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1306        1536 :        read(cvalue,*) restart_n
        1307             :
        1308        1536 :        call NUOPC_CompAttributeGet(gcomp, name="restart_ymd", value=cvalue, rc=rc)
        1309        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1310        1536 :        read(cvalue,*) restart_ymd
        1311             :
        1312             :        call alarmInit(mclock, restart_alarm, restart_option, &
        1313             :             opt_n   = restart_n,           &
        1314             :             opt_ymd = restart_ymd,         &
        1315             :             RefTime = mcurrTime,           &
        1316        1536 :             alarmname = 'alarm_restart', rc=rc)
        1317        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1318             :
        1319        1536 :        call ESMF_AlarmSet(restart_alarm, clock=mclock, rc=rc)
        1320        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1321             :
        1322             :        !----------------
        1323             :        ! Stop alarm
        1324             :        !----------------
        1325        1536 :        call NUOPC_CompAttributeGet(gcomp, name="stop_option", value=stop_option, rc=rc)
        1326        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1327             :
        1328        1536 :        call NUOPC_CompAttributeGet(gcomp, name="stop_n", value=cvalue, rc=rc)
        1329        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1330        1536 :        read(cvalue,*) stop_n
        1331             :
        1332        1536 :        call NUOPC_CompAttributeGet(gcomp, name="stop_ymd", value=cvalue, rc=rc)
        1333        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1334        1536 :        read(cvalue,*) stop_ymd
        1335             :
        1336             :        call alarmInit(mclock, stop_alarm, stop_option, &
        1337             :             opt_n   = stop_n,           &
        1338             :             opt_ymd = stop_ymd,         &
        1339             :             RefTime = mcurrTime,           &
        1340        1536 :             alarmname = 'alarm_stop', rc=rc)
        1341        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1342             :
        1343        1536 :        call ESMF_AlarmSet(stop_alarm, clock=mclock, rc=rc)
        1344        1536 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1345             :
        1346             :     end if
        1347             :
        1348             :     !--------------------------------
        1349             :     ! Advance model clock to trigger alarms then reset model clock back to currtime
        1350             :     !--------------------------------
        1351             :
        1352      368640 :     call ESMF_ClockAdvance(mclock,rc=rc)
        1353      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1354             :
        1355      368640 :     call ESMF_ClockSet(mclock, currTime=dcurrtime, timeStep=dtimestep, stopTime=mstoptime, rc=rc)
        1356      368640 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1357             :
        1358    21381120 :   end subroutine ModelSetRunClock
        1359             :
        1360             :   !===============================================================================
        1361        1536 :   subroutine ModelFinalize(gcomp, rc)
        1362             :     type(ESMF_GridComp)  :: gcomp
        1363             :     integer, intent(out) :: rc
        1364             :
        1365             :     ! local variables
        1366             :     integer :: shrlogunit            ! original log unit
        1367             :     character(*), parameter :: F00   = "('(atm_comp_nuopc) ',8a)"
        1368             :     character(*), parameter :: F91   = "('(atm_comp_nuopc) ',73('-'))"
        1369             :     character(len=*),parameter  :: subname=trim(modName)//':(ModelFinalize) '
        1370             :     !-------------------------------------------------------------------------------
        1371             :
        1372             :     !--------------------------------
        1373             :     ! Finalize routine
        1374             :     !--------------------------------
        1375             :
        1376        1536 :     rc = ESMF_SUCCESS
        1377             :
        1378        1536 :     call shr_log_getLogUnit (shrlogunit)
        1379        1536 :     call shr_log_setLogUnit (iulog)
        1380             :
        1381        1536 :     call cam_final( cam_out, cam_in )
        1382             :
        1383        1536 :     if (masterproc) then
        1384           2 :        write(iulog,F91)
        1385           2 :        write(iulog,F00) 'CAM: end of main integration loop'
        1386           2 :        write(iulog,F91)
        1387             :     end if
        1388             :
        1389        1536 :     call shr_log_setLogUnit (shrlogunit)
        1390             :
        1391        1536 :   end subroutine ModelFinalize
        1392             :
        1393             :   !===============================================================================
        1394        3072 :   subroutine cam_orbital_init(gcomp, logunit, mastertask, rc)
        1395             :
        1396             :     !----------------------------------------------------------
        1397             :     ! Initialize orbital related values
        1398             :     !----------------------------------------------------------
        1399             :
        1400             :     ! input/output variables
        1401             :     type(ESMF_GridComp) , intent(in)    :: gcomp
        1402             :     integer             , intent(in)    :: logunit
        1403             :     logical             , intent(in)    :: mastertask
        1404             :     integer             , intent(out)   :: rc              ! output error
        1405             :
        1406             :     ! local variables
        1407             :     character(len=CL) :: msgstr          ! temporary
        1408             :     character(len=CL) :: cvalue          ! temporary
        1409             :     character(len=*) , parameter :: subname = "(cam_orbital_init)"
        1410             :     !-------------------------------------------------------------------------------
        1411             :
        1412        3072 :     rc = ESMF_SUCCESS
        1413             :
        1414             :     ! Determine orbital attributes from input
        1415        3072 :     call NUOPC_CompAttributeGet(gcomp, name="orb_mode", value=cvalue, rc=rc)
        1416        3072 :     if (chkerr(rc,__LINE__,u_FILE_u)) return
        1417        3072 :     read(cvalue,*) orb_mode
        1418             :
        1419        3072 :     call NUOPC_CompAttributeGet(gcomp, name="orb_iyear", value=cvalue, rc=rc)
        1420        3072 :     if (chkerr(rc,__LINE__,u_FILE_u)) return
        1421        3072 :     read(cvalue,*) orb_iyear
        1422             :
        1423        3072 :     call NUOPC_CompAttributeGet(gcomp, name="orb_iyear_align", value=cvalue, rc=rc)
        1424        3072 :     if (chkerr(rc,__LINE__,u_FILE_u)) return
        1425        3072 :     read(cvalue,*) orb_iyear_align
        1426             :
        1427        3072 :     call NUOPC_CompAttributeGet(gcomp, name="orb_obliq", value=cvalue, rc=rc)
        1428        3072 :     if (chkerr(rc,__LINE__,u_FILE_u)) return
        1429        3072 :     read(cvalue,*) orb_obliq
        1430             :
        1431        3072 :     call NUOPC_CompAttributeGet(gcomp, name="orb_eccen", value=cvalue, rc=rc)
        1432        3072 :     if (chkerr(rc,__LINE__,u_FILE_u)) return
        1433        3072 :     read(cvalue,*) orb_eccen
        1434             :
        1435        3072 :     call NUOPC_CompAttributeGet(gcomp, name="orb_mvelp", value=cvalue, rc=rc)
        1436        3072 :     if (chkerr(rc,__LINE__,u_FILE_u)) return
        1437        3072 :     read(cvalue,*) orb_mvelp
        1438             :
        1439             :     ! Error checks
        1440        3072 :     if (trim(orb_mode) == trim(orb_fixed_year)) then
        1441           0 :        orb_obliq = SHR_ORB_UNDEF_REAL
        1442           0 :        orb_eccen = SHR_ORB_UNDEF_REAL
        1443           0 :        orb_mvelp = SHR_ORB_UNDEF_REAL
        1444           0 :        if (orb_iyear == SHR_ORB_UNDEF_INT) then
        1445           0 :           if (mastertask) then
        1446           0 :              write(logunit,*) trim(subname),' ERROR: invalid settings orb_mode =',trim(orb_mode)
        1447           0 :              write(logunit,*) trim(subname),' ERROR: fixed_year settings = ',orb_iyear
        1448           0 :              write (msgstr, *) ' ERROR: invalid settings for orb_mode '//trim(orb_mode)
        1449             :           end if
        1450           0 :           call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
        1451           0 :           return  ! bail out
        1452             :        endif
        1453        3072 :     elseif (trim(orb_mode) == trim(orb_variable_year)) then
        1454           0 :        orb_obliq = SHR_ORB_UNDEF_REAL
        1455           0 :        orb_eccen = SHR_ORB_UNDEF_REAL
        1456           0 :        orb_mvelp = SHR_ORB_UNDEF_REAL
        1457           0 :        if (orb_iyear == SHR_ORB_UNDEF_INT .or. orb_iyear_align == SHR_ORB_UNDEF_INT) then
        1458           0 :           if (mastertask) then
        1459           0 :              write(logunit,*) trim(subname),' ERROR: invalid settings orb_mode =',trim(orb_mode)
        1460           0 :              write(logunit,*) trim(subname),' ERROR: variable_year settings = ',orb_iyear, orb_iyear_align
        1461           0 :              write (msgstr, *) subname//' ERROR: invalid settings for orb_mode '//trim(orb_mode)
        1462             :           end if
        1463           0 :           call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
        1464           0 :           return  ! bail out
        1465             :        endif
        1466        3072 :     elseif (trim(orb_mode) == trim(orb_fixed_parameters)) then
        1467             :        !-- force orb_iyear to undef to make sure shr_orb_params works properly
        1468        3072 :        orb_iyear = SHR_ORB_UNDEF_INT
        1469        3072 :        orb_iyear_align = SHR_ORB_UNDEF_INT
        1470             :        if (orb_eccen == SHR_ORB_UNDEF_REAL .or. &
        1471        3072 :            orb_obliq == SHR_ORB_UNDEF_REAL .or. &
        1472             :            orb_mvelp == SHR_ORB_UNDEF_REAL) then
        1473           0 :           if (mastertask) then
        1474           0 :              write(logunit,*) trim(subname),' ERROR: invalid settings orb_mode =',trim(orb_mode)
        1475           0 :              write(logunit,*) trim(subname),' ERROR: orb_eccen = ',orb_eccen
        1476           0 :              write(logunit,*) trim(subname),' ERROR: orb_obliq = ',orb_obliq
        1477           0 :              write(logunit,*) trim(subname),' ERROR: orb_mvelp = ',orb_mvelp
        1478           0 :              write (msgstr, *) subname//' ERROR: invalid settings for orb_mode '//trim(orb_mode)
        1479             :           end if
        1480           0 :           call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
        1481           0 :           return  ! bail out
        1482             :        endif
        1483             :     else
        1484           0 :        write (msgstr, *) subname//' ERROR: invalid orb_mode '//trim(orb_mode)
        1485           0 :        call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
        1486           0 :        rc = ESMF_FAILURE
        1487           0 :        return  ! bail out
        1488             :     endif
        1489             :
        1490             :   end subroutine cam_orbital_init
        1491             :
        1492             :   !===============================================================================
        1493        4608 :   subroutine cam_orbital_update(clock, logunit,  mastertask, eccen, obliqr, lambm0, mvelpp, rc)
        1494             :
        1495             :     !----------------------------------------------------------
        1496             :     ! Update orbital settings
        1497             :     !----------------------------------------------------------
        1498             :
        1499             :     ! input/output variables
        1500             :     type(ESMF_Clock) , intent(in)    :: clock
        1501             :     integer          , intent(in)    :: logunit
        1502             :     logical          , intent(in)    :: mastertask
        1503             :     real(R8)         , intent(inout) :: eccen  ! orbital eccentricity
        1504             :     real(R8)         , intent(inout) :: obliqr ! Earths obliquity in rad
        1505             :     real(R8)         , intent(inout) :: lambm0 ! Mean long of perihelion at vernal equinox (radians)
        1506             :     real(R8)         , intent(inout) :: mvelpp ! moving vernal equinox longitude of perihelion plus pi (radians)
        1507             :     integer          , intent(out)   :: rc     ! output error
        1508             :
        1509             :     ! local variables
        1510             :     type(ESMF_Time)   :: CurrTime ! current time
        1511             :     integer           :: year     ! model year at current time
        1512             :     integer           :: orb_year ! orbital year for current orbital computation
        1513             :     character(len=CL) :: msgstr   ! temporary
        1514             :     logical, save     :: logprint = .true.
        1515             :     character(len=*) , parameter :: subname = "(cam_orbital_update)"
        1516             :     !-------------------------------------------
        1517             :
        1518        4608 :     rc = ESMF_SUCCESS
        1519             :
        1520        4608 :     if (trim(orb_mode) == trim(orb_variable_year)) then
        1521           0 :        call ESMF_ClockGet(clock, CurrTime=CurrTime, rc=rc)
        1522           0 :        if (chkerr(rc,__LINE__,u_FILE_u)) return
        1523           0 :        call ESMF_TimeGet(CurrTime, yy=year, rc=rc)
        1524           0 :        if (chkerr(rc,__LINE__,u_FILE_u)) return
        1525           0 :        orb_year = orb_iyear + (year - orb_iyear_align)
        1526             :     else
        1527        4608 :        orb_year = orb_iyear
        1528             :     end if
        1529        4608 :     if(.not. (logprint .and. mastertask)) then
        1530        4606 :        logprint = .false.
        1531             :     endif
        1532             :
        1533        4608 :     eccen = orb_eccen
        1534             :
        1535        4608 :     call shr_orb_params(orb_year, eccen, orb_obliq, orb_mvelp, obliqr, lambm0, mvelpp, logprint)
        1536        4608 :     logprint = .false.
        1537             :     if ( eccen  == SHR_ORB_UNDEF_REAL .or. obliqr == SHR_ORB_UNDEF_REAL .or. &
        1538        4608 :          mvelpp == SHR_ORB_UNDEF_REAL .or. lambm0 == SHR_ORB_UNDEF_REAL) then
        1539           0 :        write (msgstr, *) subname//' ERROR: orb params incorrect'
        1540           0 :        call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
        1541           0 :        return  ! bail out
        1542             :     endif
        1543             :
        1544       32256 :   end subroutine cam_orbital_update
        1545             :
        1546             :   !===============================================================================
        1547         768 :   subroutine cam_read_srfrest( gcomp, clock, rc )
        1548             :
        1549             :     ! input/output variables
        1550             :     type(ESMF_GridComp)             :: gcomp
        1551             :     type(ESMF_Clock), intent(inout) :: clock
        1552             :     integer         , intent(out)   :: rc
        1553             :
        1554             :     ! local variables
        1555             :     type(ESMF_State)                   :: importState, exportState
        1556             :     type(ESMF_Field)                   :: lfield
        1557             :     integer                            :: lrank
        1558             :     integer                            :: rcode        ! return error code
        1559             :     integer                            :: nf,n
        1560             :     type(file_desc_t)                  :: file
        1561             :     type(io_desc_t)                    :: iodesc
        1562             :     integer                            :: fieldCount
        1563         768 :     character(ESMF_MAXSTR),allocatable :: fieldNameList(:)
        1564             :     type(var_desc_t)                   :: varid
        1565         768 :     real(r8), pointer                  :: fldptr(:)
        1566         768 :     real(r8), pointer                  :: tmpptr(:)
        1567         768 :     real(r8), pointer                  :: fldptr2d(:,:)
        1568             :     type(ESMF_Time)                    :: currTime      ! time at previous interval
        1569             :     integer                            :: yr_spec       ! Current year
        1570             :     integer                            :: mon_spec      ! Current month
        1571             :     integer                            :: day_spec      ! Current day
        1572             :     integer                            :: sec_spec      ! Current time of day (sec)
        1573             :     character(len=256)                 :: fname_srf_cam ! surface restart filename
        1574             :     character(len=256)                 :: pname_srf_cam ! surface restart full pathname
        1575             :     character(len=PIO_MAX_NAME)        :: varname
        1576             :     integer                            :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fieldds
        1577             :     integer                            :: gridToFieldMap(1)  ! currently the size must equal 1 for rank 2 fieldds
        1578             :     integer                            :: lsize
        1579             :     character(len=8)                   :: cvalue
        1580             :     integer                            :: nloop
        1581             :     character(len=4)                   :: prefix
        1582             :     !-----------------------------------------------------------------------
        1583             :
        1584         768 :     rc = ESMF_SUCCESS
        1585             :
        1586             :     ! ------------------------------
        1587             :     ! Get surface restart dataset
        1588             :     ! ------------------------------
        1589             :
        1590         768 :     call ESMF_GridCompGet(gcomp, clock=clock, importState=importState, exportState=exportState, rc=rc)
        1591         768 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1592             :
        1593         768 :     call ESMF_ClockGet( clock, currTime=currTime, rc=rc )
        1594         768 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1595             :
        1596         768 :     call ESMF_TimeGet( currTime, yy=yr_spec, mm=mon_spec, dd=day_spec, s=sec_spec, rc=rc )
        1597         768 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1598             :
        1599             :     fname_srf_cam = interpret_filename_spec( rsfilename_spec_cam, case=cam_initfiles_get_caseid(), &
        1600         768 :          yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec )
        1601         768 :     pname_srf_cam = trim(cam_initfiles_get_restdir() )//fname_srf_cam
        1602         768 :     call getfil(pname_srf_cam, fname_srf_cam)
        1603             :
        1604             :     ! ------------------------------
        1605             :     ! Open restart file
        1606             :     ! ------------------------------
        1607             :
        1608         768 :     call cam_pio_openfile(File, fname_srf_cam, 0)
        1609        1536 :     call pio_initdecomp(pio_subsystem, pio_double, (/ngcols/), dof, iodesc)
        1610         768 :     call pio_seterrorhandling(File, pio_bcast_error)
        1611             :
        1612             :     ! ------------------------------
        1613             :     ! Read in import and export fields
        1614             :     ! ------------------------------
        1615             :
        1616        2304 :     do nloop = 1,2
        1617             :
        1618        1536 :        if (nloop == 1) then
        1619         768 :           prefix = 'x2a_' ! import fields
        1620         768 :           call ESMF_StateGet(importState, itemCount=fieldCount, rc=rc)
        1621         768 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1622        2304 :           allocate(fieldnameList(fieldCount))
        1623         768 :           call ESMF_StateGet(importState, itemNameList=fieldnameList, rc=rc)
        1624        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1625             :        else
        1626         768 :           prefix = 'a2x_' ! export fields
        1627         768 :           call ESMF_StateGet(exportState, itemCount=fieldCount, rc=rc)
        1628         768 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1629        2304 :           allocate(fieldnameList(fieldCount))
        1630         768 :           call ESMF_StateGet(exportState, itemNameList=fieldnameList, rc=rc)
        1631        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1632             :        end if
        1633             :
        1634             :        ! Loop over fields in import or export state
        1635       44544 :        do nf = 1,fieldCount
        1636             :
        1637       43008 :           if (trim(fieldnameList(nf)) == flds_scalar_name) CYCLE
        1638             :
        1639             :           ! Determine dimension of field
        1640       41472 :           if (nloop == 1) then
        1641       19968 :              call ESMF_StateGet(importState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
        1642       19968 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1643             :           else
        1644       21504 :              call ESMF_StateGet(exportState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
        1645       21504 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1646             :           end if
        1647       41472 :           call ESMF_FieldGet(lfield, rank=lrank, rc=rc)
        1648       41472 :           if (chkerr(rc,__LINE__,u_FILE_u)) return
        1649             :
        1650       84480 :           if (lrank == 1) then
        1651             :
        1652       36864 :              call ESMF_FieldGet(lfield, farrayPtr=fldptr, rc=rc)
        1653       36864 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1654       36864 :              varname = trim(prefix)//trim(fieldnameList(nf))
        1655       36864 :              rcode = pio_inq_varid(File,trim(varname) ,varid)
        1656       36864 :              if (rcode == pio_noerr) then
        1657       36864 :                 call pio_read_darray(File, varid, iodesc, fldptr, rcode)
        1658             :              else
        1659           0 :                 if (masterproc) then
        1660           0 :                    write(iulog,*)'cam_read_srfrest warning: field ',trim(varname),' is not on restart file'
        1661           0 :                    write(iulog,*)'for backwards compatibility will set it to 0'
        1662             :                 end if
        1663           0 :                 fldptr(:) = 0._r8
        1664             :              end if
        1665             :
        1666        4608 :           else if (lrank == 2) then
        1667             :
        1668             :              ! There is an output variable for each element of the undistributed dimension
        1669        4608 :              call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, gridToFieldMap=gridToFieldMap, rc=rc)
        1670        4608 :              if (chkerr(rc,__LINE__,u_FILE_u)) return
        1671        4608 :              call ESMF_FieldGet(lfield, farrayPtr=fldptr2d, rc=rc)
        1672        4608 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1673        4608 :              if (gridToFieldMap(1) == 1) then
        1674           0 :                 lsize = size(fldptr2d, dim=1)
        1675        4608 :              else if (gridToFieldMap(1) == 2) then
        1676        4608 :                 lsize = size(fldptr2d, dim=2)
        1677             :              end if
        1678             :
        1679       13824 :              allocate(tmpptr(lsize))
        1680       19968 :              do n = 1,ungriddedUBound(1)
        1681       15360 :                 write(cvalue,'(i0)') n
        1682       15360 :                 varname = trim(prefix)//trim(fieldnameList(nf))//trim(cvalue)
        1683       15360 :                 rcode = pio_inq_varid(File,trim(varname) ,varid)
        1684             :
        1685       15360 :                 if (rcode == pio_noerr) then
        1686       15360 :                    call pio_read_darray(File, varid, iodesc, tmpptr, rcode)
        1687             :                 else
        1688           0 :                    if (masterproc) then
        1689           0 :                       write(iulog,*)'cam_read_srfrest warning: field ',trim(varname),' is not on restart file'
        1690           0 :                       write(iulog,*)'for backwards compatibility will set it to 0'
        1691             :                    end if
        1692           0 :                    tmpptr(:) = 0._r8
        1693             :                 end if
        1694       19968 :                 if (gridToFieldMap(1) == 1) then
        1695           0 :                    fldptr2d(:,n) = tmpptr(:)
        1696       15360 :                 else if (gridToFieldMap(1) == 2) then
        1697     1959360 :                    fldptr2d(n,:) = tmpptr(:)
        1698             :                 end if
        1699             :              end do
        1700        4608 :              deallocate(tmpptr)
        1701             :
        1702             :           end if ! end lrank if block
        1703             :        end do
        1704        2304 :        deallocate(fieldnameList)
        1705             :     end do
        1706             :
        1707             :     ! ------------------------------
        1708             :     ! Close file
        1709             :     ! ------------------------------
        1710             :
        1711         768 :     call pio_seterrorhandling(File, pio_internal_error)
        1712         768 :     call pio_freedecomp(File, iodesc)
        1713         768 :     call cam_pio_closefile(File)
        1714             :
        1715        6144 :   end subroutine cam_read_srfrest
        1716             :
        1717             :   !===========================================================================================
        1718        1536 :   subroutine cam_write_srfrest( gcomp, yr_spec, mon_spec, day_spec, sec_spec, rc )
        1719             :
        1720             :     ! Arguments
        1721             :     type(ESMF_GridComp)   :: gcomp
        1722             :     integer , intent(in)  :: yr_spec  ! Simulation year
        1723             :     integer , intent(in)  :: mon_spec ! Simulation month
        1724             :     integer , intent(in)  :: day_spec ! Simulation day
        1725             :     integer , intent(in)  :: sec_spec ! Seconds into current simulation day
        1726             :     integer , intent(out) :: rc       ! error code
        1727             :
        1728             :     ! Local variables
        1729             :     type(ESMF_State)                   :: importState, exportState
        1730             :     type(ESMF_Field)                   :: lField
        1731             :     integer                            :: lrank
        1732             :     integer                            :: rcode        ! return error code
        1733             :     integer                            :: dimid(1), nf, n
        1734             :     type(file_desc_t)                  :: file
        1735             :     type(io_desc_t)                    :: iodesc
        1736             :     integer                            :: fieldCount
        1737        1536 :     character(ESMF_MAXSTR),allocatable :: fieldnameList(:)
        1738             :     type(var_desc_t)                   :: varid
        1739        1536 :     real(r8), pointer                  :: fldptr1d(:)
        1740        1536 :     real(r8), pointer                  :: fldptr2d(:,:)
        1741             :     character(len=PIO_MAX_NAME)        :: varname
        1742             :     character(len=256)                 :: fname_srf_cam      ! surface restart filename
        1743             :     character(len=8)                   :: cvalue
        1744             :     integer                            :: nloop
        1745             :     character(len=4)                   :: prefix
        1746             :     integer                            :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fieldds
        1747             :     integer                            :: gridToFieldMap(1)  ! currently the size must equal 1 for rank 2 fieldds
        1748             :     !-----------------------------------------------------------------------
        1749             :
        1750        1536 :     rc = ESMF_SUCCESS
        1751             :
        1752             :     ! ----------------------
        1753             :     ! Get import and export states
        1754             :     ! ----------------------
        1755             :
        1756        1536 :     call ESMF_GridCompGet(gcomp, importState=importState, exportState=exportState, rc=rc)
        1757        1536 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1758             :
        1759             :     ! ----------------------
        1760             :     ! Open surface restart dataset
        1761             :     ! ----------------------
        1762             :
        1763             :     fname_srf_cam = interpret_filename_spec( rsfilename_spec_cam, &
        1764        1536 :          yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec )
        1765             :
        1766        1536 :     call cam_pio_createfile(File, fname_srf_cam, 0)
        1767        3072 :     call pio_initdecomp(pio_subsystem, pio_double, (/ngcols/), dof, iodesc)
        1768             :
        1769             :     ! ----------------------
        1770             :     ! Define dimensions
        1771             :     ! ----------------------
        1772             :
        1773        1536 :     rcode = pio_def_dim(File, 'x2a_nx', ngcols, dimid(1))
        1774        1536 :     rcode = pio_def_dim(File, 'a2x_nx', ngcols, dimid(1))
        1775             :
        1776             :     ! ----------------------
        1777             :     ! Define import and export variable ids
        1778             :     ! ----------------------
        1779             :
        1780        4608 :     do nloop = 1,2
        1781             :
        1782        3072 :        if (nloop == 1) then
        1783        1536 :           prefix = 'x2a_' ! import fields
        1784        1536 :           call ESMF_StateGet(importState, itemCount=fieldCount, rc=rc)
        1785        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1786        4608 :           allocate(fieldNameList(fieldCount))
        1787        1536 :           call ESMF_StateGet(importState, itemNameList=fieldNameList, rc=rc)
        1788        3072 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1789             :        else
        1790        1536 :           prefix = 'a2x_' ! export fields
        1791        1536 :           call ESMF_StateGet(exportState, itemCount=fieldCount, rc=rc)
        1792        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1793        4608 :           allocate(fieldNameList(fieldCount))
        1794        1536 :           call ESMF_StateGet(exportState, itemNameList=fieldNameList, rc=rc)
        1795        3072 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1796             :        end if
        1797             :
        1798       89088 :        do nf = 1,fieldCount
        1799             :
        1800       86016 :           if (trim(fieldNameList(nf)) == flds_scalar_name) CYCLE
        1801             :
        1802       82944 :           if (nloop == 1) then
        1803       39936 :              call ESMF_StateGet(importState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
        1804       39936 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1805             :           else
        1806       43008 :              call ESMF_StateGet(exportState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
        1807       43008 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1808             :           end if
        1809       82944 :           call ESMF_FieldGet(lfield, rank=lrank, rc=rc)
        1810       82944 :           if (chkerr(rc,__LINE__,u_FILE_u)) return
        1811             :
        1812      168960 :           if (lrank == 1) then
        1813             :
        1814       73728 :              varname = trim(prefix)//trim(fieldNameList(nf))
        1815       73728 :              rcode = pio_def_var(File,trim(varname), PIO_DOUBLE, dimid, varid)
        1816       73728 :              rcode = pio_put_att(File, varid, "_fillvalue", fillvalue)
        1817             :
        1818        9216 :           else if (lrank == 2) then
        1819             :
        1820             :              ! Determine the size of the ungridded dimension and the
        1821             :              ! index where the undistributed dimension is located
        1822        9216 :              call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, gridToFieldMap=gridToFieldMap, rc=rc)
        1823        9216 :              if (chkerr(rc,__LINE__,u_FILE_u)) return
        1824             :
        1825             :              ! Output for each ungriddedUbound index
        1826       39936 :              do n = 1,ungriddedUBound(1)
        1827       30720 :                 write(cvalue,'(i0)') n
        1828       30720 :                 varname = trim(prefix)//trim(fieldNameList(nf))//trim(cvalue)
        1829       30720 :                 rcode = pio_def_var(File,trim(varname), PIO_DOUBLE, dimid, varid)
        1830       39936 :                 rcode = pio_put_att(File, varid, "_fillvalue", fillvalue)
        1831             :              end do
        1832             :
        1833             :           end if ! end if-block over rank size
        1834             :
        1835             :        end do ! end loop over import or export fieldsfields
        1836        4608 :        deallocate(fieldNameList)
        1837             :     end do
        1838             :
        1839             :     ! ----------------------
        1840             :     ! End definition phase
        1841             :     ! ----------------------
        1842             :
        1843        1536 :     rcode = pio_enddef(File)  ! don't check return code, might be enddef already
        1844             :
        1845             :     ! ----------------------
        1846             :     ! Write the restart data for the import fields and export fields
        1847             :     ! ----------------------
        1848             :
        1849        4608 :     do nloop = 1,2
        1850             :
        1851        3072 :        if (nloop == 1) then
        1852        1536 :           prefix = 'x2a_' ! import fields
        1853        1536 :           call ESMF_StateGet(importState, itemCount=fieldCount, rc=rc)
        1854        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1855        4608 :           allocate(fieldNameList(fieldCount))
        1856        1536 :           call ESMF_StateGet(importState, itemNameList=fieldNameList, rc=rc)
        1857        3072 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1858             :        else
        1859        1536 :           prefix = 'a2x_' ! export fields
        1860        1536 :           call ESMF_StateGet(exportState, itemCount=fieldCount, rc=rc)
        1861        1536 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1862        4608 :           allocate(fieldNameList(fieldCount))
        1863        1536 :           call ESMF_StateGet(exportState, itemNameList=fieldNameList, rc=rc)
        1864        3072 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1865             :        end if
        1866             :
        1867       89088 :        do nf = 1,fieldCount
        1868             :
        1869       86016 :           if (trim(fieldNameList(nf)) == flds_scalar_name) CYCLE
        1870             :
        1871       82944 :           if (nloop == 1) then
        1872       39936 :              call ESMF_StateGet(importState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
        1873       39936 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1874             :           else
        1875       43008 :              call ESMF_StateGet(exportState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
        1876       43008 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1877             :           end if
        1878       82944 :           call ESMF_FieldGet(lfield, rank=lrank, rc=rc)
        1879       82944 :           if (chkerr(rc,__LINE__,u_FILE_u)) return
        1880             :
        1881      168960 :           if (lrank == 1) then
        1882             :
        1883       73728 :              varname = trim(prefix)//trim(fieldNameList(nf))
        1884       73728 :              rcode = pio_inq_varid(File, trim(varname), varid)
        1885       73728 :              call ESMF_FieldGet(lfield, farrayPtr=fldptr1d, rc=rc)
        1886       73728 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1887       73728 :              call pio_write_darray(File, varid, iodesc, fldptr1d, rcode)
        1888             :
        1889        9216 :           else if (lrank == 2) then
        1890             :
        1891             :              ! There is an output variable for each element of the undistributed dimension
        1892        9216 :              call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc)
        1893        9216 :              if (chkerr(rc,__LINE__,u_FILE_u)) return
        1894        9216 :              call ESMF_FieldGet(lfield, farrayPtr=fldptr2d, rc=rc)
        1895        9216 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1896             :
        1897       39936 :              do n = 1,ungriddedUBound(1)
        1898       30720 :                 write(cvalue,'(i0)') n
        1899       30720 :                 varname = trim(prefix)//trim(fieldNameList(nf))//trim(cvalue)
        1900       30720 :                 rcode = pio_inq_varid(File, trim(varname), varid)
        1901       39936 :                 if (gridToFieldMap(1) == 1) then
        1902           0 :                    call pio_write_darray(File, varid, iodesc, fldptr2d(:,n), rcode, fillval=fillvalue)
        1903       30720 :                 else if (gridToFieldMap(1) == 2) then
        1904       30720 :                    call pio_write_darray(File, varid, iodesc, fldptr2d(n,:), rcode, fillval=fillvalue)
        1905             :                 end if
        1906             :              end do
        1907             :
        1908             :           end if
        1909             :        end do ! end loop over import or export fields
        1910        4608 :        deallocate(fieldNameList)
        1911             :
        1912             :     end do ! end of nloop
        1913             :
        1914             :     ! ----------------------
        1915             :     ! close the file
        1916             :     ! ----------------------
        1917             :
        1918        1536 :     call pio_freedecomp(File,iodesc)
        1919        1536 :     call cam_pio_closefile(File)
        1920             :
        1921        3072 :   end subroutine cam_write_srfrest
        1922             :
        1923             :   !===============================================================================
        1924           0 :   subroutine cam_write_clockrest( clock, yr_spec, mon_spec, day_spec, sec_spec, rc )
        1925             :
        1926             :     ! When there is no mediator, the driver needs to have restart information to start up
        1927             :     ! This routine writes this out and the driver reads it back in on a restart run
        1928             :
        1929             :     ! Arguments
        1930             :     type(ESMF_Clock) , intent(in)  :: clock
        1931             :     integer          , intent(in)  :: yr_spec  ! Simulation year
        1932             :     integer          , intent(in)  :: mon_spec ! Simulation month
        1933             :     integer          , intent(in)  :: day_spec ! Simulation day
        1934             :     integer          , intent(in)  :: sec_spec ! Seconds into current simulation day
        1935             :     integer          , intent(out) :: rc       ! error code
        1936             :
        1937             :     ! Local variables
        1938             :     type(ESMF_Time)   :: startTime
        1939             :     type(ESMF_Time)   :: currTime
        1940             :     type(ESMF_Time)   :: nextTime
        1941             :     integer           :: unitn
        1942             :     type(file_desc_t) :: File
        1943             :     integer           :: start_ymd
        1944             :     integer           :: start_tod
        1945             :     integer           :: curr_ymd
        1946             :     integer           :: curr_tod
        1947             :     integer           :: yy,mm,dd  ! Temporaries for time query
        1948             :     type(var_desc_t)  :: varid_start_ymd
        1949             :     type(var_desc_t)  :: varid_start_tod
        1950             :     type(var_desc_t)  :: varid_curr_ymd
        1951             :     type(var_desc_t)  :: varid_curr_tod
        1952             :     integer           :: rcode
        1953             :     character(ESMF_MAXSTR)  :: restart_pfile
        1954             :     character(ESMF_MAXSTR)  :: restart_file
        1955             :     !-----------------------------------------------------------------------
        1956             :
        1957           0 :     rc = ESMF_SUCCESS
        1958             :
        1959             :     ! Get properties from clock
        1960           0 :     call ESMF_ClockGet( clock, startTime=startTime, currTime=currTime, rc=rc)
        1961           0 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1962           0 :     call ESMF_ClockGetNextTime(clock, nextTime=nextTime, rc=rc)
        1963           0 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1964             :
        1965           0 :     call ESMF_TimeGet( startTime, yy=yy, mm=mm, dd=dd, s=start_tod, rc=rc )
        1966           0 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1967           0 :     call shr_cal_ymd2date(yy,mm,dd,start_ymd)
        1968             :
        1969           0 :     call ESMF_TimeGet( nextTime, yy=yy, mm=mm, dd=dd, s=curr_tod, rc=rc )
        1970             :    !call ESMF_TimeGet( currTime, yy=yy, mm=mm, dd=dd, s=curr_tod, rc=rc )
        1971           0 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        1972           0 :     call shr_cal_ymd2date(yy,mm,dd,curr_ymd)
        1973             :
        1974             :     ! Open clock info restart dataset
        1975             :     restart_file = interpret_filename_spec( '%c.cpl.r.%y-%m-%d-%s.nc', &
        1976           0 :          yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec )
        1977             :
        1978           0 :     if (masterproc) then
        1979           0 :        write(iulog,*) " In this configuration, there is no mediator"
        1980           0 :        write(iulog,*) " Normally, the mediator restart file provides the restart time info"
        1981           0 :        write(iulog,*) " In this case, CAM will create the rpointer.cpl and cpl restart file"
        1982           0 :        write(iulog,*) " containing this information"
        1983           0 :        write(iulog,*) " writing rpointer file for driver clock info, rpointer.cpl"
        1984           0 :        write(iulog,*) " writing restart clock info for driver= "//trim(restart_file)
        1985           0 :        open(newunit=unitn, file='rpointer.cpl', form='FORMATTED')
        1986           0 :        write(unitn,'(a)') trim(restart_file)
        1987           0 :        close(unitn)
        1988             :     endif
        1989             :
        1990           0 :     call cam_pio_createfile(File, trim(restart_file), 0)
        1991           0 :     rcode = pio_def_var(File, 'start_ymd', PIO_INT, varid_start_ymd)
        1992           0 :     rcode = pio_def_var(File, 'start_tod', PIO_INT, varid_start_tod)
        1993           0 :     rcode = pio_def_var(File, 'curr_ymd' , PIO_INT, varid_curr_ymd)
        1994           0 :     rcode = pio_def_var(File, 'curr_tod' , PIO_INT, varid_curr_tod)
        1995           0 :     rcode = pio_enddef(File)
        1996           0 :     rcode = pio_put_var(File, varid_start_ymd, start_ymd)
        1997           0 :     rcode = pio_put_var(File, varid_start_tod, start_tod)
        1998           0 :     rcode = pio_put_var(File, varid_curr_ymd, curr_ymd)
        1999           0 :     rcode = pio_put_var(File, varid_curr_tod, curr_tod)
        2000           0 :     call cam_pio_closefile(File)
        2001             :
        2002           0 :   end subroutine cam_write_clockrest
        2003             :
        2004             :   !===============================================================================
        2005           0 :   subroutine cam_set_mesh_for_single_column(scol_lon, scol_lat, mesh, rc)
        2006             :
        2007             :     ! Generate a mesh for single column
        2008             :     use netcdf
        2009             :
        2010             :     ! input/output variables
        2011             :     real(r8)        , intent(in)  :: scol_lon
        2012             :     real(r8)        , intent(in)  :: scol_lat
        2013             :     type(ESMF_Mesh) , intent(out) :: mesh
        2014             :     integer         , intent(out) :: rc
        2015             :
        2016             :     ! local variables
        2017             :     type(ESMF_Grid)        :: lgrid
        2018             :     integer                :: maxIndex(2)
        2019             :     real(r8)               :: mincornerCoord(2)
        2020             :     real(r8)               :: maxcornerCoord(2)
        2021             :     character(len=*), parameter :: subname= ' (lnd_set_mesh_for_single_column) '
        2022             :     !-------------------------------------------------------------------------------
        2023             :
        2024           0 :     rc = ESMF_SUCCESS
        2025             :
        2026             :     ! Use center and come up with arbitrary area delta lon and lat = .1 degree
        2027           0 :     maxIndex(1)       = 1                ! number of lons
        2028           0 :     maxIndex(2)       = 1                ! number of lats
        2029           0 :     mincornerCoord(1) = scol_lon - .1_r8 ! min lon
        2030           0 :     mincornerCoord(2) = scol_lat - .1_r8 ! min lat
        2031           0 :     maxcornerCoord(1) = scol_lon + .1_r8 ! max lon
        2032           0 :     maxcornerCoord(2) = scol_lat + .1_r8 ! max lat
        2033             :
        2034             :     ! create the ESMF grid
        2035             :     lgrid = ESMF_GridCreateNoPeriDimUfrm (maxindex=maxindex, &
        2036             :          mincornercoord=mincornercoord, maxcornercoord= maxcornercoord, &
        2037           0 :          staggerloclist=(/ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER/), rc=rc)
        2038           0 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        2039             :
        2040             :     ! create the mesh from the lgrid
        2041           0 :     mesh = ESMF_MeshCreate(lgrid, rc=rc)
        2042           0 :     if (ChkErr(rc,__LINE__,u_FILE_u)) return
        2043             :
        2044           0 :   end subroutine cam_set_mesh_for_single_column
        2045             :
        2046             :   !===============================================================================
        2047             :   subroutine cam_pio_checkerr(ierror, description)
        2048             :     use pio, only : PIO_NOERR
        2049             :     integer     , intent(in) :: ierror
        2050             :     character(*), intent(in) :: description
        2051             :     if (ierror /= PIO_NOERR) then
        2052             :        write (*,'(6a)') 'ERROR ', trim(description)
        2053             :        call shr_sys_abort()
        2054             :     endif
        2055             :   end subroutine cam_pio_checkerr
        2056             :
        2057             : end module atm_comp_nuopc

Generated by: LCOV version 1.14