!----------------------------------------------------------------------------- ! $Id: constants_clubb.F90 7140 2014-07-31 19:14:05Z betlej@uwm.edu $ !============================================================================= module constants_clubb ! Description: ! Contains frequently occuring model constants ! References: ! None !--------------------------------------------------------------------------- use clubb_precision, only: & dp, & ! Variable(s) core_rknd #ifdef CLUBB_CAM /* Set constants as they're set in CAM */ use shr_const_mod, only: shr_const_rdair, shr_const_cpdair, shr_const_latvap, & shr_const_latice, shr_const_latsub, shr_const_rgas, & shr_const_mwwv, shr_const_stebol, shr_const_tkfrz, & shr_const_mwdair, shr_const_g, shr_const_karman, & shr_const_rhofw #elif GFDL ! use GFDL constants, and then rename them to avoid confusion in case ! that the constants share the same names between GFDL and CLUBB use constants_mod, only: pi_gfdl => PI, & radians_per_deg_dp_gfdl => DEG_TO_RAD, & Cp_gfdl => CP_AIR, & Lv_gfdl => HLV, & Ls_gfdl => HLS, & Lf_gfdl => HLF, & Rd_gfdl => RDGAS, & Rv_gfdl => RVGAS, & stefan_boltzmann_gfdl => STEFAN, & T_freeze_K_gfdl => TFREEZE, & grav_gfdl => GRAV, & vonk_gfdl => VONKARM, & rho_lw_gfdl => DENS_H2O #endif implicit none private ! Default scope !----------------------------------------------------------------------------- ! Numerical/Arbitrary Constants !----------------------------------------------------------------------------- ! Fortran file unit I/O constants integer, parameter, public :: & fstderr = 0, fstdin = 5, fstdout = 6 ! Maximum variable name length in CLUBB GrADS or netCDF output integer, parameter, public :: & var_length = 30 ! The parameter parab_cyl_max_input is the largest magnitude that the input to ! the parabolic cylinder function is allowed to have. When the value of the ! input to the parabolic cylinder function is too large in magnitude ! (depending on the order of the parabolic cylinder function), overflow ! occurs, and the output of the parabolic cylinder function is +/-Inf. The ! parameter parab_cyl_max_input places a limit on the absolute value of the ! input to the parabolic cylinder function. When the value of the potential ! input exceeds this parameter (usually due to a very large ratio of ith PDF ! component mean of x to ith PDF component standard deviation of x), the ! variable x is considered to be constant and a different version of the ! equation called. ! ! The largest allowable magnitude of the input to the parabolic cylinder ! function (before overflow occurs) is dependent on the order of parabolic ! cylinder function. However, after a lot of testing, it was determined that ! an absolute value of 49 works well for an order of 12 or less. real( kind = core_rknd ), parameter, public :: & parab_cyl_max_input = 49.0_core_rknd ! Largest allowable input to parab. cyl. fnct. ! "Over-implicit" weighted time step. ! ! The weight of the implicit portion of a term is controlled by the factor ! gamma_over_implicit_ts (abbreviated "gamma" in the expression below). A ! factor is added to the right-hand side of the equation in order to balance a ! weight that is not equal to 1, such that: ! ! -y(t) * [ gamma * X(t+1) + ( 1 - gamma ) * X(t) ] + RHS; ! ! where X is the variable that is being solved for in a predictive equation ! (such as w'^3, w'th_l', r_t'^2, etc), y(t) is the linearized portion of the ! term that gets treated implicitly, and RHS is the portion of the term that ! is always treated explicitly. A weight of greater than 1 can be applied to ! make the term more numerically stable. ! ! gamma_over_implicit_ts Effect on term ! ! 0.0 Term becomes completely explicit ! ! 1.0 Standard implicit portion of the term; ! as it was without the weighting factor. ! ! 1.5 Strongly weighted implicit portion of the term; ! increased numerical stability. ! ! 2.0 More strongly weighted implicit portion of the ! term; increased numerical stability. ! ! Note: The "over-implicit" weighted time step is only applied to terms that ! tend to significantly decrease the amount of numerical stability for ! variable X. ! The "over-implicit" weighted time step is applied to the turbulent ! advection term for the following variables: ! w'^3 (also applied to the turbulent production term), found in ! module advance_wp2_wp3_module; ! w'r_t', w'th_l', and w'sclr', found in ! module advance_xm_wpxp_module; and ! r_t'^2, th_l'^2, r_t'th_l', u'^2, v'^2, sclr'^2, sclr'r_t', ! and sclr'th_l', found in module advance_xp2_xpyp_module. real( kind = core_rknd ), parameter, public :: & gamma_over_implicit_ts = 1.50_core_rknd !----------------------------------------------------------------------------- ! Mathematical Constants !----------------------------------------------------------------------------- real( kind = dp ), parameter, public :: & pi_dp = 3.14159265358979323846_dp #ifdef GFDL real( kind = core_rknd ), parameter, public :: & pi = pi_gfdl ! The ratio of radii to their circumference real( kind = dp ), parameter, public :: & radians_per_deg_dp = radians_per_deg_dp_gfdl #else real( kind = core_rknd ), parameter, public :: & pi = 3.141592654_core_rknd ! The ratio of radii to their circumference real( kind = dp ), parameter, public :: & radians_per_deg_dp = pi_dp / 180._dp #endif real( kind = dp ), parameter, public :: & sqrt_2pi_dp = 2.5066282746310005024_dp, & ! sqrt(2*pi) sqrt_2_dp = 1.4142135623730950488_dp ! sqrt(2) real( kind = core_rknd ), parameter, public :: & sqrt_2pi = 2.5066282746310005024_core_rknd, & ! sqrt(2*pi) sqrt_2 = 1.4142135623730950488_core_rknd ! sqrt(2) real( kind = dp ), parameter, public:: & two_dp = 2.0_dp, & ! 2 one_dp = 1.0_dp, & ! 1 one_half_dp = 0.5_dp, & ! 1/2 one_fourth_dp = 0.25_dp, & ! 1/4 zero_dp = 0.0_dp ! 0 real( kind = core_rknd ), parameter, public :: & one_hundred = 100.0_core_rknd, & ! 100 fifty = 50.0_core_rknd, & ! 50 twenty = 20.0_core_rknd, & ! 20 ten = 10.0_core_rknd, & ! 10 five = 5.0_core_rknd, & ! 5 four = 4.0_core_rknd, & ! 4 three = 3.0_core_rknd, & ! 3 two = 2.0_core_rknd, & ! 2 three_halves = 3.0_core_rknd/2.0_core_rknd, & ! 3/2 four_thirds = 4.0_core_rknd/3.0_core_rknd, & ! 4/3 one = 1.0_core_rknd, & ! 1 three_fourths = 0.75_core_rknd, & ! 3/4 two_thirds = 2.0_core_rknd/3.0_core_rknd, & ! 2/3 one_half = 0.5_core_rknd, & ! 1/2 one_third = 1.0_core_rknd/3.0_core_rknd, & ! 1/3 one_fourth = 0.25_core_rknd, & ! 1/4 zero = 0.0_core_rknd ! 0 !----------------------------------------------------------------------------- ! Physical constants !----------------------------------------------------------------------------- #ifdef CLUBB_CAM real( kind = core_rknd ), parameter, public :: & Cp = shr_const_cpdair, & ! Dry air specific heat at constant p [J/kg/K] Lv = shr_const_latvap, & ! Latent heat of vaporization [J/kg] Lf = shr_const_latice, & ! Latent heat of fusion [J/kg] Ls = shr_const_latsub, & ! Latent heat of sublimation [J/kg] Rd = shr_const_rdair, & ! Dry air gas constant [J/kg/K] Rv = shr_const_rgas/shr_const_mwwv ! Water vapor gas constant [J/kg/K] real( kind = core_rknd ), parameter, public :: & stefan_boltzmann = shr_const_stebol ! Stefan-Boltzmann constant [W/(m^2 K^4)] real( kind = core_rknd ), parameter, public :: & T_freeze_K = shr_const_tkfrz ! Freezing point of water [K] ! Useful combinations of Rd and Rv real( kind = core_rknd ), parameter, public :: & ep = shr_const_mwwv/shr_const_mwdair, & ! ep = 0.622 [-] ep1 = (1.0-ep)/ep,& ! ep1 = 0.61 [-] ep2 = 1.0/ep ! ep2 = 1.61 [-] real( kind = core_rknd ), parameter, public :: & kappa = (shr_const_rgas/shr_const_mwdair)/shr_const_cpdair ! kappa [-] real( kind = core_rknd ), parameter, public :: & grav = shr_const_g, & ! Gravitational acceleration [m/s^2] p0 = 1.0e5 ! Reference pressure [Pa] ! Von Karman's constant ! Constant of the logarithmic wind profile in the surface layer real( kind = core_rknd ), parameter, public :: & vonk = shr_const_karman, & ! Accepted value is 0.40 (+/-) 0.01 [-] rho_lw = shr_const_rhofw ! Density of liquid water [kg/m^3] #elif GFDL real( kind = core_rknd ), parameter, public :: & Cp = Cp_gfdl, & ! Dry air specific heat at constant p [J/kg/K] Lv = Lv_gfdl, & ! Latent heat of vaporization [J/kg] Ls = Ls_gfdl, & ! Latent heat of sublimation [J/kg] Lf = Lf_gfdl, & ! Latent heat of fusion [J/kg] Rd = Rd_gfdl, & ! Dry air gas constant [J/kg/K] Rv = Rv_gfdl ! Water vapor gas constant [J/kg/K] real( kind = core_rknd ), parameter, public :: & stefan_boltzmann = stefan_boltzmann_gfdl ! Stefan-Boltzmann constant [W/(m^2 K^4)] real( kind = core_rknd ), parameter, public :: & T_freeze_K = T_freeze_K_gfdl ! Freezing point of water [K] ! Useful combinations of Rd and Rv real( kind = core_rknd ), parameter, public :: & ep = Rd / Rv, & ! ep = 0.622 [-] ep1 = (1.0-ep)/ep,& ! ep1 = 0.61 [-] ep2 = 1.0/ep ! ep2 = 1.61 [-] real( kind = core_rknd ), parameter, public :: & kappa = Rd / Cp ! kappa [-] ! Changed g to grav to make it easier to find in the code 5/25/05 ! real, parameter :: grav = 9.80665 ! Gravitational acceleration [m/s^2] real( kind = core_rknd ), parameter, public :: & grav = grav_gfdl, & ! Gravitational acceleration [m/s^2] p0 = 1.0e5 ! Reference pressure [Pa] ! Von Karman's constant ! Constant of the logarithmic wind profile in the surface layer real( kind = core_rknd ), parameter, public :: & vonk = vonk_gfdl, & ! Accepted value is 0.40 (+/-) 0.01 [-] rho_lw = rho_lw_gfdl ! Density of liquid water [kg/m^3] #else real( kind = core_rknd ), parameter, public :: & Cp = 1004.67_core_rknd, & ! Dry air specific heat at constant p [J/kg/K] Lv = 2.5e6_core_rknd, & ! Latent heat of vaporization [J/kg] Ls = 2.834e6_core_rknd, & ! Latent heat of sublimation [J/kg] Lf = 3.33e5_core_rknd, & ! Latent heat of fusion [J/kg] Rd = 287.04_core_rknd, & ! Dry air gas constant [J/kg/K] Rv = 461.5_core_rknd ! Water vapor gas constant [J/kg/K] real( kind = core_rknd ), parameter, public :: & stefan_boltzmann = 5.6704e-8_core_rknd ! Stefan-Boltzmann constant [W/(m^2 K^4)] real( kind = core_rknd ), parameter, public :: & T_freeze_K = 273.15_core_rknd ! Freezing point of water [K] ! Useful combinations of Rd and Rv real( kind = core_rknd ), parameter, public :: & ep = Rd / Rv, & ! ep = 0.622_core_rknd [-] ep1 = (1.0_core_rknd-ep)/ep,& ! ep1 = 0.61_core_rknd [-] ep2 = 1.0_core_rknd/ep ! ep2 = 1.61_core_rknd [-] real( kind = core_rknd ), parameter, public :: & kappa = Rd / Cp ! kappa [-] ! Changed g to grav to make it easier to find in the code 5/25/05 ! real, parameter, public :: grav = 9.80665_core_rknd ! Gravitational acceleration [m/s^2] real( kind = core_rknd ), parameter, public :: & grav = 9.81_core_rknd, & ! Gravitational acceleration [m/s^2] p0 = 1.0e5_core_rknd ! Reference pressure [Pa] ! Von Karman's constant ! Constant of the logarithmic wind profile in the surface layer real( kind = core_rknd ), parameter, public :: & vonk = 0.4_core_rknd, & ! Accepted value is 0.40 (+/-) 0.01 [-] rho_lw = 1000.0_core_rknd ! Density of liquid water [kg/m^3] #endif real( kind = core_rknd ), parameter, public :: & rho_ice = 917.0_core_rknd ! Density of ice [kg/m^3] ! Tolerances below which we consider moments to be zero real( kind = core_rknd ), parameter, public :: & w_tol = 2.e-2_core_rknd, & ! [m/s] thl_tol = 1.e-2_core_rknd, & ! [K] rt_tol = 1.e-8_core_rknd, & ! [kg/kg] chi_tol = 1.e-8_core_rknd, & ! [kg/kg] eta_tol = chi_tol ! [kg/kg] ! Tolerances for use by the monatonic flux limiter. ! rt_tol_mfl is larger than rt_tol. rt_tol is extremely small ! (1e-8) to prevent spurious cloud formation aloft in LBA. ! rt_tol_mfl is larger (1e-4) to prevent the mfl from ! depositing moisture at the top of the domain. real( kind = core_rknd ), parameter, public :: & thl_tol_mfl = 1.e-2_core_rknd, & ! [K] rt_tol_mfl = 1.e-4_core_rknd ! [kg/kg] ! The tolerance for w'^2 is the square of the tolerance for w. real( kind = core_rknd ), parameter, public :: & w_tol_sqd = w_tol**2 ! [m^2/s^2] real( kind = core_rknd ), parameter, public :: & Skw_max_mag = 4.5_core_rknd ! Max magnitude of skewness [-] real( kind = core_rknd ), parameter, public :: & Skw_max_mag_sqd = Skw_max_mag**2 ! Max mag. of Skw squared [-] ! Set tolerances for Khairoutdinov and Kogan rain microphysics to insure ! against numerical errors. The tolerance values for Nc, rr, and Nr insure ! against underflow errors in computing the PDF for l_kk_rain. Basically, ! they insure that those values squared won't be less then 10^-38, which is ! the lowest number that can be numerically represented. However, the ! tolerance value for rc doubles as the lowest mixing ratio there can be to ! still officially have a cloud at that level. This is figured to be about ! 1.0_core_rknd x 10^-7 kg/kg. Brian; February 10, 2007. real( kind = core_rknd ), parameter, public :: & rc_tol = 1.0E-6_core_rknd, & ! Tolerance value for r_c [kg/kg] Nc_tol = 1.0E+2_core_rknd, & ! Tolerance value for N_c [#/kg] Ncn_tol = 1.0E+2_core_rknd ! Tolerance value for N_cn [#/kg] real( kind = core_rknd ), parameter, public :: & mvr_cloud_max = 1.6E-5_core_rknd ! Max. avg. mean vol. rad. cloud [m] real( kind = core_rknd ), parameter, public :: & Nc_in_cloud_min = 2.0e+4_core_rknd ! Precipitating hydrometeor tolerances for mixing ratios. real( kind = core_rknd ), parameter, public :: & rr_tol = 1.0E-10_core_rknd, & ! Tolerance value for r_r [kg/kg] ri_tol = 1.0E-10_core_rknd, & ! Tolerance value for r_i [kg/kg] rs_tol = 1.0E-10_core_rknd, & ! Tolerance value for r_s [kg/kg] rg_tol = 1.0E-10_core_rknd ! Tolerance value for r_g [kg/kg] ! Maximum allowable values for the average mean volume radius of the various ! hydrometeor species. real( kind = core_rknd ), parameter, public :: & mvr_rain_max = 5.0E-3_core_rknd, & ! Max. avg. mean vol. rad. rain [m] mvr_ice_max = 1.3E-4_core_rknd, & ! Max. avg. mean vol. rad. ice [m] mvr_snow_max = 1.0E-2_core_rknd, & ! Max. avg. mean vol. rad. snow [m] mvr_graupel_max = 2.0E-2_core_rknd ! Max. avg. mean vol. rad. graupel [m] ! Precipitating hydrometeor tolerances for concentrations. ! Tolerance value for N_r [#/kg] real( kind = core_rknd ), parameter, public :: & Nr_tol = ( one / ( four_thirds * pi * rho_lw * mvr_rain_max**3 ) ) & * rr_tol ! Tolerance value for N_i [#/kg] real( kind = core_rknd ), parameter, public :: & Ni_tol = ( one / ( four_thirds * pi * rho_ice * mvr_ice_max**3 ) ) & * ri_tol ! Tolerance value for N_s [#/kg] real( kind = core_rknd ), parameter, public :: & Ns_tol = ( one / ( four_thirds * pi * rho_ice * mvr_snow_max**3 ) ) & * rs_tol ! Tolerance value for N_s [#/kg] real( kind = core_rknd ), parameter, public :: & Ng_tol = ( one / ( four_thirds * pi * rho_ice * mvr_graupel_max**3 ) ) & * rg_tol ! Minimum value for em (turbulence kinetic energy) ! If anisotropic TKE is enabled, em = (1/2) * ( up2 + vp2 + wp2 ); ! otherwise, em = (3/2) * wp2. Since up2, vp2, and wp2 all have ! the same minimum threshold value of w_tol_sqd, em cannot be less ! than (3/2) * w_tol_sqd. Thus, em_min = (3/2) * w_tol_sqd. real( kind = core_rknd ), parameter, public :: & em_min = 1.5_core_rknd * w_tol_sqd ! [m^2/s^2] real( kind = core_rknd ), parameter, public :: & eps = 1.0e-10_core_rknd ! Small value to prevent a divide by zero real( kind = core_rknd ), parameter, public :: & zero_threshold = 0.0_core_rknd ! Defining a threshold on a physical quantity to be 0. ! The maximum absolute value (or magnitude) that a correlation is allowed to ! have. Statistically, a correlation is not allowed to be less than -1 or ! greater than 1, so the maximum magnitude would be 1. real( kind = core_rknd ), parameter, public :: & max_mag_correlation = 0.99_core_rknd real( kind = core_rknd ), parameter, public :: & cloud_frac_min = 0.005_core_rknd ! Threshold for cloud fractions !----------------------------------------------------------------------------- ! Useful conversion factors. !----------------------------------------------------------------------------- real(kind=core_rknd), parameter, public :: & sec_per_day = 86400.0_core_rknd, & ! Seconds in a day. sec_per_hr = 3600.0_core_rknd, & ! Seconds in an hour. sec_per_min = 60.0_core_rknd, & ! Seconds in a minute. min_per_hr = 60.0_core_rknd ! Minutes in an hour. real( kind = core_rknd ), parameter, public :: & g_per_kg = 1000.0_core_rknd ! Grams in a kilogram. real( kind = core_rknd ), parameter, public :: & pascal_per_mb = 100.0_core_rknd ! Pascals per Millibar real( kind = core_rknd ), parameter, public :: & cm3_per_m3 = 1.e6_core_rknd, & ! Cubic centimeters per cubic meter micron_per_m = 1.e6_core_rknd, & ! Micrometers per meter cm_per_m = 100._core_rknd, & ! Centimeters per meter mm_per_m = 1000._core_rknd ! Millimeters per meter !----------------------------------------------------------------------------- ! Unused variable !----------------------------------------------------------------------------- real( kind = core_rknd ), parameter, public :: & unused_var = -999._core_rknd ! The standard value for unused variables !============================================================================= end module constants_clubb