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: 2024-12-17 22:39:59 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