LCOV - code coverage report
Current view: | top level - control - cam_comp.F90 (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 101 | 103 | 98.1 %
Date: | 2025-01-13 21:54:50 |  | Functions: | 6 | 6 | 100.0 %

              Line data    Source code
           1             : module cam_comp
           2             : !-----------------------------------------------------------------------
           3             : !
           4             : ! Community Atmosphere Model (CAM) component interfaces.
           5             : !
           6             : ! This interface layer is CAM specific, i.e., it deals entirely with CAM
           7             : ! specific data structures.  It is the layer above this, either atm_comp_mct
           8             : ! or atm_comp_nuopc, which translates between CAM and either MCT or NUOPC
           9             : ! data structures in order to interface with the driver/coupler.
          10             : !
          11             : !-----------------------------------------------------------------------
          12             :
          13             : use shr_kind_mod,      only: r8 => SHR_KIND_R8, cl=>SHR_KIND_CL, cs=>SHR_KIND_CS
          14             : use shr_sys_mod,       only: shr_sys_flush
          15             :
          16             : use spmd_utils,        only: masterproc, mpicom
          17             : use cam_control_mod,   only: cam_ctrl_init, cam_ctrl_set_orbit
          18             : use runtime_opts,      only: read_namelist
          19             : use time_manager,      only: timemgr_init, get_nstep
          20             : use camsrfexch,        only: cam_out_t, cam_in_t
          21             : use ppgrid,            only: begchunk, endchunk
          22             : use physics_types,     only: physics_state, physics_tend
          23             : use dyn_comp,          only: dyn_import_t, dyn_export_t
          24             :
          25             : use physics_buffer,    only: physics_buffer_desc
          26             : use offline_driver,    only: offline_driver_init, offline_driver_dorun, offline_driver_run
          27             :
          28             : use perf_mod
          29             : use cam_logfile,       only: iulog
          30             : use cam_abortutils,    only: endrun
          31             :
          32             : implicit none
          33             : private
          34             :
          35             : public cam_init      ! First phase of CAM initialization
          36             : public cam_run1      ! CAM run method phase 1
          37             : public cam_run2      ! CAM run method phase 2
          38             : public cam_run3      ! CAM run method phase 3
          39             : public cam_run4      ! CAM run method phase 4
          40             : public cam_final     ! CAM Finalization
          41             :
          42             : type(dyn_import_t) :: dyn_in   ! Dynamics import container
          43             : type(dyn_export_t) :: dyn_out  ! Dynamics export container
          44             :
          45             : type(physics_state),       pointer :: phys_state(:) => null()
          46             : type(physics_tend ),       pointer :: phys_tend(:) => null()
          47             : type(physics_buffer_desc), pointer :: pbuf2d(:,:) => null()
          48             :
          49             : real(r8) :: dtime_phys         ! Time step for physics tendencies.  Set by call to
          50             :                                ! stepon_run1, then passed to the phys_run*
          51             :
          52             : !-----------------------------------------------------------------------
          53             : contains
          54             : !-----------------------------------------------------------------------
          55             :
          56        3072 : subroutine cam_init(                                             &
          57        1536 :    caseid, ctitle, model_doi_url,                                &
          58             :    initial_run_in, restart_run_in, branch_run_in, post_assim_in, &
          59        1536 :    calendar, brnch_retain_casename, aqua_planet,                 &
          60             :    single_column, scmlat, scmlon,                                &
          61             :    eccen, obliqr, lambm0, mvelpp,                                &
          62             :    perpetual_run, perpetual_ymd,                                 &
          63             :    dtime, start_ymd, start_tod, ref_ymd, ref_tod,                &
          64             :    stop_ymd, stop_tod, curr_ymd, curr_tod,                       &
          65             :    cam_out, cam_in)
          66             :
          67             :    !-----------------------------------------------------------------------
          68             :    !
          69             :    ! CAM component initialization.
          70             :    !
          71             :    !-----------------------------------------------------------------------
          72             :
          73             :    use cam_initfiles,    only: cam_initfiles_open
          74             :    use dyn_grid,         only: dyn_grid_init
          75             :    use phys_grid,        only: phys_grid_init
          76             :    use physpkg,          only: phys_register, phys_init
          77             :    use chem_surfvals,    only: chem_surfvals_init
          78             :    use dyn_comp,         only: dyn_init
          79             :    use cam_restart,      only: cam_read_restart
          80             :    use stepon,           only: stepon_init
          81             :    use ionosphere_interface, only: ionosphere_init
          82             :    use camsrfexch,       only: hub2atm_alloc, atm2hub_alloc
          83             :    use cam_history,      only: intht, write_camiop
          84             :    use history_scam,     only: scm_intht, initialize_iop_history
          85             :    use cam_pio_utils,    only: init_pio_subsystem
          86             :    use cam_instance,     only: inst_suffix
          87             :    use cam_snapshot_common, only: cam_snapshot_deactivate
          88             :    use air_composition,  only: air_composition_init
          89             :    use phys_grid_ctem,   only: phys_grid_ctem_reg
          90             :
          91             :    ! Arguments
          92             :    character(len=cl), intent(in) :: caseid                ! case ID
          93             :    character(len=cl), intent(in) :: ctitle                ! case title
          94             :    character(len=cl), intent(in) :: model_doi_url         ! CESM model DOI
          95             :    logical,           intent(in) :: initial_run_in        ! true => inital run
          96             :    logical,           intent(in) :: restart_run_in        ! true => restart run
          97             :    logical,           intent(in) :: branch_run_in         ! true => branch run
          98             :    logical,           intent(in) :: post_assim_in         ! true => resume mode
          99             :    character(len=cs), intent(in) :: calendar              ! Calendar type
         100             :    logical,           intent(in) :: brnch_retain_casename ! Flag to allow a branch to use the same
         101             :                                                           ! caseid as the run being branched from.
         102             :    logical,           intent(in) :: aqua_planet           ! Flag to run model in "aqua planet" mode
         103             :
         104             :    logical,           intent(in) :: single_column
         105             :    real(r8),          intent(in) :: scmlat
         106             :    real(r8),          intent(in) :: scmlon
         107             :
         108             :    real(r8),          intent(in) :: eccen
         109             :    real(r8),          intent(in) :: obliqr
         110             :    real(r8),          intent(in) :: lambm0
         111             :    real(r8),          intent(in) :: mvelpp
         112             :
         113             :    logical,           intent(in) :: perpetual_run    ! true => perpetual mode enabled
         114             :    integer,           intent(in) :: perpetual_ymd    ! Perpetual date (YYYYMMDD)
         115             :    integer,           intent(in) :: dtime                 ! model timestep (sec)
         116             :
         117             :    integer,           intent(in) :: start_ymd             ! Start date (YYYYMMDD)
         118             :    integer,           intent(in) :: start_tod             ! Start time of day (sec)
         119             :    integer,           intent(in) :: curr_ymd              ! Start date (YYYYMMDD)
         120             :    integer,           intent(in) :: curr_tod              ! Start time of day (sec)
         121             :    integer,           intent(in) :: stop_ymd              ! Stop date (YYYYMMDD)
         122             :    integer,           intent(in) :: stop_tod              ! Stop time of day (sec)
         123             :    integer,           intent(in) :: ref_ymd               ! Reference date (YYYYMMDD)
         124             :    integer,           intent(in) :: ref_tod               ! Reference time of day (sec)
         125             :
         126             :    type(cam_out_t),   pointer    :: cam_out(:)       ! Output from CAM to surface
         127             :    type(cam_in_t) ,   pointer    :: cam_in(:)        ! Merged input state to CAM
         128             :
         129             :    ! Local variables
         130             :    character(len=cs) :: filein      ! Input namelist filename
         131             :    !-----------------------------------------------------------------------
         132             :
         133        1536 :    call init_pio_subsystem()
         134             :
         135             :    ! Initializations using data passed from coupler.
         136             :    call cam_ctrl_init(               &
         137             :       caseid_in=caseid,              &
         138             :       ctitle_in=ctitle,              &
         139             :       initial_run_in=initial_run_in, &
         140             :       restart_run_in=restart_run_in, &
         141             :       branch_run_in=branch_run_in,   &
         142             :       post_assim_in=post_assim_in,   &
         143             :       aqua_planet_in=aqua_planet,    &
         144        1536 :       brnch_retain_casename_in=brnch_retain_casename)
         145             :
         146        1536 :    call cam_ctrl_set_orbit(eccen, obliqr, lambm0, mvelpp)
         147             :
         148             :    call timemgr_init( &
         149             :       dtime, calendar, start_ymd, start_tod, ref_ymd,  &
         150             :       ref_tod, stop_ymd, stop_tod, curr_ymd, curr_tod, &
         151        1536 :       perpetual_run, perpetual_ymd, initial_run_in)
         152             :
         153             :    ! Read CAM namelists.
         154        1536 :    filein = "atm_in" // trim(inst_suffix)
         155        1536 :    call read_namelist(filein, single_column, scmlat, scmlon)
         156             :
         157             :    ! Open initial or restart file, and topo file if specified.
         158        1536 :    call cam_initfiles_open()
         159             :
         160             :    ! Initialize grids and dynamics grid decomposition
         161        1536 :    call dyn_grid_init()
         162             :
         163             :    ! Initialize physics grid decomposition
         164        1536 :    call phys_grid_init()
         165             :
         166             :    ! Register zonal average grid for phys TEM diagnostics
         167        1536 :    call phys_grid_ctem_reg()
         168             :
         169             :    ! Register advected tracers and physics buffer fields
         170        1536 :    call phys_register ()
         171             :
         172             :    ! Initialize ghg surface values before default initial distributions
         173             :    ! are set in dyn_init
         174        1536 :    call chem_surfvals_init()
         175             :
         176        1536 :    call air_composition_init()
         177             :    ! initialize ionosphere
         178        1536 :    call ionosphere_init()
         179             :
         180        1536 :    if (initial_run_in) then
         181             :
         182         768 :       call dyn_init(dyn_in, dyn_out)
         183             :
         184             :       ! Allocate and setup surface exchange data
         185         768 :       call atm2hub_alloc(cam_out)
         186         768 :       call hub2atm_alloc(cam_in)
         187             :
         188             :    else
         189             :
         190         768 :       call cam_read_restart(cam_in, cam_out, dyn_in, dyn_out, pbuf2d, stop_ymd, stop_tod)
         191             :
         192             :    end if
         193             :
         194        1536 :    if (write_camiop) call initialize_iop_history()
         195             :
         196        1536 :    call phys_init( phys_state, phys_tend, pbuf2d, cam_in, cam_out )
         197             :
         198        1536 :    call stepon_init(dyn_in, dyn_out)
         199             :
         200        1536 :    call offline_driver_init()
         201             :
         202        1536 :    if (single_column) call scm_intht()
         203        1536 :    call intht(model_doi_url)
         204             :
         205        1536 :    call cam_snapshot_deactivate()
         206             :
         207        1536 : end subroutine cam_init
         208             :
         209             : !
         210             : !-----------------------------------------------------------------------
         211             : !
         212      741888 : subroutine cam_run1(cam_in, cam_out)
         213             : !-----------------------------------------------------------------------
         214             : !
         215             : ! Purpose:   First phase of atmosphere model run method.
         216             : !            Runs first phase of dynamics and first phase of
         217             : !            physics (before surface model updates).
         218             : !
         219             : !-----------------------------------------------------------------------
         220             :
         221        1536 :    use physpkg,          only: phys_run1
         222             :    use stepon,           only: stepon_run1
         223             :    use ionosphere_interface,only: ionosphere_run1
         224             :
         225             :    type(cam_in_t)  :: cam_in(begchunk:endchunk)
         226             :    type(cam_out_t) :: cam_out(begchunk:endchunk)
         227             :
         228             :    !-----------------------------------------------------------------------
         229             :
         230      370944 :    if (offline_driver_dorun) return
         231             :
         232             :    !----------------------------------------------------------
         233             :    ! First phase of dynamics (at least couple from dynamics to physics)
         234             :    ! Return time-step for physics from dynamics.
         235             :    !----------------------------------------------------------
         236      370944 :    call t_barrierf ('sync_stepon_run1', mpicom)
         237      370944 :    call t_startf ('stepon_run1')
         238      370944 :    call stepon_run1( dtime_phys, phys_state, phys_tend, pbuf2d, dyn_in, dyn_out )
         239      370944 :    call t_stopf  ('stepon_run1')
         240             :
         241             :    !----------------------------------------------------------
         242             :    ! first phase of ionosphere -- write to IC file if needed
         243             :    !----------------------------------------------------------
         244      370944 :    call ionosphere_run1(pbuf2d)
         245             :
         246             :    !
         247             :    !----------------------------------------------------------
         248             :    ! PHYS_RUN Call the Physics package
         249             :    !----------------------------------------------------------
         250             :    !
         251      370944 :    call t_barrierf ('sync_phys_run1', mpicom)
         252      370944 :    call t_startf ('phys_run1')
         253      370944 :    call phys_run1(phys_state, dtime_phys, phys_tend, pbuf2d,  cam_in, cam_out)
         254      370944 :    call t_stopf  ('phys_run1')
         255             :
         256      370944 : end subroutine cam_run1
         257             :
         258             : !
         259             : !-----------------------------------------------------------------------
         260             : !
         261             :
         262      738816 : subroutine cam_run2( cam_out, cam_in )
         263             : !-----------------------------------------------------------------------
         264             : !
         265             : ! Purpose:   Second phase of atmosphere model run method.
         266             : !            Run the second phase physics, run methods that
         267             : !            require the surface model updates.  And run the
         268             : !            second phase of dynamics that at least couples
         269             : !            between physics to dynamics.
         270             : !
         271             : !-----------------------------------------------------------------------
         272             :
         273      370944 :    use physpkg,          only: phys_run2
         274             :    use stepon,           only: stepon_run2
         275             :    use ionosphere_interface, only: ionosphere_run2
         276             :
         277             :    type(cam_out_t), intent(inout) :: cam_out(begchunk:endchunk)
         278             :    type(cam_in_t),  intent(inout) :: cam_in(begchunk:endchunk)
         279             :
         280      369408 :    if (offline_driver_dorun) then
         281           0 :       call offline_driver_run( phys_state, pbuf2d, cam_out, cam_in )
         282             :       return
         283             :    endif
         284             :
         285             :    !
         286             :    ! Second phase of physics (after surface model update)
         287             :    !
         288      369408 :    call t_barrierf ('sync_phys_run2', mpicom)
         289      369408 :    call t_startf ('phys_run2')
         290      369408 :    call phys_run2(phys_state, dtime_phys, phys_tend, pbuf2d,  cam_out, cam_in )
         291      369408 :    call t_stopf  ('phys_run2')
         292             :
         293             :    !
         294             :    ! Second phase of dynamics (at least couple from physics to dynamics)
         295             :    !
         296      369408 :    call t_barrierf ('sync_stepon_run2', mpicom)
         297      369408 :    call t_startf ('stepon_run2')
         298      369408 :    call stepon_run2( phys_state, phys_tend, dyn_in, dyn_out )
         299      369408 :    call t_stopf  ('stepon_run2')
         300             :
         301             :    !
         302             :    ! Ion transport
         303             :    !
         304      369408 :    call t_startf('ionosphere_run2')
         305      369408 :    call ionosphere_run2( phys_state, pbuf2d )
         306      369408 :    call t_stopf ('ionosphere_run2')
         307             :
         308      369408 : end subroutine cam_run2
         309             :
         310             : !
         311             : !-----------------------------------------------------------------------
         312             : !
         313             :
         314      738816 : subroutine cam_run3( cam_out )
         315             : !-----------------------------------------------------------------------
         316             : !
         317             : ! Purpose:  Third phase of atmosphere model run method. This consists
         318             : !           of the third phase of the dynamics. For some dycores
         319             : !           this will be the actual dynamics run, for others the
         320             : !           dynamics happens before physics in phase 1.
         321             : !
         322             : !-----------------------------------------------------------------------
         323      369408 :    use stepon,           only: stepon_run3
         324             :
         325             :    type(cam_out_t), intent(inout) :: cam_out(begchunk:endchunk)
         326             : !-----------------------------------------------------------------------
         327             :
         328      369408 :    if (offline_driver_dorun) return
         329             :
         330             :    !
         331             :    ! Third phase of dynamics
         332             :    !
         333      369408 :    call t_barrierf ('sync_stepon_run3', mpicom)
         334      369408 :    call t_startf ('stepon_run3')
         335      369408 :    call stepon_run3( dtime_phys, cam_out, phys_state, dyn_in, dyn_out )
         336             :
         337      369408 :    call t_stopf  ('stepon_run3')
         338             :
         339      369408 : end subroutine cam_run3
         340             :
         341             : !
         342             : !-----------------------------------------------------------------------
         343             : !
         344             :
         345      738816 : subroutine cam_run4( cam_out, cam_in, rstwr, nlend, &
         346             :                      yr_spec, mon_spec, day_spec, sec_spec )
         347             :
         348             : !-----------------------------------------------------------------------
         349             : !
         350             : ! Purpose:  Final phase of atmosphere model run method. This consists
         351             : !           of all the restart output, history writes, and other
         352             : !           file output.
         353             : !
         354             : !-----------------------------------------------------------------------
         355      369408 :    use dycore_budget,    only: print_budget
         356             :    use cam_history,      only: wshist, wrapup, hstwr
         357             :    use cam_restart,      only: cam_write_restart
         358             :    use qneg_module,      only: qneg_print_summary
         359             :    use time_manager,     only: is_last_step
         360             :
         361             :    type(cam_out_t), intent(inout)        :: cam_out(begchunk:endchunk)
         362             :    type(cam_in_t) , intent(inout)        :: cam_in(begchunk:endchunk)
         363             :    logical            , intent(in)           :: rstwr           ! true => write restart file
         364             :    logical            , intent(in)           :: nlend           ! true => this is final timestep
         365             :    integer            , intent(in), optional :: yr_spec         ! Simulation year
         366             :    integer            , intent(in), optional :: mon_spec        ! Simulation month
         367             :    integer            , intent(in), optional :: day_spec        ! Simulation day
         368             :    integer            , intent(in), optional :: sec_spec        ! Seconds into current simulation day
         369             :
         370             :    !----------------------------------------------------------
         371             :    ! History and restart logic: Write and/or dispose history tapes if required
         372             :    !----------------------------------------------------------
         373             :    !
         374      369408 :    call t_barrierf ('sync_wshist', mpicom)
         375      369408 :    call t_startf ('wshist')
         376      369408 :    call wshist ()
         377      369408 :    call t_stopf  ('wshist')
         378             :
         379             :    !
         380             :    ! Write restart files
         381             :    !
         382      369408 :    if (rstwr) then
         383        1536 :       call t_startf ('cam_write_restart')
         384        1536 :       if (present(yr_spec).and.present(mon_spec).and.present(day_spec).and.present(sec_spec)) then
         385             :          call cam_write_restart(cam_in, cam_out, dyn_out, pbuf2d, &
         386        1536 :               yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec )
         387             :       else
         388           0 :          call cam_write_restart(cam_in, cam_out, dyn_out, pbuf2d )
         389             :       end if
         390        1536 :       call t_stopf  ('cam_write_restart')
         391             :    end if
         392             :
         393      369408 :    call t_startf ('cam_run4_wrapup')
         394      369408 :    call wrapup(rstwr, nlend)
         395      369408 :    call t_stopf  ('cam_run4_wrapup')
         396             :
         397      369408 :    call qneg_print_summary(is_last_step())
         398             :
         399      369408 :    call print_budget(hstwr)
         400             :
         401      369408 :    call shr_sys_flush(iulog)
         402             :
         403      369408 : end subroutine cam_run4
         404             :
         405             : !
         406             : !-----------------------------------------------------------------------
         407             : !
         408             :
         409        1536 : subroutine cam_final( cam_out, cam_in )
         410             : !-----------------------------------------------------------------------
         411             : !
         412             : ! Purpose:  CAM finalization.
         413             : !
         414             : !-----------------------------------------------------------------------
         415      369408 :    use stepon,               only: stepon_final
         416             :    use physpkg,              only: phys_final
         417             :    use cam_initfiles,        only: cam_initfiles_close
         418             :    use camsrfexch,           only: atm2hub_deallocate, hub2atm_deallocate
         419             :    use ionosphere_interface, only: ionosphere_final
         420             :    use cam_control_mod,      only: initial_run
         421             :
         422             :    !
         423             :    ! Arguments
         424             :    !
         425             :    type(cam_out_t), pointer :: cam_out(:) ! Output from CAM to surface
         426             :    type(cam_in_t),  pointer :: cam_in(:)   ! Input from merged surface to CAM
         427             :
         428             :    ! Local variables
         429             :    integer :: nstep           ! Current timestep number.
         430             :    !-----------------------------------------------------------------------
         431             :
         432        1536 :    call phys_final( phys_state, phys_tend , pbuf2d)
         433        1536 :    call stepon_final(dyn_in, dyn_out)
         434        1536 :    call ionosphere_final()
         435             :
         436        1536 :    if (initial_run) then
         437         768 :       call cam_initfiles_close()
         438             :    end if
         439             :
         440        1536 :    call hub2atm_deallocate(cam_in)
         441        1536 :    call atm2hub_deallocate(cam_out)
         442             :
         443             :    ! This flush attempts to ensure that asynchronous diagnostic prints from all
         444             :    ! processes do not get mixed up with the "END OF MODEL RUN" message printed
         445             :    ! by masterproc below.  The test-model script searches for this message in the
         446             :    ! output log to figure out if CAM completed successfully.
         447        1536 :    call shr_sys_flush( 0 )       ! Flush all output to standard error
         448        1536 :    call shr_sys_flush( iulog )   ! Flush all output to the CAM log file
         449             :
         450        1536 :    if (masterproc) then
         451           2 :       nstep = get_nstep()
         452           2 :       write(iulog,9300) nstep-1,nstep
         453             : 9300  format (//'Number of completed timesteps:',i6,/,'Time step ',i6, &
         454             :                 ' partially done to provide convectively adjusted and ', &
         455             :                 'time filtered values for history tape.')
         456           2 :       write(iulog,*)' '
         457           2 :       write(iulog,*)'******* END OF MODEL RUN *******'
         458             :    end if
         459             :
         460        1536 : end subroutine cam_final
         461             :
         462             : !-----------------------------------------------------------------------
         463             :
         464             : end module cam_comp

Generated by: LCOV version 1.14