LCOV - code coverage report
Current view: top level - cpl/nuopc - atm_comp_nuopc.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 645 783 82.4 %
Date: 2024-12-17 17:57:11 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           0 :        perpetual_run = .true.
     632           0 :        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       47616 :        do n=1, fieldCount
     861       46080 :           call ESMF_StateGet(importState, itemName=fieldNameList(n), field=field, rc=rc)
     862       46080 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
     863             : 
     864       46080 :           atCorrectTime = NUOPC_IsAtTime(field, currTime, rc=rc)
     865       46080 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
     866             : 
     867       93696 :           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       47616 :        do n=1, fieldCount
     943       46080 :           call ESMF_StateGet(exportState, itemName=fieldNameList(n), field=field, rc=rc)
     944       46080 :           if (ChkErr(rc,__LINE__,u_FILE_u)) return
     945             : 
     946       46080 :           call NUOPC_SetAttribute(field, name="Updated", value="true", rc=rc)
     947       93696 :           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      368640 :        call cam_orbital_update(clock, iulog, masterproc, eccen, obliqr, lambm0, mvelpp, rc)
    1078      368640 :        if (ChkErr(rc,__LINE__,u_FILE_u)) return
    1079      368640 :        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        3072 :        orb_obliq = SHR_ORB_UNDEF_REAL
    1455        3072 :        orb_eccen = SHR_ORB_UNDEF_REAL
    1456        3072 :        orb_mvelp = SHR_ORB_UNDEF_REAL
    1457        3072 :        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           0 :     elseif (trim(orb_mode) == trim(orb_fixed_parameters)) then
    1467             :        !-- force orb_iyear to undef to make sure shr_orb_params works properly
    1468           0 :        orb_iyear = SHR_ORB_UNDEF_INT
    1469           0 :        orb_iyear_align = SHR_ORB_UNDEF_INT
    1470             :        if (orb_eccen == SHR_ORB_UNDEF_REAL .or. &
    1471           0 :            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      371712 :   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      371712 :     rc = ESMF_SUCCESS
    1519             : 
    1520      371712 :     if (trim(orb_mode) == trim(orb_variable_year)) then
    1521      371712 :        call ESMF_ClockGet(clock, CurrTime=CurrTime, rc=rc)
    1522      371712 :        if (chkerr(rc,__LINE__,u_FILE_u)) return
    1523      371712 :        call ESMF_TimeGet(CurrTime, yy=year, rc=rc)
    1524      371712 :        if (chkerr(rc,__LINE__,u_FILE_u)) return
    1525      371712 :        orb_year = orb_iyear + (year - orb_iyear_align)
    1526             :     else
    1527           0 :        orb_year = orb_iyear
    1528             :     end if
    1529      371712 :     if(.not. (logprint .and. mastertask)) then
    1530      371710 :        logprint = .false.
    1531             :     endif
    1532             : 
    1533      371712 :     eccen = orb_eccen
    1534             : 
    1535      371712 :     call shr_orb_params(orb_year, eccen, orb_obliq, orb_mvelp, obliqr, lambm0, mvelpp, logprint)
    1536      371712 :     logprint = .false.
    1537             :     if ( eccen  == SHR_ORB_UNDEF_REAL .or. obliqr == SHR_ORB_UNDEF_REAL .or. &
    1538      371712 :          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     2601984 :   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       46848 :        do nf = 1,fieldCount
    1636             : 
    1637       45312 :           if (trim(fieldnameList(nf)) == flds_scalar_name) CYCLE
    1638             : 
    1639             :           ! Determine dimension of field
    1640       43776 :           if (nloop == 1) then
    1641       21504 :              call ESMF_StateGet(importState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
    1642       21504 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
    1643             :           else
    1644       22272 :              call ESMF_StateGet(exportState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
    1645       22272 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
    1646             :           end if
    1647       43776 :           call ESMF_FieldGet(lfield, rank=lrank, rc=rc)
    1648       43776 :           if (chkerr(rc,__LINE__,u_FILE_u)) return
    1649             : 
    1650       89088 :           if (lrank == 1) then
    1651             : 
    1652       39168 :              call ESMF_FieldGet(lfield, farrayPtr=fldptr, rc=rc)
    1653       39168 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
    1654       39168 :              varname = trim(prefix)//trim(fieldnameList(nf))
    1655       39168 :              rcode = pio_inq_varid(File,trim(varname) ,varid)
    1656       39168 :              if (rcode == pio_noerr) then
    1657       39168 :                 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       93696 :        do nf = 1,fieldCount
    1799             : 
    1800       90624 :           if (trim(fieldNameList(nf)) == flds_scalar_name) CYCLE
    1801             : 
    1802       87552 :           if (nloop == 1) then
    1803       43008 :              call ESMF_StateGet(importState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
    1804       43008 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
    1805             :           else
    1806       44544 :              call ESMF_StateGet(exportState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
    1807       44544 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
    1808             :           end if
    1809       87552 :           call ESMF_FieldGet(lfield, rank=lrank, rc=rc)
    1810       87552 :           if (chkerr(rc,__LINE__,u_FILE_u)) return
    1811             : 
    1812      178176 :           if (lrank == 1) then
    1813             : 
    1814       78336 :              varname = trim(prefix)//trim(fieldNameList(nf))
    1815       78336 :              rcode = pio_def_var(File,trim(varname), PIO_DOUBLE, dimid, varid)
    1816       78336 :              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       93696 :        do nf = 1,fieldCount
    1868             : 
    1869       90624 :           if (trim(fieldNameList(nf)) == flds_scalar_name) CYCLE
    1870             : 
    1871       87552 :           if (nloop == 1) then
    1872       43008 :              call ESMF_StateGet(importState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
    1873       43008 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
    1874             :           else
    1875       44544 :              call ESMF_StateGet(exportState, itemName=trim(fieldnameList(nf)), field=lfield, rc=rc)
    1876       44544 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
    1877             :           end if
    1878       87552 :           call ESMF_FieldGet(lfield, rank=lrank, rc=rc)
    1879       87552 :           if (chkerr(rc,__LINE__,u_FILE_u)) return
    1880             : 
    1881      178176 :           if (lrank == 1) then
    1882             : 
    1883       78336 :              varname = trim(prefix)//trim(fieldNameList(nf))
    1884       78336 :              rcode = pio_inq_varid(File, trim(varname), varid)
    1885       78336 :              call ESMF_FieldGet(lfield, farrayPtr=fldptr1d, rc=rc)
    1886       78336 :              if (ChkErr(rc,__LINE__,u_FILE_u)) return
    1887       78336 :              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