diff --git a/doc/ChangeLog b/doc/ChangeLog index 07d6a6f9f4..40d1ac8e95 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,62 @@ =============================================================== +Tag name: cam6_3_012 +Originator(s): ckruse, cacraig +Date: March 3, 2021 +One-line Summary: Add Horizontal Momentum Tendency Budget Variables +Github PR URL: https://github.com/ESCOMP/CAM/pull/232 + +Purpose of changes (include the issue number and title text for each relevant GitHub issue): + - Add Horizontal Momemntum Tendency Budget Variables (#226) + - Output U and V tendencies after every physics parameterization when history_budget is set to true. For ease + of use, all tendencies are output, even if they are zero or are output under a different name. + +Describe any changes made to build system: + +Describe any changes made to the namelist: + - "history_budget" now also outputs the horizontal momentum tendency variables after every physics parameterization + +List any changes to the defaults for the boundary datasets: + +Describe any substantial timing or memory changes: + +Code reviewed by: cacraig, goldy, fvitt, nusbaume + +List all files eliminated: + +List all files added and what they do: + +List all existing files that have been modified, and describe the changes: +M src/physics/cam/cam_diagnostics.F90 +M src/physics/cam/check_energy.F90 +M src/physics/cam/physpkg.F90 + - Add logic to output horizontal momementum tendencies after every physics parameterization + +If there were any failures reported from running test_driver.sh on any test +platform, and checkin with these failures has been OK'd by the gatekeeper, +then copy the lines from the td.*.status files for the failed tests to the +appropriate machine below. All failed tests must be justified. + +cheyenne/intel/aux_cam: all BFB + +izumi/nag/aux_cam: + SMS_D_Ln7.T42_T42_mg17.QPSCAMC5.izumi_nag.cam-scmarm (Overall: DIFF) details: + FAIL SMS_D_Ln7.T42_T42_mg17.QPSCAMC5.izumi_nag.cam-scmarm BASELINE /fs/cgd/csm/models/atm/cam/pretag_bl/cam6_3_011_nag: FIELDLIST field lists differ (otherwise bit-for-bit) + - expected new output fields + + DAE.f45_f45_mg37.FHS94.izumi_nag.cam-dae (Overall: FAIL) details: + FAIL DAE.f45_f45_mg37.FHS94.izumi_nag.cam-dae COMPARE_base_da + FAIL DAE.f45_f45_mg37.FHS94.izumi_nag.cam-dae BASELINE /fs/cgd/csm/models/atm/cam/pretag_bl/cam6_3_011_nag: ERROR BFAIL some baseline files were missing + - continued known failing test + +izumi/pgi/aux_cam: + ERC_D_Ln9.f10_f10_mg37.QPC4.izumi_pgi.cam-outfrq3s_diags (Overall: DIFF) details: + FAIL ERC_D_Ln9.f10_f10_mg37.QPC4.izumi_pgi.cam-outfrq3s_diags BASELINE /fs/cgd/csm/models/atm/cam/pretag_bl/cam6_3_011_pgi: FIELDLIST field lists differ (otherwise bit-for-bit) + - expected new output fields + +=============================================================== +=============================================================== + Tag name: cam6_3_011 Originator(s): jet Date: 1 Mar 2021 diff --git a/src/physics/cam/cam_diagnostics.F90 b/src/physics/cam/cam_diagnostics.F90 index a90d806284..4ab35242c0 100644 --- a/src/physics/cam/cam_diagnostics.F90 +++ b/src/physics/cam/cam_diagnostics.F90 @@ -90,6 +90,8 @@ module cam_diagnostics integer :: kvh_idx = 0 integer :: cush_idx = 0 integer :: t_ttend_idx = 0 +integer :: t_utend_idx = 0 +integer :: t_vtend_idx = 0 integer :: prec_dp_idx = 0 integer :: snow_dp_idx = 0 @@ -150,6 +152,8 @@ subroutine diag_register_dry() ! Request physics buffer space for fields that persist across timesteps. call pbuf_add_field('T_TTEND', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), t_ttend_idx) + call pbuf_add_field('T_UTEND', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), t_utend_idx) + call pbuf_add_field('T_VTEND', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), t_vtend_idx) end subroutine diag_register_dry subroutine diag_register_moist() @@ -195,6 +199,9 @@ subroutine diag_init_dry(pbuf2d) ! State before physics call addfld ('TBP', (/ 'lev' /), 'A','K', 'Temperature (before physics)') + call addfld ('UBP', (/ 'lev' /), 'A','m/s', 'Zonal wind (before physics)') + call addfld ('VBP', (/ 'lev' /), 'A','m/s', 'Meridional Wind (before physics)') + call register_vector_field('UBP','VBP') call addfld (bpcnst(1), (/ 'lev' /), 'A','kg/kg', trim(cnst_longname(1))//' (before physics)') ! State after physics call addfld ('TAP', (/ 'lev' /), 'A','K', 'Temperature (after physics)' ) @@ -208,7 +215,12 @@ subroutine diag_init_dry(pbuf2d) call addfld ('TFIX', horiz_only, 'A', 'K/s', 'T fixer (T equivalent of Energy correction)') end if call addfld ('TTEND_TOT', (/ 'lev' /), 'A', 'K/s', 'Total temperature tendency') - + + ! outfld calls in diag_phys_tend_writeout + call addfld ('UTEND_TOT', (/ 'lev' /), 'A', 'm/s2', 'Total zonal wind tendency') + call addfld ('VTEND_TOT', (/ 'lev' /), 'A', 'm/s2', 'Total meridional wind tendency') + call register_vector_field('UTEND_TOT','VTEND_TOT') + ! Debugging negative water output fields call addfld ('INEGCLPTEND ', (/ 'lev' /), 'A', 'kg/kg/s', 'Cloud ice tendency due to clipping neg values after microp') call addfld ('LNEGCLPTEND ', (/ 'lev' /), 'A', 'kg/kg/s', 'Cloud liq tendency due to clipping neg values after microp') @@ -330,9 +342,13 @@ subroutine diag_init_dry(pbuf2d) call add_default ('U ' , history_budget_histfile_num, ' ') call add_default ('V ' , history_budget_histfile_num, ' ') call add_default ('TTEND_TOT' , history_budget_histfile_num, ' ') + call add_default ('UTEND_TOT' , history_budget_histfile_num, ' ') + call add_default ('VTEND_TOT' , history_budget_histfile_num, ' ') ! State before physics (FV) call add_default ('TBP ' , history_budget_histfile_num, ' ') + call add_default ('UBP ' , history_budget_histfile_num, ' ') + call add_default ('VBP ' , history_budget_histfile_num, ' ') call add_default (bpcnst(1) , history_budget_histfile_num, ' ') ! State after physics (FV) call add_default ('TAP ' , history_budget_histfile_num, ' ') @@ -351,9 +367,14 @@ subroutine diag_init_dry(pbuf2d) end if ! outfld calls in diag_phys_tend_writeout - call addfld ('PTTEND', (/ 'lev' /), 'A', 'K/s','T total physics tendency' ) + call addfld ('PTTEND', (/ 'lev' /), 'A', 'K/s','T total physics tendency') + call addfld ('UTEND_PHYSTOT', (/ 'lev' /), 'A', 'm/s2','U total physics tendency') + call addfld ('VTEND_PHYSTOT', (/ 'lev' /), 'A', 'm/s2','V total physics tendency') + call register_vector_field('UTEND_PHYSTOT','VTEND_PHYSTOT') if ( history_budget ) then call add_default ('PTTEND' , history_budget_histfile_num, ' ') + call add_default ('UTEND_PHYSTOT' , history_budget_histfile_num, ' ') + call add_default ('VTEND_PHYSTOT' , history_budget_histfile_num, ' ') end if ! create history variables for fourier coefficients of the diurnal @@ -613,6 +634,8 @@ subroutine diag_init_moist(pbuf2d) if ( history_budget ) then call add_default (cnst_name(1), history_budget_histfile_num, ' ') call add_default ('PTTEND' , history_budget_histfile_num, ' ') + call add_default ('UTEND_PHYSTOT' , history_budget_histfile_num, ' ') + call add_default ('VTEND_PHYSTOT' , history_budget_histfile_num, ' ') call add_default (ptendnam( 1), history_budget_histfile_num, ' ') if (ixcldliq > 0) then call add_default (ptendnam(ixcldliq), history_budget_histfile_num, ' ') @@ -862,6 +885,8 @@ subroutine diag_conv_tend_ini(state,pbuf) integer :: i, k, m, lchnk, ncol real(r8), pointer, dimension(:,:) :: t_ttend + real(r8), pointer, dimension(:,:) :: t_utend + real(r8), pointer, dimension(:,:) :: t_vtend lchnk = state%lchnk ncol = state%ncol @@ -885,6 +910,10 @@ subroutine diag_conv_tend_ini(state,pbuf) do m = 1, dyn_time_lvls call pbuf_get_field(pbuf, t_ttend_idx, t_ttend, start=(/1,1,m/), kount=(/pcols,pver,1/)) t_ttend(:ncol,:) = state%t(:ncol,:) + call pbuf_get_field(pbuf, t_utend_idx, t_utend, start=(/1,1,m/), kount=(/pcols,pver,1/)) + t_utend(:ncol,:) = state%u(:ncol,:) + call pbuf_get_field(pbuf, t_vtend_idx, t_vtend, start=(/1,1,m/), kount=(/pcols,pver,1/)) + t_vtend(:ncol,:) = state%v(:ncol,:) end do end if @@ -2018,6 +2047,8 @@ subroutine diag_phys_tend_writeout_dry(state, pbuf, tend, ztodt) real(r8) :: heat_glob ! global energy integral (FV only) ! CAM pointers to get variables from the physics buffer real(r8), pointer, dimension(:,:) :: t_ttend + real(r8), pointer, dimension(:,:) :: t_utend + real(r8), pointer, dimension(:,:) :: t_vtend integer :: itim_old,m !----------------------------------------------------------------------- @@ -2043,19 +2074,31 @@ subroutine diag_phys_tend_writeout_dry(state, pbuf, tend, ztodt) ftem3(:ncol,:pver) = tend%dtdt(:ncol,:pver) end if call outfld('PTTEND',ftem3, pcols, lchnk ) + ftem3(:ncol,:pver) = tend%dudt(:ncol,:pver) + call outfld('UTEND_PHYSTOT',ftem3, pcols, lchnk ) + ftem3(:ncol,:pver) = tend%dvdt(:ncol,:pver) + call outfld('VTEND_PHYSTOT',ftem3, pcols, lchnk ) ! Total (physics+dynamics, everything!) tendency for Temperature - !! get temperature stored in physics buffer + !! get temperature, U, and V stored in physics buffer itim_old = pbuf_old_tim_idx() call pbuf_get_field(pbuf, t_ttend_idx, t_ttend, start=(/1,1,itim_old/), kount=(/pcols,pver,1/)) + call pbuf_get_field(pbuf, t_utend_idx, t_utend, start=(/1,1,itim_old/), kount=(/pcols,pver,1/)) + call pbuf_get_field(pbuf, t_vtend_idx, t_vtend, start=(/1,1,itim_old/), kount=(/pcols,pver,1/)) - !! calculate and outfld the total temperature tendency + !! calculate and outfld the total temperature, U, and V tendencies ftem3(:ncol,:) = (state%t(:ncol,:) - t_ttend(:ncol,:))/ztodt call outfld('TTEND_TOT', ftem3, pcols, lchnk) + ftem3(:ncol,:) = (state%u(:ncol,:) - t_utend(:ncol,:))/ztodt + call outfld('UTEND_TOT', ftem3, pcols, lchnk) + ftem3(:ncol,:) = (state%v(:ncol,:) - t_vtend(:ncol,:))/ztodt + call outfld('VTEND_TOT', ftem3, pcols, lchnk) - !! update physics buffer with this time-step's temperature + !! update physics buffer with this time-step's temperature, U, and V t_ttend(:ncol,:) = state%t(:ncol,:) + t_utend(:ncol,:) = state%u(:ncol,:) + t_vtend(:ncol,:) = state%v(:ncol,:) end subroutine diag_phys_tend_writeout_dry @@ -2220,6 +2263,8 @@ subroutine diag_state_b4_phys_write_dry (state) lchnk = state%lchnk call outfld('TBP', state%t, pcols, lchnk ) + call outfld('UBP', state%u, pcols, lchnk ) + call outfld('VBP', state%v, pcols, lchnk ) end subroutine diag_state_b4_phys_write_dry diff --git a/src/physics/cam/check_energy.F90 b/src/physics/cam/check_energy.F90 index 2260792315..6fd157628f 100644 --- a/src/physics/cam/check_energy.F90 +++ b/src/physics/cam/check_energy.F90 @@ -66,6 +66,8 @@ module check_energy integer :: teout_idx = 0 ! teout index in physics buffer integer :: dtcore_idx = 0 ! dtcore index in physics buffer + integer :: ducore_idx = 0 ! ducore index in physics buffer + integer :: dvcore_idx = 0 ! dvcore index in physics buffer type check_tracers_data real(r8) :: tracer(pcols,pcnst) ! initial vertically integrated total (kinetic + static) energy @@ -137,9 +139,13 @@ subroutine check_energy_register() call pbuf_add_field('TEOUT', 'global',dtype_r8 , (/pcols,dyn_time_lvls/), teout_idx) call pbuf_add_field('DTCORE','global',dtype_r8, (/pcols,pver,dyn_time_lvls/),dtcore_idx) + call pbuf_add_field('DUCORE','global',dtype_r8, (/pcols,pver,dyn_time_lvls/),ducore_idx) + call pbuf_add_field('DVCORE','global',dtype_r8, (/pcols,pver,dyn_time_lvls/),dvcore_idx) if(is_subcol_on()) then call pbuf_register_subcol('TEOUT', 'phys_register', teout_idx) call pbuf_register_subcol('DTCORE', 'phys_register', dtcore_idx) + call pbuf_register_subcol('DUCORE', 'phys_register', ducore_idx) + call pbuf_register_subcol('DVCORE', 'phys_register', dvcore_idx) end if end subroutine check_energy_register diff --git a/src/physics/cam/physpkg.F90 b/src/physics/cam/physpkg.F90 index bbb57fb5e2..e8da28d94c 100644 --- a/src/physics/cam/physpkg.F90 +++ b/src/physics/cam/physpkg.F90 @@ -86,6 +86,8 @@ module physpkg integer :: prec_sh_idx = 0 integer :: snow_sh_idx = 0 integer :: dlfzm_idx = 0 ! detrained convective cloud water mixing ratio. + integer :: ducore_idx = 0 ! ducore index in physics buffer + integer :: dvcore_idx = 0 ! dvcore index in physics buffer !======================================================================= contains @@ -760,6 +762,8 @@ subroutine phys_init( phys_state, phys_tend, pbuf2d, cam_in, cam_out ) use cam_abortutils, only: endrun use nudging, only: Nudge_Model, nudging_init use cam_snapshot, only: cam_snapshot_init + use cam_history, only: addfld, register_vector_field, add_default + use phys_control, only: phys_getopts ! Input/output arguments type(physics_state), pointer :: phys_state(:) @@ -773,6 +777,11 @@ subroutine phys_init( phys_state, phys_tend, pbuf2d, cam_in, cam_out ) integer :: lchnk integer :: ierr + logical :: history_budget ! output tendencies and state variables for + ! temperature, water vapor, cloud + ! ice, cloud liquid, U, V + integer :: history_budget_histfile_num ! output history file number for budget fields + !----------------------------------------------------------------------- call physics_type_alloc(phys_state, phys_tend, begchunk, endchunk, pcols) @@ -952,6 +961,74 @@ subroutine phys_init( phys_state, phys_tend, pbuf2d, cam_in, cam_out ) ! Initialize the snapshot capability call cam_snapshot_init(cam_in, cam_out, pbuf2d, begchunk) + ! addfld calls for U, V tendency budget variables that are output in + ! tphysac, tphysbc + call addfld ( 'UTEND_DCONV', (/ 'lev' /), 'A', 'm/s2', 'Zonal wind tendency by deep convection') + call addfld ( 'VTEND_DCONV', (/ 'lev' /), 'A', 'm/s2', 'Meridional wind tendency by deep convection') + call register_vector_field ( 'UTEND_DCONV', 'VTEND_DCONV') + call addfld ( 'UTEND_SHCONV', (/ 'lev' /), 'A', 'm/s2', 'Zonal wind tendency by shallow convection') + call addfld ( 'VTEND_SHCONV', (/ 'lev' /), 'A', 'm/s2', 'Meridional wind tendency by shallow convection') + call register_vector_field ( 'UTEND_SHCONV', 'VTEND_SHCONV') + call addfld ( 'UTEND_MACROP', (/ 'lev' /), 'A', 'm/s2', 'Zonal wind tendency by macrophysics') + call addfld ( 'VTEND_MACROP', (/ 'lev' /), 'A', 'm/s2', 'Meridional wind tendency by macrophysics') + call register_vector_field ( 'UTEND_MACROP', 'VTEND_MACROP') + call addfld ( 'UTEND_VDIFF', (/ 'lev' /), 'A', 'm/s2', 'Zonal wind tendency by vert. diffus.') + call addfld ( 'VTEND_VDIFF', (/ 'lev' /), 'A', 'm/s2', 'Meridional wind tendency by vert. diffus.') + call register_vector_field ( 'UTEND_VDIFF', 'VTEND_VDIFF') + call addfld ( 'UTEND_RAYLEIGH', (/ 'lev' /), 'A', 'm/s2', 'Zonal wind tendency by Rayleigh Fric.') + call addfld ( 'VTEND_RAYLEIGH', (/ 'lev' /), 'A', 'm/s2', 'Meridional wind tendency by Rayleigh Fric.') + call register_vector_field ( 'UTEND_RAYLEIGH', 'VTEND_RAYLEIGH') + call addfld ( 'UTEND_GWDTOT', (/ 'lev' /), 'A', 'm/s2', 'Zonal wind tendency by all GWs') + call addfld ( 'VTEND_GWDTOT', (/ 'lev' /), 'A', 'm/s2', 'Meridional wind tendency by all GWs') + call register_vector_field ( 'UTEND_GWDTOT', 'VTEND_GWDTOT') + call addfld ( 'UTEND_QBORLX', (/ 'lev' /), 'A', 'm/s2', 'Zonal wind tendency by QBO relaxation') + call addfld ( 'VTEND_QBORLX', (/ 'lev' /), 'A', 'm/s2', 'Meridional wind tendency by QBO relaxation') + call register_vector_field ( 'UTEND_QBORLX', 'VTEND_QBORLX') + call addfld ( 'UTEND_LUNART', (/ 'lev' /), 'A', 'm/s2', 'Zonal wind tendency by lunar tides') + call addfld ( 'VTEND_LUNART', (/ 'lev' /), 'A', 'm/s2', 'Meridional wind tendency by lunar tides') + call register_vector_field ( 'UTEND_LUNART', 'VTEND_LUNART') + call addfld ( 'UTEND_IONDRG', (/ 'lev' /), 'A', 'm/s2', 'Zonal wind tendency by ion drag') + call addfld ( 'VTEND_IONDRG', (/ 'lev' /), 'A', 'm/s2', 'Meridional wind tendency by ion drag') + call register_vector_field ( 'UTEND_IONDRG', 'VTEND_IONDRG') + call addfld ( 'UTEND_NDG', (/ 'lev' /), 'A', 'm/s2', 'Zonal wind tendency by nudging') + call addfld ( 'VTEND_NDG', (/ 'lev' /), 'A', 'm/s2', 'Meridional wind tendency by nudging') + call register_vector_field ( 'UTEND_NDG', 'VTEND_NDG') + call addfld('UTEND_CORE', (/ 'lev' /), 'A', 'm/s2' , 'Zonal wind tendency due to dynamical core') + call addfld('VTEND_CORE', (/ 'lev' /), 'A', 'm/s2' , 'Meridional wind tendency due to dynamical core') + call register_vector_field('UTEND_CORE','VTEND_CORE') + + + call phys_getopts(history_budget_out = history_budget, & + history_budget_histfile_num_out = history_budget_histfile_num) + + if ( history_budget ) then + call add_default ( 'UTEND_DCONV' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_DCONV' , history_budget_histfile_num, ' ') + call add_default ( 'UTEND_SHCONV' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_SHCONV' , history_budget_histfile_num, ' ') + call add_default ( 'UTEND_MACROP' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_MACROP' , history_budget_histfile_num, ' ') + call add_default ( 'UTEND_VDIFF' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_VDIFF' , history_budget_histfile_num, ' ') + call add_default ( 'UTEND_RAYLEIGH' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_RAYLEIGH' , history_budget_histfile_num, ' ') + call add_default ( 'UTEND_GWDTOT' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_GWDTOT' , history_budget_histfile_num, ' ') + call add_default ( 'UTEND_QBORLX' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_QBORLX' , history_budget_histfile_num, ' ') + call add_default ( 'UTEND_LUNART' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_LUNART' , history_budget_histfile_num, ' ') + call add_default ( 'UTEND_IONDRG' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_IONDRG' , history_budget_histfile_num, ' ') + call add_default ( 'UTEND_NDG' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_NDG' , history_budget_histfile_num, ' ') + call add_default ( 'UTEND_CORE' , history_budget_histfile_num, ' ') + call add_default ( 'VTEND_CORE' , history_budget_histfile_num, ' ') + end if + + ducore_idx = pbuf_get_index('DUCORE') + dvcore_idx = pbuf_get_index('DVCORE') + end subroutine phys_init ! @@ -1286,7 +1363,7 @@ subroutine tphysac (ztodt, cam_in, & use perf_mod use flux_avg, only: flux_avg_run use unicon_cam, only: unicon_cam_org_diags - use cam_history, only: hist_fld_active + use cam_history, only: hist_fld_active, outfld use qneg_module, only: qneg4 use co2_cycle, only: co2_cycle_set_ptend use nudging, only: Nudge_Model,Nudge_ON,nudging_timestep_tend @@ -1345,6 +1422,8 @@ subroutine tphysac (ztodt, cam_in, & real(r8), pointer, dimension(:,:) :: cldliqini real(r8), pointer, dimension(:,:) :: cldiceini real(r8), pointer, dimension(:,:) :: dtcore + real(r8), pointer, dimension(:,:) :: ducore + real(r8), pointer, dimension(:,:) :: dvcore real(r8), pointer, dimension(:,:) :: ast ! relative humidity cloud fraction !----------------------------------------------------------------------- @@ -1369,6 +1448,8 @@ subroutine tphysac (ztodt, cam_in, & ifld = pbuf_get_index('DTCORE') call pbuf_get_field(pbuf, ifld, dtcore, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) ) + call pbuf_get_field(pbuf, ducore_idx, ducore, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) ) + call pbuf_get_field(pbuf, dvcore_idx, dvcore, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) ) call pbuf_get_field(pbuf, qini_idx, qini) call pbuf_get_field(pbuf, cldliqini_idx, cldliqini) @@ -1521,6 +1602,12 @@ subroutine tphysac (ztodt, cam_in, & (trim(cam_take_snapshot_before) == trim(cam_take_snapshot_after))) then call cam_snapshot_ptend_outfld(ptend, lchnk) end if + if ( ptend%lu ) then + call outfld( 'UTEND_VDIFF', ptend%u, pcols, lchnk) + end if + if ( ptend%lv ) then + call outfld( 'VTEND_VDIFF', ptend%v, pcols, lchnk) + end if call physics_update(state, ptend, ztodt, tend) if (trim(cam_take_snapshot_after) == "vertical_diffusion_section") then @@ -1535,6 +1622,12 @@ subroutine tphysac (ztodt, cam_in, & !=================================================== call t_startf('rayleigh_friction') call rayleigh_friction_tend( ztodt, state, ptend) + if ( ptend%lu ) then + call outfld( 'UTEND_RAYLEIGH', ptend%u, pcols, lchnk) + end if + if ( ptend%lv ) then + call outfld( 'VTEND_RAYLEIGH', ptend%v, pcols, lchnk) + end if call physics_update(state, ptend, ztodt, tend) call t_stopf('rayleigh_friction') @@ -1607,6 +1700,12 @@ subroutine tphysac (ztodt, cam_in, & (trim(cam_take_snapshot_before) == trim(cam_take_snapshot_after))) then call cam_snapshot_ptend_outfld(ptend, lchnk) end if + if ( ptend%lu ) then + call outfld( 'UTEND_GWDTOT', ptend%u, pcols, lchnk) + end if + if ( ptend%lv ) then + call outfld( 'VTEND_GWDTOT', ptend%v, pcols, lchnk) + end if call physics_update(state, ptend, ztodt, tend) if (trim(cam_take_snapshot_after) == "gw_tend") then @@ -1631,6 +1730,12 @@ subroutine tphysac (ztodt, cam_in, & (trim(cam_take_snapshot_before) == trim(cam_take_snapshot_after))) then call cam_snapshot_ptend_outfld(ptend, lchnk) end if + if ( ptend%lu ) then + call outfld( 'UTEND_QBORLX', ptend%u, pcols, lchnk) + end if + if ( ptend%lv ) then + call outfld( 'VTEND_QBORLX', ptend%v, pcols, lchnk) + end if call physics_update(state, ptend, ztodt, tend) if (trim(cam_take_snapshot_after) == "qbo_relax") then @@ -1643,6 +1748,12 @@ subroutine tphysac (ztodt, cam_in, & ! Lunar tides call lunar_tides_tend( state, ptend ) + if ( ptend%lu ) then + call outfld( 'UTEND_LUNART', ptend%u, pcols, lchnk) + end if + if ( ptend%lv ) then + call outfld( 'VTEND_LUNART', ptend%v, pcols, lchnk) + end if call physics_update(state, ptend, ztodt, tend) ! Check energy integrals call check_energy_chng(state, tend, "lunar_tides", nstep, ztodt, zero, zero, zero, zero) @@ -1671,6 +1782,12 @@ subroutine tphysac (ztodt, cam_in, & (trim(cam_take_snapshot_before) == trim(cam_take_snapshot_after))) then call cam_snapshot_ptend_outfld(ptend, lchnk) end if + if ( ptend%lu ) then + call outfld( 'UTEND_IONDRG', ptend%u, pcols, lchnk) + end if + if ( ptend%lv ) then + call outfld( 'VTEND_IONDRG', ptend%v, pcols, lchnk) + end if call physics_update(state, ptend, ztodt, tend) if (trim(cam_take_snapshot_after) == "iondrag_calc_section") then @@ -1696,6 +1813,12 @@ subroutine tphysac (ztodt, cam_in, & !---------------------------------- if((Nudge_Model).and.(Nudge_ON)) then call nudging_timestep_tend(state,ptend) + if ( ptend%lu ) then + call outfld( 'UTEND_NDG', ptend%u, pcols, lchnk) + end if + if ( ptend%lv ) then + call outfld( 'VTEND_NDG', ptend%v, pcols, lchnk) + end if call physics_update(state,ptend,ztodt,tend) call check_energy_chng(state, tend, "nudging", nstep, ztodt, zero, zero, zero, zero) endif @@ -1786,9 +1909,11 @@ subroutine tphysac (ztodt, cam_in, & !!! REMOVE THIS CALL, SINCE ONLY Q IS BEING ADJUSTED. WON'T BALANCE ENERGY. TE IS SAVED BEFORE THIS !!! call check_energy_chng(state, tend, "drymass", nstep, ztodt, zero, zero, zero, zero) - ! store T in buffer for use in computing dynamics T-tendency in next timestep + ! store T, U, and V in buffer for use in computing dynamics T-tendency in next timestep do k = 1,pver dtcore(:ncol,k) = state%t(:ncol,k) + ducore(:ncol,k) = state%u(:ncol,k) + dvcore(:ncol,k) = state%v(:ncol,k) end do !-------------- Energy budget checks ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1907,6 +2032,7 @@ subroutine tphysbc (ztodt, state, & ! type(physics_ptend) :: ptend ! indivdual parameterization tendencies + type(physics_ptend) :: ptend_macp_all ! sum of macrophysics tendencies (e.g. CLUBB) over substeps type(physics_state) :: state_sc ! state for sub-columns type(physics_ptend) :: ptend_sc ! ptend for sub-columns type(physics_ptend) :: ptend_aero ! ptend for microp_aero @@ -1946,6 +2072,8 @@ subroutine tphysbc (ztodt, state, & real(r8), pointer, dimension(:,:) :: cldliqini real(r8), pointer, dimension(:,:) :: cldiceini real(r8), pointer, dimension(:,:) :: dtcore + real(r8), pointer, dimension(:,:) :: ducore + real(r8), pointer, dimension(:,:) :: dvcore real(r8), pointer, dimension(:,:,:) :: fracis ! fraction of transported species that are insoluble @@ -2020,6 +2148,8 @@ subroutine tphysbc (ztodt, state, & ifld = pbuf_get_index('DTCORE') call pbuf_get_field(pbuf, ifld, dtcore, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) ) + call pbuf_get_field(pbuf, ducore_idx, ducore, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) ) + call pbuf_get_field(pbuf, dvcore_idx, dvcore, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) ) ifld = pbuf_get_index('FRACIS') call pbuf_get_field(pbuf, ifld, fracis, start=(/1,1,1/), kount=(/pcols, pver, pcnst/) ) @@ -2082,10 +2212,14 @@ subroutine tphysbc (ztodt, state, & call outfld('TEINP', state%te_ini, pcols, lchnk ) call outfld('TEFIX', state%te_cur, pcols, lchnk ) - ! T tendency due to dynamics + ! T, U, V tendency due to dynamics if( nstep > dyn_time_lvls-1 ) then dtcore(:ncol,:pver) = (state%t(:ncol,:pver) - dtcore(:ncol,:pver))/ztodt + ducore(:ncol,:pver) = (state%u(:ncol,:pver) - ducore(:ncol,:pver))/ztodt + dvcore(:ncol,:pver) = (state%v(:ncol,:pver) - dvcore(:ncol,:pver))/ztodt call outfld( 'DTCORE', dtcore, pcols, lchnk ) + call outfld( 'UTEND_CORE', ducore, pcols, lchnk ) + call outfld( 'VTEND_CORE', dvcore, pcols, lchnk ) end if call t_stopf('energy_fixer') @@ -2138,6 +2272,13 @@ subroutine tphysbc (ztodt, state, & (trim(cam_take_snapshot_before) == trim(cam_take_snapshot_after))) then call cam_snapshot_ptend_outfld(ptend, lchnk) end if + + if ( ptend%lu ) then + call outfld( 'UTEND_DCONV', ptend%u, pcols, lchnk) + end if + if ( ptend%lv ) then + call outfld( 'VTEND_DCONV', ptend%v, pcols, lchnk) + end if call physics_update(state, ptend, ztodt, tend) if (trim(cam_take_snapshot_after) == "convect_deep_tend") then @@ -2195,6 +2336,12 @@ subroutine tphysbc (ztodt, state, & (trim(cam_take_snapshot_before) == trim(cam_take_snapshot_after))) then call cam_snapshot_ptend_outfld(ptend, lchnk) end if + if ( ptend%lu ) then + call outfld( 'UTEND_SHCONV', ptend%u, pcols, lchnk) + end if + if ( ptend%lv ) then + call outfld( 'VTEND_SHCONV', ptend%v, pcols, lchnk) + end if call physics_update(state, ptend, ztodt, tend) if (trim(cam_take_snapshot_after) == "convect_shallow_tend") then @@ -2273,6 +2420,10 @@ subroutine tphysbc (ztodt, state, & prec_pcw_macmic = 0._r8 snow_pcw_macmic = 0._r8 + ! initialize ptend structures where macro and microphysics tendencies are + ! accumulated over macmic substeps + call physics_ptend_init(ptend_macp_all,state%psetcols,'macrophysics',lu=.true.,lv=.true.) + do macmic_it = 1, cld_macmic_num_steps !=================================================== @@ -2312,6 +2463,7 @@ subroutine tphysbc (ztodt, state, & (trim(cam_take_snapshot_before) == trim(cam_take_snapshot_after))) then call cam_snapshot_ptend_outfld(ptend, lchnk) end if + call physics_ptend_sum(ptend,ptend_macp_all,ncol) call physics_update(state, ptend, ztodt, tend) if (trim(cam_take_snapshot_after) == "macrop_driver_tend") then @@ -2357,6 +2509,7 @@ subroutine tphysbc (ztodt, state, & (trim(cam_take_snapshot_before) == trim(cam_take_snapshot_after))) then call cam_snapshot_ptend_outfld(ptend, lchnk) end if + call physics_ptend_sum(ptend,ptend_macp_all,ncol) call physics_update(state, ptend, ztodt, tend) if (trim(cam_take_snapshot_after) == "clubb_tend_cam") then @@ -2505,6 +2658,10 @@ subroutine tphysbc (ztodt, state, & end do ! end substepping over macrophysics/microphysics + call outfld( 'UTEND_MACROP', ptend_macp_all%u, pcols, lchnk) + call outfld( 'VTEND_MACROP', ptend_macp_all%v, pcols, lchnk) + call physics_ptend_dealloc(ptend_macp_all) + prec_sed(:ncol) = prec_sed_macmic(:ncol)/cld_macmic_num_steps snow_sed(:ncol) = snow_sed_macmic(:ncol)/cld_macmic_num_steps prec_pcw(:ncol) = prec_pcw_macmic(:ncol)/cld_macmic_num_steps