From b47246dedfa7c377ac2bfb060e2d465beb931f2a Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Thu, 22 Jan 2026 09:10:38 -0700 Subject: [PATCH] Update CAM4 physics suite for SIMA aquaplanet configurations (#349) Originator(s): nusbaume Description (include issue title and the keyword ['closes', 'fixes', 'resolves'] and issue number): Add namelist modifications and additional helper schemes in order to run the full CAM4 physics suite in CAM-SIMA in aquaplanet mode. List all namelist files that were added or changed: A schemes/radiation_utils/radiative_gas_concentrations_namelist.xml - New namelist variable to set the concentrations of radiatively active gases. M schemes/cloud_fraction/compute_cloud_fraction_namelist.xml M schemes/gravity_wave_drag/gw_common_namelist.xml M schemes/radiation_utils/solar_irradiance_data_namelist.xml M schemes/rrtmgp/rrtmgp_constituents_namelist.xml M schemes/zhang_mcfarlane/zm_conv_options_namelist.xml - Add new namelist values for CAM4 and/or aquaplanet CAM-SIMA configurations. List all files eliminated and why: N/A List all files added and what they do: A schemes/radiation_utils/radiative_gas_concentrations.F90 A schemes/radiation_utils/radiative_gas_concentrations.meta - New scheme which sets the global concentrations of radiatively active gases using hardcoded namelist values. A schemes/utilities/set_surface_coupling_vars.F90 A schemes/utilities/set_surface_coupling_vars.meta - New scheme which sets the outgoing (i.e. `cam_out`) coupler variables. List all existing files that have been modified, and describe the changes: (Helpful git command: `git diff --name-status development...`) M schemes/rasch_kristjansson/prognostic_cloud_water.F90 - Move subroutine call outside of loop to improve performance (found during CAM4 aquaplanet debugging). M suites/suite_cam4.xml - Update CAM4 suite to allow for a complete CAM4 physics run in CAM-SIMA when in aquaplanet mode. M suites/suite_cam7.xml - Add commented-out 'set_surface_coupling_vars' scheme, as it will be needed for an eventual CAM7 simulation in CAM-SIMA. List all automated tests that failed, as well as an explanation for why they weren't fixed: Is this an answer-changing PR? If so, is it a new physics package, algorithm change, tuning change, etc? Yes, at least for full physics CAM4 aquaplanet simulations. This PR introduces new schemes and namelist values to the CAM4 physics suite, which is what allows this configuration to run in CAM-SIMA. If yes to the above question, describe how this code was validated with the new/modified features: Performed a short, three month run and examined the model output, at least for some generic state variables (U,V,T,Q,PS). All of the results seemed reasonable, and the model successfully ran to completion. --------- Co-authored-by: peverwhee Co-authored-by: Cheryl Craig Co-authored-by: Courtney Peverley Co-authored-by: John Truesdale Co-authored-by: Haipeng Lin Co-authored-by: Jian Sun Co-authored-by: Haipeng Lin --- .../compute_cloud_fraction_namelist.xml | 1 + .../gravity_wave_drag/gw_common_namelist.xml | 4 + ...prescribe_radiative_gas_concentrations.F90 | 184 ++++++++++++++ ...rescribe_radiative_gas_concentrations.meta | 56 ++++ ..._radiative_gas_concentrations_namelist.xml | 157 ++++++++++++ .../solar_irradiance_data_namelist.xml | 7 +- .../prognostic_cloud_water.F90 | 6 +- .../rrtmgp/rrtmgp_constituents_namelist.xml | 19 +- .../utilities/set_surface_coupling_vars.F90 | 201 +++++++++++++++ .../utilities/set_surface_coupling_vars.meta | 240 ++++++++++++++++++ .../vertical_diffusion_sponge_layer.meta | 12 + .../zm_conv_options_namelist.xml | 4 + suites/suite_cam4.xml | 34 ++- suites/suite_cam7.xml | 8 +- 14 files changed, 916 insertions(+), 17 deletions(-) create mode 100644 schemes/radiation_utils/prescribe_radiative_gas_concentrations.F90 create mode 100644 schemes/radiation_utils/prescribe_radiative_gas_concentrations.meta create mode 100644 schemes/radiation_utils/prescribe_radiative_gas_concentrations_namelist.xml create mode 100644 schemes/utilities/set_surface_coupling_vars.F90 create mode 100644 schemes/utilities/set_surface_coupling_vars.meta diff --git a/schemes/cloud_fraction/compute_cloud_fraction_namelist.xml b/schemes/cloud_fraction/compute_cloud_fraction_namelist.xml index 18c511bd..f91074fe 100644 --- a/schemes/cloud_fraction/compute_cloud_fraction_namelist.xml +++ b/schemes/cloud_fraction/compute_cloud_fraction_namelist.xml @@ -133,6 +133,7 @@ 0.900D0 0.8975D0 0.8975D0 + 0.910D0 diff --git a/schemes/gravity_wave_drag/gw_common_namelist.xml b/schemes/gravity_wave_drag/gw_common_namelist.xml index 167d9543..1cc191ab 100644 --- a/schemes/gravity_wave_drag/gw_common_namelist.xml +++ b/schemes/gravity_wave_drag/gw_common_namelist.xml @@ -32,6 +32,7 @@ 2.5D0 + 0.D0 @@ -47,6 +48,7 @@ 10 + 0 @@ -63,6 +65,7 @@ 2.0D0 + 0.D0 @@ -94,6 +97,7 @@ .true. + .false. diff --git a/schemes/radiation_utils/prescribe_radiative_gas_concentrations.F90 b/schemes/radiation_utils/prescribe_radiative_gas_concentrations.F90 new file mode 100644 index 00000000..3fe7411a --- /dev/null +++ b/schemes/radiation_utils/prescribe_radiative_gas_concentrations.F90 @@ -0,0 +1,184 @@ +!------------------------------------------------------------------------------- +! This module uses namelist variable to set prescribed concentrations +! for radiatively-active gases. + +! Eventually this module should be replaced with a more comprehensive atmospheric +! composition/chemistry system, but is fine to use for now when running low-top, +! non-exoplanet CAM-SIMA configurations with minimal chemistry. +!------------------------------------------------------------------------------- +module prescribe_radiative_gas_concentrations + + implicit none + + private + public :: prescribe_radiative_gas_concentrations_init + + +!------------------------------------------------------------------------------- +contains +!------------------------------------------------------------------------------- + +!> \section arg_table_prescribe_radiative_gas_concentrations_init Argument Table +!! \htmlinclude prescribe_radiative_gas_concentrations_init.html +!! + subroutine prescribe_radiative_gas_concentrations_init(ch4_vmr, co2_vmr, cfc11_vmr, & + cfc12_vmr, n2o_vmr, const_array, & + errmsg, errcode) + + ! Use statements + use ccpp_constituent_prop_mod, only: int_unassigned + use ccpp_scheme_utils, only: ccpp_constituent_index + use ccpp_kinds, only: kind_phys + + ! Use statement from RRTMGP, + ! which should hopefully be replaced once + ! molar masses for these species are included + ! in the constituents properties themselves: + use radiation_utils, only: get_molar_mass_ratio + + + ! Input arguments + real(kind_phys), intent(in) :: ch4_vmr + real(kind_phys), intent(in) :: co2_vmr + real(kind_phys), intent(in) :: cfc11_vmr + real(kind_phys), intent(in) :: cfc12_vmr + real(kind_phys), intent(in) :: n2o_vmr + + ! Input/output arguments + real(kind_phys), intent(inout) :: const_array(:,:,:) ! Constituents array + + ! Output arguments + character(len=512), intent(out) :: errmsg + integer, intent(out) :: errcode + + ! Local variables + integer :: const_idx !Constituents object index + real(kind_phys) :: dry_air_to_const_molar_mass_ratio !Ratio of dry air molar mass to constituent molar mass + + !+++++++++++++++++++++++++++++++++++ + ! Convert number/mole fraction into + ! mass mixing ratio w.r.t dry air + !+++++++++++++++++++++++++++++++++++ + + !---- + ! CH4: + !---- + + ! Check if CH4 is present in constituents object: + call ccpp_constituent_index('CH4', const_idx, errcode, errmsg) + if (errcode /= 0) then + return + else if (const_idx /= int_unassigned) then + + ! Get ratio of molar mass of dry air / constituent molar mass + call get_molar_mass_ratio('CH4', dry_air_to_const_molar_mass_ratio, errmsg, errcode) + if (errcode /= 0) then + return + end if + + ! Convert namelist-provided number/mole fraction to + ! mass mixing ratio w.r.t. dry air, and set constituents + ! array to new coonverted value: + const_array(:,:,const_idx) = ch4_vmr*dry_air_to_const_molar_mass_ratio + + end if + + !---- + ! CO2: + !---- + + ! Check if CO2 is present in constituents object: + call ccpp_constituent_index('CO2', const_idx, errcode, errmsg) + if (errcode /= 0) then + return + else if (const_idx /= int_unassigned) then + + ! Get ratio of molar mass of dry air / constituent molar mass + call get_molar_mass_ratio('CO2', dry_air_to_const_molar_mass_ratio, errmsg, errcode) + if (errcode /= 0) then + return + end if + + ! Convert namelist-provided number/mole fraction to + ! mass mixing ratio w.r.t. dry air, and set constituents + ! array to new coonverted value: + const_array(:,:,const_idx) = co2_vmr*dry_air_to_const_molar_mass_ratio + + end if + + !------ + ! CFC11: + !------ + + ! Check if CFC-11 is present in constituents object: + call ccpp_constituent_index('CFC11', const_idx, errcode, errmsg) + if (errcode /= 0) then + return + else if (const_idx /= int_unassigned) then + + ! Get ratio of molar mass of dry air / constituent molar mass + call get_molar_mass_ratio('CFC11', dry_air_to_const_molar_mass_ratio, errmsg, errcode) + if (errcode /= 0) then + return + end if + + ! Convert namelist-provided number/mole fraction to + ! mass mixing ratio w.r.t. dry air, and set constituents + ! array to new coonverted value: + const_array(:,:,const_idx) = cfc11_vmr*dry_air_to_const_molar_mass_ratio + + end if + + !------ + ! CFC12: + !------ + + ! Check if CFC-12 is present in constituents object: + call ccpp_constituent_index('CFC12', const_idx, errcode, errmsg) + if (errcode /= 0) then + return + else if (const_idx /= int_unassigned) then + + ! Get ratio of molar mass of dry air / constituent molar mass + call get_molar_mass_ratio('CFC12', dry_air_to_const_molar_mass_ratio, errmsg, errcode) + if (errcode /= 0) then + return + end if + + ! Convert namelist-provided number/mole fraction to + ! mass mixing ratio w.r.t. dry air, and set constituents + ! array to new coonverted value: + const_array(:,:,const_idx) = cfc12_vmr*dry_air_to_const_molar_mass_ratio + + end if + + !---- + ! N2O: + !---- + + ! Check if N2O is present in constituents object: + call ccpp_constituent_index('N2O', const_idx, errcode, errmsg) + if (errcode /= 0) then + return + else if (const_idx /= int_unassigned) then + + ! Get ratio of molar mass of dry air / constituent molar mass + call get_molar_mass_ratio('N2O', dry_air_to_const_molar_mass_ratio, errmsg, errcode) + if (errcode /= 0) then + return + end if + + ! Convert namelist-provided number/mole fraction to + ! mass mixing ratio w.r.t. dry air, and set constituents + ! array to new coonverted value: + const_array(:,:,const_idx) = n2o_vmr*dry_air_to_const_molar_mass_ratio + + end if + + ! Set error variables + errmsg = '' + errcode = 0 + + end subroutine prescribe_radiative_gas_concentrations_init + +end module prescribe_radiative_gas_concentrations \ No newline at end of file diff --git a/schemes/radiation_utils/prescribe_radiative_gas_concentrations.meta b/schemes/radiation_utils/prescribe_radiative_gas_concentrations.meta new file mode 100644 index 00000000..55be49a4 --- /dev/null +++ b/schemes/radiation_utils/prescribe_radiative_gas_concentrations.meta @@ -0,0 +1,56 @@ +[ccpp-table-properties] + name = prescribe_radiative_gas_concentrations + type = scheme + dependencies = ../rrtmgp/utils/radiation_utils.F90 + +[ccpp-arg-table] + name = prescribe_radiative_gas_concentrations_init + type = scheme +[ ch4_vmr ] + standard_name = prescribed_volume_mixing_ratio_of_ch4 + units = mol mol-1 + type = real | kind = kind_phys + dimensions = () + intent = in +[ co2_vmr ] + standard_name = prescribed_volume_mixing_ratio_of_co2 + units = mol mol-1 + type = real | kind = kind_phys + dimensions = () + intent = in +[ cfc11_vmr ] + standard_name = prescribed_volume_mixing_ratio_of_cfc11 + units = mol mol-1 + type = real | kind = kind_phys + dimensions = () + intent = in +[ cfc12_vmr ] + standard_name = prescribed_volume_mixing_ratio_of_cfc12 + units = mol mol-1 + type = real | kind = kind_phys + dimensions = () + intent = in +[ n2o_vmr ] + standard_name = prescribed_volume_mixing_ratio_of_n2o + units = mol mol-1 + type = real | kind = kind_phys + dimensions = () + intent = in +[ const_array ] + standard_name = ccpp_constituents + units = none + type = real | kind = kind_phys + dimensions = (horizontal_dimension,vertical_layer_dimension,number_of_ccpp_constituents) + intent = inout +[ errmsg ] + standard_name = ccpp_error_message + units = none + type = character | kind = len=512 + dimensions = () + intent = out +[ errcode ] + standard_name = ccpp_error_code + units = 1 + type = integer + dimensions = () + intent = out diff --git a/schemes/radiation_utils/prescribe_radiative_gas_concentrations_namelist.xml b/schemes/radiation_utils/prescribe_radiative_gas_concentrations_namelist.xml new file mode 100644 index 00000000..7134e532 --- /dev/null +++ b/schemes/radiation_utils/prescribe_radiative_gas_concentrations_namelist.xml @@ -0,0 +1,157 @@ + + + + + + + + + real + kind_phys + ghg_cam + chem_surfvals + prescribed_volume_mixing_ratio_of_ch4 + mol mol-1 + + CH4 volume mixing ratio. This is used as the time invariant value + of CH4 if no time varying values are specified. + + + 1760.0e-9 + 1650.0e-9 + + + + real + kind_phys + ghg_cam + chem_surfvals + prescribed_volume_mixing_ratio_of_co2 + mol mol-1 + + CO2 volume mixing ratio. This is used as the time invariant value + of CO2 if no time varying values are specified. + + + 367.0e-6 + 348.0e-6 + + + + real + kind_phys + ghg_cam + chem_surfvals + prescribed_volume_mixing_ratio_of_cfc11 + mol mol-1 + + CFC-11 volume mixing ratio. This is used as the time invariant value + of CFC-11 if no time varying values are specified. + + + 653.45e-12 + + + + real + kind_phys + ghg_cam + chem_surfvals + prescribed_volume_mixing_ratio_of_cfc12 + mol mol-1 + + CFC-12 volume mixing ratio. This is used as the time invariant value + of CFC-12 if no time varying values are specified. + + + 535.0e-12 + + + + real + kind_phys + ghg_cam + chem_surfvals + prescribed_volume_mixing_ratio_of_n2o + mol mol-1 + + N2O volume mixing ratio. This is used as the time invariant value + of N2O if no time varying values are specified. + + + 316.0e-9 + 306.0e-9 + + + + diff --git a/schemes/radiation_utils/solar_irradiance_data_namelist.xml b/schemes/radiation_utils/solar_irradiance_data_namelist.xml index f1bfce2c..680eaeef 100644 --- a/schemes/radiation_utils/solar_irradiance_data_namelist.xml +++ b/schemes/radiation_utils/solar_irradiance_data_namelist.xml @@ -82,10 +82,13 @@ filename_of_solar_irradiance_data none - The filename of the solar irradiance data. + The filename of the solar irradiance data. If the file + path is set to "NONE" then it is assumed that a + constant solar irradiance is being used. ${DIN_LOC_ROOT}/atm/cam/solar/SolarForcingCMIP7piControl_c20250103.nc + NONE @@ -112,6 +115,7 @@ .true. + .false. @@ -152,6 +156,7 @@ -9999D0 + 1365.0 diff --git a/schemes/rasch_kristjansson/prognostic_cloud_water.F90 b/schemes/rasch_kristjansson/prognostic_cloud_water.F90 index d2f4d117..b239b42d 100644 --- a/schemes/rasch_kristjansson/prognostic_cloud_water.F90 +++ b/schemes/rasch_kristjansson/prognostic_cloud_water.F90 @@ -513,9 +513,13 @@ subroutine prognostic_cloud_water_run( & ! The cloud microphysics is highly nonlinear and coupled with qme ! Both rain processes and qme are calculated iteratively. qme_iter_loop: do l = 1, iter + + ! Adjust relative humidity above the tropopause in higher + ! latitude regions: + call relhum_min_adj(ncol, pver, tropLev, dlat, rhu00, rhu_adj) + qme_update_loop: do i = 1, ncol ! calculation of qme has 4 scenarios - call relhum_min_adj(ncol, pver, tropLev, dlat, rhu00, rhu_adj) if(relhum(i) > rhu_adj(i,k)) then ! 1. whole grid saturation diff --git a/schemes/rrtmgp/rrtmgp_constituents_namelist.xml b/schemes/rrtmgp/rrtmgp_constituents_namelist.xml index 670c2c82..8720ed53 100644 --- a/schemes/rrtmgp/rrtmgp_constituents_namelist.xml +++ b/schemes/rrtmgp/rrtmgp_constituents_namelist.xml @@ -86,7 +86,24 @@ calculation in RRTMGP (H2O not included because it is assumed to be advected if present). - 'N:O2:O2', 'A:CO2:CO2', 'N:ozone:O3', 'A:N2O:N2O', 'A:CH4:CH4', 'N:CFC11STAR:CFC11', 'A:CFC12:CFC12' + + 'N:O2:O2', + 'A:CO2:CO2', + 'N:ozone:O3', + 'A:N2O:N2O', + 'A:CH4:CH4', + 'N:CFC11STAR:CFC11', + 'A:CFC12:CFC12' + + + 'N:O2:O2', + 'N:CO2:CO2', + 'N:ozone:O3', + 'N:N2O:N2O', + 'N:CH4:CH4', + 'N:CFC11:CFC11', + 'N:CFC12:CFC12' + diff --git a/schemes/utilities/set_surface_coupling_vars.F90 b/schemes/utilities/set_surface_coupling_vars.F90 new file mode 100644 index 00000000..6e2eed6f --- /dev/null +++ b/schemes/utilities/set_surface_coupling_vars.F90 @@ -0,0 +1,201 @@ +!----------------------------------------------------------------------- +! Module to handle data that is exchanged between the atmosphere +! model and the surface models (land, sea-ice, ocean, etc.). + +! Please note that currently this is a SIMA-specific module, +! but could be made more host model-independent in the future. +!----------------------------------------------------------------------- +module set_surface_coupling_vars + + implicit none + private + + ! Public interfaces + public :: set_surface_coupling_vars_run + +!=============================================================================== +CONTAINS +!=============================================================================== + +!> \section arg_table_set_surface_coupling_vars_run Argument Table +!! \htmlinclude set_surface_coupling_vars_run.html +!! +subroutine set_surface_coupling_vars_run(ncol, pver, ncnst, gravit, rair, phis, & + surf_pres, air_temp, inv_ps_exner, zm, & + rho, uwnd, vwnd, air_pres, cnst_array, & + prec_dp, snow_dp, prec_sh, snow_sh, & + prec_str, snow_str, air_temp_bot, & + pot_temp_bot, zm_bot, rho_bot, & + uwnd_bot, vwnd_bot, air_pres_bot, & + topo_height, sea_lev_pres, cnst_bot, & + conv_prec, conv_snow, strat_prec, & + strat_snow, errmsg, errcode) + + ! Set surface variables needed for atmosphere-surface coupling. + + ! Use statements + use ccpp_kinds, only: kind_phys + + ! Input arguments + integer, intent(in) :: ncol + integer, intent(in) :: pver + integer, intent(in) :: ncnst + + real(kind_phys), intent(in) :: gravit ! Gravitational acceleration [m s-2] + real(kind_phys), intent(in) :: rair ! Dry air gas constant [J kg-1 K-1] + real(kind_phys), intent(in) :: phis(:) ! Surface geopotential [m2 s-2] + real(kind_phys), intent(in) :: surf_pres(:) ! Surface pressure [Pa] + real(kind_phys), intent(in) :: air_temp(:,:) ! Air temperature [K] + real(kind_phys), intent(in) :: inv_ps_exner(:,:) ! Inverse Exner function w.r.t. surface pressure [1] + real(kind_phys), intent(in) :: zm(:,:) ! Geopotential height wrt surface [m] + real(kind_phys), intent(in) :: rho(:,:) ! Dry air density [kg m-3] + real(kind_phys), intent(in) :: uwnd(:,:) ! Eastward wind [m s-1] + real(kind_phys), intent(in) :: vwnd(:,:) ! Northward wind [m s-1] + real(kind_phys), intent(in) :: air_pres(:,:) ! Air pressure [Pa] + real(kind_phys), intent(in) :: cnst_array(:,:,:) ! CCPP constituents array [none] + + real(kind_phys), intent(in) :: prec_dp(:) ! LWE deep convective precipitation (all phases) [m s-1] + real(kind_phys), intent(in) :: snow_dp(:) ! LWE deep convective frozen precipitation (e.g. snow) [m s-1] + real(kind_phys), intent(in) :: prec_sh(:) ! LWE shallow convective precipitation (all phases) [m s-1] + real(kind_phys), intent(in) :: snow_sh(:) ! LWE shallow convective frozen precipitation (all phases) [m s-1] + real(kind_phys), intent(in) :: prec_str(:) ! LWE stratiform precipitation (all phases) [m s-1] + real(kind_phys), intent(in) :: snow_str(:) ! LWE stratiform frozen precipitation (e.g. snow) [m s-1] + + ! Output arguments + real(kind_phys), intent(out) :: air_temp_bot(:) ! Air temperature at bottom of atmosphere for coupling [K] + real(kind_phys), intent(out) :: pot_temp_bot(:) ! Potential air temprature at bottom of atmosphere for coupling [K] + real(kind_phys), intent(out) :: zm_bot(:) ! Geopotential height wrt surface at bottom of atmosphere for coupling [m] + real(kind_phys), intent(out) :: rho_bot(:) ! Dry air density at bottom of atmosphere for coupling [kg m-3] + real(kind_phys), intent(out) :: uwnd_bot(:) ! Eastward wind at bottom of atmosphere for coupling [m s-1] + real(kind_phys), intent(out) :: vwnd_bot(:) ! Northward wind at bottom of atmosphere for coupling [m s-1] + real(kind_phys), intent(out) :: air_pres_bot(:) ! Air pressure at bottom of atmosphere for coupling [Pa] + real(kind_phys), intent(out) :: topo_height(:) ! Geopotential height of surface topography [m] + real(kind_phys), intent(out) :: sea_lev_pres(:) ! Sea Level Pressure [Pa] + real(kind_phys), intent(out) :: cnst_bot(:,:) ! Constituent mixing ratios at bottom of atmosphere for coupling [kg kg-1] + + real(kind_phys), intent(out) :: conv_prec(:) ! LWE Convective precipitation (all phases) [m s-1] + real(kind_phys), intent(out) :: conv_snow(:) ! LWE Frozen convective precipitation (e.g. snow) [m s-1] + real(kind_phys), intent(out) :: strat_prec(:) ! LWE Stratiform (large-scale) precipitation (all phases) [m s-1] + real(kind_phys), intent(out) :: strat_snow(:) ! LWE Frozen stratiform (large-scale)precipitation (e.g. snow) [m s-1] + + character(len=512), intent(out) :: errmsg ! CCPP error message + integer, intent(out) :: errcode ! CCPP error code + + ! Local variables + + integer :: i ! column index + integer :: m ! constituent index + + !----------------------------------------------------------------------- + + errmsg = '' + errcode = 0 + + ! Copy over atmospheric 3-D variables to surface fields: + do i=1,ncol + air_temp_bot(i) = air_temp(i,pver) + pot_temp_bot(i) = air_temp(i,pver) * inv_ps_exner(i,pver) + zm_bot(i) = zm(i,pver) + rho_bot(i) = rho(i,pver) + uwnd_bot(i) = uwnd(i,pver) + vwnd_bot(i) = vwnd(i,pver) + air_pres_bot(i) = air_pres(i,pver) + topo_height(i) = phis(i)/gravit + end do + + ! Calculate Sea Level Pressure (PSL): + call calc_sea_level_pressure(ncol, gravit, rair, air_pres_bot, phis, & + surf_pres, air_temp_bot, sea_lev_pres) + + ! Set surface constituent values: + do m = 1, ncnst + do i = 1, ncol + cnst_bot(i,m) = cnst_array(i,pver,m) + end do + end do + + ! + ! Precipation and snow rates from shallow convection, deep convection and stratiform processes. + ! Compute total convective and stratiform precipitation and snow rates + ! + do i=1,ncol + conv_prec(i) = prec_dp(i) + prec_sh(i) + conv_snow(i) = snow_dp(i) + snow_sh(i) + + strat_prec(i) = prec_str(i) !Might be better to have microphysics set these directly + strat_snow(i) = snow_str(i) + end do + +end subroutine set_surface_coupling_vars_run + +!*************************************************** +! private subroutine to calculate sea level pressure +!*************************************************** + +subroutine calc_sea_level_pressure(ncol, gravit, rair, pbot, phis, ps, tbot, psl) + +!----------------------------------------------------------------------- +! +! Compute sea level pressure. +! +! Uses ECMWF formulation Algorithm: See section 3.1.b in NCAR NT-396 "Vertical +! Interpolation and Truncation of Model-Coordinate Data +! +!----------------------------------------------------------------------- + + ! Use statements + use ccpp_kinds, only: kind_phys + + !-----------------------------Arguments--------------------------------- + integer , intent(in) :: ncol ! longitude dimension + + real(kind_phys), intent(in) :: gravit ! Gravitational acceleration [m s-2] + real(kind_phys), intent(in) :: rair ! gas constant for dry air [J kg-1 K-1] + real(kind_phys), intent(in) :: pbot(:) ! Bottom layer atmospheric pressure [Pa] + real(kind_phys), intent(in) :: phis(:) ! Surface geopotential [m2 s-2] + real(kind_phys), intent(in) :: ps(:) ! Surface air pressure [Pa] + real(kind_phys), intent(in) :: Tbot(:) ! Bottom layer Atmospheric temperature [K] + + real(kind_phys), intent(out):: psl(:) ! Sea level pressures [Pa] + + !-----------------------------Parameters-------------------------------- + real(kind_phys), parameter :: xlapse = 6.5e-3_kind_phys ! Temperature lapse rate [K m-1] + + !-----------------------------Local Variables--------------------------- + integer :: i ! Loop index + real(kind_phys) :: alpha ! Temperature lapse rate in terms of pressure ratio (unitless) + real(kind_phys) :: Tstar ! Computed surface temperature + real(kind_phys) :: TT0 ! Computed temperature at sea-level + real(kind_phys) :: alph ! Power to raise P/Ps to get rate of increase of T with pressure + real(kind_phys) :: beta ! alpha*phis/(R*T) term used in approximation of PSL + !----------------------------------------------------------------------- + + alpha = rair*xlapse/gravit + do i=1,ncol + if ( abs(phis(i)/gravit) < 1.e-4_kind_phys )then + psl(i)=ps(i) + else + Tstar=Tbot(i)*(1._kind_phys+alpha*(ps(i)/pbot(i)-1._kind_phys)) ! pg 7 eq 5 + + TT0=Tstar + xlapse*phis(i)/gravit ! pg 8 eq 13 + + if ( Tstar<=290.5_kind_phys .and. TT0>290.5_kind_phys ) then ! pg 8 eq 14.1 + alph=rair/phis(i)*(290.5_kind_phys-Tstar) + else if (Tstar>290.5_kind_phys .and. TT0>290.5_kind_phys) then ! pg 8 eq 14.2 + alph=0._kind_phys + Tstar= 0.5_kind_phys * (290.5_kind_phys + Tstar) + else + alph=alpha + if (Tstar<255._kind_phys) then + Tstar= 0.5_kind_phys * (255._kind_phys + Tstar) ! pg 8 eq 14.3 + end if + end if + + beta = phis(i)/(rair*Tstar) + psl(i)=ps(i)*exp( beta*(1._kind_phys-alph*beta/2._kind_phys+((alph*beta)**2)/3._kind_phys)) + end if + end do + +end subroutine calc_sea_level_pressure + +end module set_surface_coupling_vars diff --git a/schemes/utilities/set_surface_coupling_vars.meta b/schemes/utilities/set_surface_coupling_vars.meta new file mode 100644 index 00000000..73f32544 --- /dev/null +++ b/schemes/utilities/set_surface_coupling_vars.meta @@ -0,0 +1,240 @@ +[ccpp-table-properties] + name = set_surface_coupling_vars + type = scheme + +[ccpp-arg-table] + name = set_surface_coupling_vars_run + type = scheme + +#---------------- +#Input Arguments +#---------------- + +[ ncol ] + standard_name = horizontal_loop_extent + units = count + type = integer + dimensions = () + intent = in +[ pver ] + standard_name = vertical_layer_dimension + units = count + type = integer + dimensions = () + intent = in +[ ncnst ] + standard_name = number_of_ccpp_constituents + units = count + type = integer + dimensions = () + intent = in +[ gravit ] + standard_name = standard_gravitational_acceleration + units = m s-2 + type = real | kind = kind_phys + dimensions = () + intent = in +[ rair ] + standard_name = gas_constant_of_dry_air + units = J kg-1 K-1 + type = real | kind = kind_phys + dimensions = () + intent = in +[ phis ] + standard_name = surface_geopotential + type = real | kind = kind_phys + units = m2 s-2 + dimensions = (horizontal_loop_extent) + intent = in +[ surf_pres ] + standard_name = surface_air_pressure + type = real | kind = kind_phys + units = Pa + dimensions = (horizontal_loop_extent) + intent = in +[ air_temp ] + standard_name = air_temperature + type = real | kind = kind_phys + units = K + dimensions = (horizontal_loop_extent, vertical_layer_dimension) + intent = in +[ inv_ps_exner ] + standard_name = reciprocal_of_dimensionless_exner_function_wrt_surface_air_pressure + units = 1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent, vertical_layer_dimension) + intent = in +[ zm ] + standard_name = geopotential_height_wrt_surface + type = real | kind = kind_phys + units = m + dimensions = (horizontal_loop_extent, vertical_layer_dimension) + intent = in +[ rho ] + standard_name = dry_air_density + units = kg m-3 + dimensions = (horizontal_loop_extent, vertical_layer_dimension) + type = real | kind = kind_phys + intent = in +[ uwnd ] + standard_name = eastward_wind + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent, vertical_layer_dimension) + intent = in +[ vwnd ] + standard_name = northward_wind + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent, vertical_layer_dimension) + intent = in +[ air_pres ] + standard_name = air_pressure + units = Pa + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent, vertical_layer_dimension) + intent = in +[ cnst_array ] + standard_name = ccpp_constituents + units = none + dimensions = (horizontal_loop_extent, vertical_layer_dimension, number_of_ccpp_constituents) + type = real | kind = kind_phys + intent = in +[ prec_dp ] + standard_name = lwe_precipitation_rate_at_surface_due_to_deep_convection + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = in +[ snow_dp ] + standard_name = lwe_frozen_precipitation_rate_at_surface_due_to_deep_convection + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = in +[ prec_sh ] + standard_name = lwe_precipitation_rate_at_surface_due_to_shallow_convection + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = in +[ snow_sh ] + standard_name = lwe_frozen_precipitation_rate_at_surface_due_to_shallow_convection + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = in +[ prec_str ] + standard_name = lwe_large_scale_precipitation_rate_at_surface + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = in +[ snow_str ] + standard_name = lwe_snow_and_cloud_ice_precipitation_rate_at_surface_due_to_microphysics + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = in + +#---------------- +#Output Arguments +#---------------- + +[ air_temp_bot ] + standard_name = air_temperature_at_bottom_layer_to_coupler + units = K + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ pot_temp_bot ] + standard_name = potential_temperature_wrt_surface_pressure_at_bottom_layer_to_coupler + units = K + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ zm_bot ] + standard_name = geopotential_height_wrt_surface_at_bottom_layer_to_coupler + units = m + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ rho_bot ] + standard_name = dry_air_density_at_bottom_layer_to_coupler + units = kg m-3 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ uwnd_bot ] + standard_name = eastward_wind_at_bottom_layer_to_coupler + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ vwnd_bot ] + standard_name = northward_wind_at_bottom_layer_to_coupler + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ air_pres_bot ] + standard_name = air_pressure_at_bottom_layer_to_coupler + units = Pa + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ topo_height ] + standard_name = surface_topographic_height_to_coupler + units = m + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ sea_lev_pres ] + standard_name = air_pressure_at_sea_level_to_coupler + units = Pa + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ cnst_bot ] + standard_name = constituent_mixing_ratio_at_bottom_layer_to_coupler + units = kg kg-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent, number_of_ccpp_constituents) + intent = out +[ conv_prec ] + standard_name = lwe_convective_precipitation_rate_at_surface_to_coupler + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ conv_snow ] + standard_name = lwe_convective_snowfall_rate_at_surface_to_coupler + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ strat_prec ] + standard_name = lwe_large_scale_precipitation_rate_at_surface_to_coupler + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ strat_snow ] + standard_name = lwe_large_scale_snowfall_rate_at_surface_to_coupler + units = m s-1 + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent) + intent = out +[ errmsg ] + standard_name = ccpp_error_message + units = none + type = character | kind = len=512 + dimensions = () + intent = out +[ errcode ] + standard_name = ccpp_error_code + units = 1 + type = integer + dimensions = () + intent = out + diff --git a/schemes/vertical_diffusion/vertical_diffusion_sponge_layer.meta b/schemes/vertical_diffusion/vertical_diffusion_sponge_layer.meta index d091f95c..9ee426cf 100644 --- a/schemes/vertical_diffusion/vertical_diffusion_sponge_layer.meta +++ b/schemes/vertical_diffusion/vertical_diffusion_sponge_layer.meta @@ -23,6 +23,12 @@ dimensions = () type = real | kind = kind_phys intent = in +[ diff_sponge_fac ] + standard_name = scale_factor_for_sponge_layer_vertical_diffusion + units = 1 + dimensions = () + type = real | kind = kind_phys + intent = in [ errmsg ] standard_name = ccpp_error_message units = none @@ -51,6 +57,12 @@ dimensions = () type = integer intent = in +[ diff_sponge_fac ] + standard_name = scale_factor_for_sponge_layer_vertical_diffusion + units = 1 + dimensions = () + type = real | kind = kind_phys + intent = in [ kvm ] standard_name = eddy_momentum_diffusivity_at_interfaces units = m2 s-1 diff --git a/schemes/zhang_mcfarlane/zm_conv_options_namelist.xml b/schemes/zhang_mcfarlane/zm_conv_options_namelist.xml index 001fde77..2ed47487 100644 --- a/schemes/zhang_mcfarlane/zm_conv_options_namelist.xml +++ b/schemes/zhang_mcfarlane/zm_conv_options_namelist.xml @@ -14,6 +14,7 @@ Autoconversion coefficient over land in ZM deep convection scheme. 0.0075D0 + 0.0035D0 @@ -27,6 +28,7 @@ Autoconversion coefficient over ocean in ZM deep convection scheme. 0.0300D0 + 0.0035D0 @@ -66,6 +68,8 @@ Tunable evaporation efficiency for land in ZM deep convection scheme. 1.0E-5 + 3.0E-6 + 3.0E-6 diff --git a/suites/suite_cam4.xml b/suites/suite_cam4.xml index 3a3f41c5..de4f1484 100644 --- a/suites/suite_cam4.xml +++ b/suites/suite_cam4.xml @@ -7,15 +7,15 @@ Shallow convection Hack Macrophysics RK Microphysics RK - Radiation RRTMGP (commented out) + Radiation RRTMGP Chemistry None (not implemented) Vertical Diffusion HB Gravity Wave Drag Orographic --> - - initialize_constituents + to_be_ccppized_temporary + prescribe_radiative_gas_concentrations zm_conv_options @@ -215,16 +215,16 @@ sima_state_diagnostics - + rrtmgp_cloud_diagnostics - + rrtmgp_lw_mcica_subcol_gen - + - + rrtmgp_diagnostics - + apply_heating_rate + geopotential_temp @@ -269,6 +269,12 @@ tropopause_find tropopause_diagnostics + + + calc_dry_air_ideal_gas_density + set_surface_coupling_vars + @@ -359,6 +365,7 @@ + gravity_wave_drag_common @@ -394,6 +401,7 @@ + check_energy_save_teout diff --git a/suites/suite_cam7.xml b/suites/suite_cam7.xml index b39cebe4..e7508b7f 100644 --- a/suites/suite_cam7.xml +++ b/suites/suite_cam7.xml @@ -5,7 +5,6 @@ - initialize_constituents to_be_ccppized_temporary @@ -75,6 +74,13 @@ check_energy_scaling check_energy_chng + + + + +