module stepon !----------------------------------------------------------------------- ! ! Purpose: ! Module for time-stepping of the Spectral Semi-Lagrangian Dynamical core. ! !----------------------------------------------------------------------- use shr_kind_mod, only: r8 => shr_kind_r8 use shr_sys_mod, only: shr_sys_flush use pmgrid, only: plev, plat, plevp, plon, beglat, endlat use spmd_utils, only: masterproc use scanslt, only: advection_state use prognostics, only: u3, v3, t3, q3, n3, div, dpsl, dpsm, ps, omga, & phis use camsrfexch, only: cam_out_t use ppgrid, only: begchunk, endchunk use physics_types, only: physics_state, physics_tend use time_manager, only: is_first_step use infnan, only: nan use perf_mod use dyn_comp, only: dyn_import_t, dyn_export_t implicit none private ! By default make all data and methods private to this module ! ! Public methods ! public stepon_init ! Initialization public stepon_run1 ! Run method phase 1 public stepon_run2 ! Run method phase 2 public stepon_run3 ! Run method phase 3 public stepon_final ! Finalization ! ! Private module data ! save type(physics_state), pointer :: phys_state(:) ! Physics state data type(physics_tend ), pointer :: phys_tend(:) ! Physics tendency data real(r8) :: detam(plev) ! intervals between vert full levs. real(r8) :: cwava(plat) ! weight applied to global integrals real(r8), allocatable :: t2(:,:,:) ! temp tendency real(r8), allocatable :: fu(:,:,:) ! u wind tendency real(r8), allocatable :: fv(:,:,:) ! v wind tendency real(r8), allocatable :: flx_net(:,:) ! net flux from physics real(r8) :: coslat(plon) ! cosine of latitude real(r8) :: rcoslat(plon) ! Inverse of coseine of latitude real(r8) :: rpmid(plon,plev) ! inverse of midpoint pressure real(r8) :: pdel(plon,plev) ! Pressure depth of layer real(r8) :: pint(plon,plevp) ! Pressure at interfaces real(r8) :: pmid(plon,plev) ! Pressure at midpoint type(advection_state) :: adv_state ! Advection state data !======================================================================= contains !======================================================================= subroutine stepon_init( gw, etamid , dyn_in, dyn_out) !----------------------------------------------------------------------- ! ! Purpose: ! Stepon initialization, primarily dynamics initialization. ! !----------------------------------------------------------------------- use rgrid, only: nlon use commap, only: clat use time_manager, only: is_first_step use scanslt, only: slt_initial use hycoef, only: hyam, hybm !----------------------------------------------------------------------- ! Output arguments ! real(r8), intent(out) :: gw(plat) ! Gaussian weights real(r8), intent(out) :: etamid(plev) ! vertical coords at midpoints type(dyn_import_t) :: dyn_in ! included for compatibility type(dyn_export_t) :: dyn_out ! included for compatibility ! Local variables ! integer i,k,lat ! longitude,level,latitude indices !----------------------------------------------------------------------- ! ! Define eta coordinates on midpoints ! call t_startf ('stepon_startup') do k=1,plev etamid(k) = hyam(k) + hybm(k) end do if (is_first_step()) then do lat=beglat,endlat do i=1,nlon(lat) coslat(i) = cos(clat(lat)) rcoslat(i) = 1._r8/coslat(i) end do ! ! Set current time pressure arrays for model levels etc. ! call plevs0(nlon(lat), plon, plev, ps(1,lat,n3), pint, pmid, pdel) ! do k=1,plev do i=1,nlon(lat) rpmid(i,k) = 1._r8/pmid(i,k) end do end do ! ! Calculate vertical motion field ! call omcalc (rcoslat, div(1,1,lat,n3), u3(1,1,lat,n3), v3(1,1,lat,n3), dpsl(1,lat), & dpsm(1,lat), pmid, pdel, rpmid, pint(1,plevp), & omga(1,1,lat), nlon(lat)) end do end if call slt_initial( detam, gw, cwava, etamid, adv_state ) allocate(t2(plon,plev,beglat:endlat)) allocate(fu(plon,plev,beglat:endlat)) allocate(fv(plon,plev,beglat:endlat)) allocate(flx_net(plon,beglat:endlat)) call t_stopf ('stepon_startup') end subroutine stepon_init ! !======================================================================= ! subroutine stepon_run1( ztodt, phys_state, phys_tend, pbuf2d, dyn_in, dyn_out ) !----------------------------------------------------------------------- ! ! Purpose: First phase of run method for SLD. Return ! time-step to atmosphere and couple to physics. ! !----------------------------------------------------------------------- use time_manager, only: get_step_size use dp_coupling, only: d_p_coupling, p_d_coupling use physics_buffer, only : physics_buffer_desc ! ! Output arguments: ! real(r8), intent(out) :: ztodt ! time step type(physics_state), intent(inout) :: phys_state(begchunk:endchunk) type(physics_tend), intent(out) :: phys_tend(begchunk:endchunk) type(physics_buffer_desc), pointer :: pbuf2d(:,:) type(dyn_import_t) :: dyn_in ! included for compatibility type(dyn_export_t) :: dyn_out ! included for compatibility ztodt = get_step_size() ! ! Dump state variables to IC file ! call t_startf ('diag_dynvar_ic') call diag_dynvar_ic (phis, ps(1,beglat,n3), t3(1,1,beglat,n3), u3(1,1,beglat,n3), & v3(1,1,beglat,n3), q3(1,1,1,beglat,n3) ) call t_stopf ('diag_dynvar_ic') ! !---------------------------------------------------------- ! PHYS_RUN Call the Physics package !---------------------------------------------------------- ! call t_startf ('d_p_coupling') call d_p_coupling (ps(1,beglat,n3), t3(1,1,beglat,n3), u3(1,1,beglat,n3), & v3(1,1,beglat,n3), q3(1,1,1,beglat,n3), & omga, phis, phys_state, phys_tend, pbuf2d) call t_stopf ('d_p_coupling') end subroutine stepon_run1 ! !======================================================================= ! subroutine stepon_run2( phys_state, phys_tend, dyn_in, dyn_out ) !----------------------------------------------------------------------- ! ! Purpose: Second phase of run method for SLD. Couple from physics ! to dynamics. ! !----------------------------------------------------------------------- use dp_coupling, only: p_d_coupling ! ! Input arguments: ! type(physics_state), intent(in):: phys_state(begchunk:endchunk) type(physics_tend), intent(in):: phys_tend(begchunk:endchunk) type(dyn_import_t) :: dyn_in ! included for compatibility type(dyn_export_t) :: dyn_out ! included for compatibility call t_startf ('p_d_coupling') call p_d_coupling (phys_state, phys_tend, t2, fu, fv, flx_net,q3(1,1,1,beglat,n3)) call t_stopf ('p_d_coupling') end subroutine stepon_run2 ! !======================================================================= ! subroutine stepon_run3( ztodt, etamid, cam_out, phys_state, dyn_in, dyn_out ) !----------------------------------------------------------------------- ! ! Purpose: Final phase of run method for SLD. Run the actual ! dynamics. ! !----------------------------------------------------------------------- ! ! Input arguments: ! real(r8), intent(in) :: ztodt ! time step real(r8), intent(in) :: etamid(plev) ! vertical coords at midpoints type(physics_state), intent(in):: phys_state(begchunk:endchunk) type(dyn_import_t) :: dyn_in ! included for compatibility type(dyn_export_t) :: dyn_out ! included for compatibility ! ! Input/output argument: ! type(cam_out_t), intent(inout) :: cam_out(begchunk:endchunk) !---------------------------------------------------------- ! DYNPKG Call the Dynamics Package !---------------------------------------------------------- call t_startf ('dynpkg') call dynpkg(t2 ,fu ,fv ,etamid , & cwava ,detam ,flx_net , ztodt ,adv_state) call t_stopf ('dynpkg') end subroutine stepon_run3 ! !======================================================================= ! subroutine stepon_final(dyn_in, dyn_out) !----------------------------------------------------------------------- ! ! Purpose: Stepon finalization. ! !----------------------------------------------------------------------- use scanslt, only: slt_final type(dyn_import_t) :: dyn_in ! included for compatibility type(dyn_export_t) :: dyn_out ! included for compatibility call slt_final( adv_state ) deallocate(t2) deallocate(fu) deallocate(fv) end subroutine stepon_final ! !======================================================================= ! end module stepon