diff --git a/.github/workflows/ci_fv3_ccpp_prebuild.yml b/.github/workflows/ci_fv3_ccpp_prebuild.yml index a32b66b7b..a5c2f8092 100644 --- a/.github/workflows/ci_fv3_ccpp_prebuild.yml +++ b/.github/workflows/ci_fv3_ccpp_prebuild.yml @@ -3,12 +3,10 @@ name: CI test to run FV3 ccpp_prebuild step on: [push, pull_request] jobs: - build-linux: + ccpp-prebuild-FV3: # The type of runner that the job will run on - runs-on: ubuntu-latest - strategy: - max-parallel: 5 + runs-on: ubuntu-20.04 steps: - name: Checkout current ccpp-physics code diff --git a/.github/workflows/ci_scm_ccpp_prebuild.yml b/.github/workflows/ci_scm_ccpp_prebuild.yml index 64fac3cd1..7c9d2300a 100644 --- a/.github/workflows/ci_scm_ccpp_prebuild.yml +++ b/.github/workflows/ci_scm_ccpp_prebuild.yml @@ -3,12 +3,10 @@ name: CI test to run SCM ccpp_prebuild step on: [push, pull_request] jobs: - build-linux: + ccpp-prebuild-SCM: # The type of runner that the job will run on - runs-on: ubuntu-latest - strategy: - max-parallel: 5 + runs-on: ubuntu-20.04 steps: diff --git a/.gitmodules b/.gitmodules index 75e5ea836..8758980ec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "physics/rte-rrtmgp"] path = physics/rte-rrtmgp url = https://github.com/earth-system-radiation/rte-rrtmgp - branch = dtc/ccpp + branch = main diff --git a/CMakeLists.txt b/CMakeLists.txt index d14778b06..950bd048e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(ccpp_physics #------------------------------------------------------------------------------ set(PACKAGE "ccpp-physics") -set(AUTHORS "Grant Firl" "Dom Heinzeller" "Man Zhang" "Mike Kavulich" "Chunxi Zhang") +set(AUTHORS "Grant Firl" "Dustin Swales" "Man Zhang" "Mike Kavulich" ) #------------------------------------------------------------------------------ # Set OpenMP flags for C/C++/Fortran @@ -81,14 +81,10 @@ get_filename_component(LOCAL_CURRENT_SOURCE_DIR ${FULL_PATH_TO_CMAKELISTS} DIREC # List of files that need to be compiled without OpenMP set(SCHEMES_OPENMP_OFF ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_gas_optics.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_rrtmgp_constants.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_rrtmgp_util_reorder.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_rrtmgp_util_string.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/kernels/mo_gas_optics_kernels.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/kernels/mo_rrtmgp_util_reorder_kernels.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/tests/mo_testing_io.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/tests/clear_sky_regression.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/mo_rrtmgp_clr_all_sky.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/mo_fluxes_byband.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/solar_variability/mo_solar_variability.F90 @@ -97,14 +93,6 @@ set(SCHEMES_OPENMP_OFF ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rrtmgp/mo_ ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/mo_compute_bc.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/cloud_optics/mo_cloud_sampling.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/extensions/cloud_optics/mo_cloud_optics.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/mo_load_coefficients.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/rfmip-clear-sky/rrtmgp_rfmip_sw.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/rfmip-clear-sky/mo_rfmip_io.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/rfmip-clear-sky/rrtmgp_rfmip_lw.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/mo_simple_netcdf.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/all-sky/rrtmgp_allsky.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/all-sky/mo_load_cloud_coefficients.F90 - ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/examples/all-sky/mo_garand_atmos_io.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rte/mo_rte_config.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rte/mo_source_functions.F90 ${LOCAL_CURRENT_SOURCE_DIR}/physics/rte-rrtmgp/rte/mo_rte_sw.F90 @@ -195,7 +183,9 @@ set_target_properties(ccpp_physics PROPERTIES VERSION ${PROJECT_VERSION} target_include_directories(ccpp_physics PUBLIC $) -target_link_libraries(ccpp_physics PUBLIC w3emc::w3emc_d NetCDF::NetCDF_Fortran) +target_link_libraries(ccpp_physics PUBLIC w3emc::w3emc_d + sp::sp_d + NetCDF::NetCDF_Fortran) # Define where to install the library install(TARGETS ccpp_physics diff --git a/CODEOWNERS b/CODEOWNERS index cf7a886aa..15821a791 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -4,127 +4,198 @@ # Default codeowners for files that don't have specific owners: -* @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +* @grantfirl @ChunxiZhang-NOAA @dustinswales @mzhangw # The following lines are from the CCPP Primary Schemes Points of Contact # https://docs.google.com/spreadsheets/d/14y0Th_sSpCqlssEMNfSZ_Ni9wrpPqfpPY0kRG7jCZB8/edit#gid=0 # (Internal NOAA document.) -smoke/* @haiqinli @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/cs_conv_aw_adj.* @AnningCheng-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cs_conv.* @AnningCheng-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cu_gf* @hannahcbarnes @haiqinli @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/sascnvn.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cu_ntiedtke* @ChunxiZhang-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich -physics/rascnv.* @SMoorthi-emc @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/samfdeepcnv.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/samfshalcnv.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/samfaerosols.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/shalcnv.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/unified_ugwp* @mdtoyNOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/ugwp_driver_v0.F @mdtoyNOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cires_ugwp* @mdtoyNOAA @ValeryYudin-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/drag_suite.* @mdtoyNOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/gwdc.* @Songyou184 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/gwdps.* @Songyou184 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/gfdl_fv_sat_adj.* @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/gfdl_cloud_microphys.* @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/module_gfdl_cloud_microphys.* @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/multi_gases.F90 @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/mp_fer_hires.* @ericaligo-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_MP_FER_HIRES.* @ericaligo-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/module_mp_thompson* @gthompsnWRF @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_mp_radar.* @gthompsnWRF @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/mp_thompson* @gthompsnWRF @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/precpd.* @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/gscond.* @RuiyuSun @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/m_micro* @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/aer_cloud.F @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/aerclm_def.F @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cldmacro.F @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/cldwat2m_micro.F @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/wv_saturation.F @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/micro_mg* @AnningCheng-NOAA @andrewgettelman @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/ozphys* @AlexBelochitski-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/satmedmfvdif.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/satmedmfvdifq.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/mfpbl.f @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/mfscu.f @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/mfpbltq.f @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/mfscuq.f @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/shinhongvdif.* @ChunxiZhang-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich -physics/ysuvdif.* @ChunxiZhang-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich - -physics/tridi.f @JongilHan66 @ChunxiZhang-NOAA @JongilHan66 @WeiguoWang-NOAA @AlexBelochitski-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich - -physics/moninedmf.* @JongilHan66 @WeiguoWang-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/module_BL_MYJPBL.* @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_MYJPBL_wrapper.* @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/module_bl_mynn.* @joeolson42 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_MYNNPBL_wrapper.* @joeolson42 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/gcm_shoc.* @AlexBelochitski-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/moninshoc.* @AlexBelochitski-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/rte-rrtmgp @dustinswales @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/radiation_tools.* @dustinswales @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/rrtmgp_lw_rte.met* @dustinswales @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/rrtmgp_sw_rte.met* @dustinswales @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/radlw_main.* @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/HWRF_mcica_random_numbers.F90 @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/HWRF_mersenne_twister.F90 @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/radlw_datatb.f @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/radsw_datatb.* @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/radsw_main.* @mjiacono @Qingfu-Liu @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/radsw_param.f @dustinswales @Qingfu-Liu @mjiacono @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/rayleigh_damp.* @yangfanglin @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/GFS_stochastics.* @pjpegion @lisa-bengtsson @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/flake* @YihuaWu-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/sfc_drv.* @HelinWei-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/sflx.f @HelinWei-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/surface_perturbation.* @HelinWei-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/*noahmp* @barlage @cenlinhe @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/set_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/namelist_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/namelist_soilveg_ruc.* @tanyasmirnova @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/set_soilveg_ruc.* @tanyasmirnova @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_sf_ruclsm.* @tanyasmirnova @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/module_soil_pre.* @tanyasmirnova @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/sfc_drv_ruc.* @tanyasmirnova @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/date_def.f @XuLi-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/*nst* @XuLi-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/sfc_ocean.* @HelinWei-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/sfc_diff.* @JongilHan66 @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/h2ophys.* @AlexBelochitski-NOAA @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA - -physics/sfc_sice.* @wd20xw @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA -physics/sfc_cice.* @wd20xw @climbfuji @SamuelTrahanNOAA @grantfirl @mzhangw @panll @mkavulich @ChunxiZhang-NOAA +smoke/* @haiqinli @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/aerclm_def.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/aer_cloud.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/aerinterp.F90 @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/bl_mynn_common.f90 @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/calpreciptype.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cires_orowam2017.f @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cires_tauamf_data.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cires_ugwp* @ValeryYudin-NOAA @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cldmacro.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cldwat2m_micro.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cnvc90.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cs_conv_aw_adj.* @AnningCheng-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cs_conv.* @AnningCheng-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cu_gf* @hannahcbarnes @haiqinli @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/cu_ntiedtke* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/date_def.f @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/dcyc2t3.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/drag_suite.* @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/flake* @YihuaWu-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/funcphys.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/fv_sat_adj.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gcycle.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/get_phi_fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/get_prs_fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gfdl_cloud_microphys.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFDL_parse_tracers.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gfdl_sfc_layer.* @ZhanZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_cloud_diagnostics.* @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_DCNV_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_DCNV_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_debug.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_GWD_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_GWD_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_MP_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_MP_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_PBL_generic_common.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_PBL_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_PBL_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_phys_time_vary.fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_phys_time_vary.scm.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gfs_phy_tracer_config.F @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_radiation_surface.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rad_time_vary.fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rad_time_vary.scm.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_cloud_mp.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_cloud_overlap.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_lw_post.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmg_post.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_pre.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmg_pre.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_setup.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_sw_post.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmgp_sw_pre.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_rrtmg_setup.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_SCNV_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_SCNV_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_stochastics.* @pjpegion @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_1.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_2.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_4.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_5.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_phys_reset.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_interstitial_rad_reset.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_stateout_reset.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_suite_stateout_update.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_composites_inter.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_composites_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_composites_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_generic_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_generic_pre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_loop_control_part1.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_surface_loop_control_part2.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_time_vary_pre.fv3.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/GFS_time_vary_pre.scm.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gocart_tracer_config_stub.f @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gwdc.* @Songyou184 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/gwdps.* @Songyou184 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/h2o_def.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/h2ointerp.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/h2ophys.* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/hedmf.* @JongilHan66 @WeiguoWang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/iccn_def.F @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/iccninterp.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/iounitdef.f @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/lsm_noah.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/lsm_ruc.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/machine.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/maximum_hourly_diagnostics.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mersenne_twister.f @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfpbl.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfpblt.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfpbltq.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfscu.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mfscuq.f @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/micro_mg* @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/m_micro* @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_bfmicrophysics.f @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_BL_MYJPBL.* @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_bl_mynn.* @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_gfdl_cloud_microphys.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_MP_FER_HIRES.* @ericaligo-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_mp_nssl_2mom.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_mp_radar.* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_mp_thompson* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_nst* @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_sf_exchcoef.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_SF_JSFC.F90 @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_sf_mynn.F90 @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_sf_ruclsm.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/module_soil_pre.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/moninshoc.* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mp_fer_hires.* @ericaligo-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mp_nssl.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mp_thompson* @gthompsnWRF @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/multi_gases.F90 @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/myjpbl_wrapper.* @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/myjsfc_wrapper.* @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mynnedmf_wrapper.* @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/mynnsfc_wrapper.* @joeolson42 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/namelist_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/namelist_soilveg_ruc.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/*noahmp* @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ozinterp.f90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ozne_def.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ozphys* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/physcons.F90 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/phys_tend.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/progsigma_calc.f90 @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radcons.f90 @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_aerosols.f @Qingfu-Liu @dustinswales @AnningCheng-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_astronomy.f @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_cloud_overlap.F90 @dustinswales @mjiacono @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_clouds.f @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_gases.f @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_surface.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radiation_tools.F90 @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radlw_* @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/radsw_* @mjiacono @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rad_sw_pre.* @dustinswales @Qingfu-Liu @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rascnv.* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rayleigh_damp.* @yangfanglin @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmg_lw_cloud_optics.F90 @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmg_lw_post.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmg_lw_pre.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmgp_aerosol_optics.* @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmgp_lw_* @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmgp_sw_* @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmg_sw_cloud_optics.F90 @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rrtmg_sw_post.* @Qingfu-Liu @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/rte-rrtmgp @RobertPincus @dustinswales @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/samfdeepcnv.* @JongilHan66 @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/samfshalcnv.* @JongilHan66 @lisa-bengtsson @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/samfaerosols.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sascnvn.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/satmedmfvdif.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/satmedmfvdifq.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/scm_sfc_flux_spec.* @grantfirl @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/set_soilveg.* @HelinWei-NOAA @barlage @cenlinhe @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/set_soilveg_ruc.* @tanyasmirnova @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_cice.* @wd20xw @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_diag.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_diag_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_diff.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_nst* @XuLi-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_ocean.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sfc_sice.* @wd20xw @grantfirl @ChunxiZhang-NOAA @dustinswales +#physics/sfcsub.F @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sflx.f @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sgscloud_radpost.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/sgscloud_radpre.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/shalcnv.* @JongilHan66 @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/shinhongvdif.* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/shoc.* @SMoorthi-emc @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/surface_perturbation.* @HelinWei-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/tridi.f @JongilHan66 @ChunxiZhang-NOAA @WeiguoWang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ugwp_driver_v0.F @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ugwpv1_gsldrag.* @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ugwpv1_gsldrag_post.* @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/unified_ugwp* @mdtoyNOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/wv_saturation.F @AnningCheng-NOAA @andrewgettelman @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/ysuvdif.* @ChunxiZhang-NOAA @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/zhaocarr_gscond.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales +physics/zhaocarr_precpd.* @RuiyuSun @grantfirl @ChunxiZhang-NOAA @dustinswales ######################################################################## diff --git a/physics/GFS_MP_generic_post.F90 b/physics/GFS_MP_generic_post.F90 index b7e65bc8b..1a04c74ba 100644 --- a/physics/GFS_MP_generic_post.F90 +++ b/physics/GFS_MP_generic_post.F90 @@ -20,10 +20,11 @@ module GFS_MP_generic_post !> @{ subroutine GFS_MP_generic_post_run( & im, levs, kdt, nrcm, nncl, ntcw, ntrac, imp_physics, imp_physics_gfdl, imp_physics_thompson, imp_physics_nssl, & - imp_physics_mg, imp_physics_fer_hires, cal_pre, cplflx, cplchm, cpllnd, progsigma, con_g, rainmin, dtf, frain, rainc, & - rain1, rann, xlat, xlon, gt0, gq0, prsl, prsi, phii, tsfc, ice, snow, graupel, save_t, save_q, rain0, ice0, snow0,& - graupel0, del, rain, domr_diag, domzr_diag, domip_diag, doms_diag, tprcp, srflag, sr, cnvprcp, totprcp, totice, & - totsnw, totgrp, cnvprcpb, totprcpb, toticeb, totsnwb, totgrpb, rain_cpl, rainc_cpl, snow_cpl, pwat, & + imp_physics_mg, imp_physics_fer_hires, cal_pre, cplflx, cplchm, cpllnd, progsigma, con_g, rhowater, rainmin, dtf, & + frain, rainc, rain1, rann, xlat, xlon, gt0, gq0, prsl, prsi, phii, tsfc, ice, snow, graupel, save_t, save_q, & + rain0, ice0, snow0, graupel0, del, rain, domr_diag, domzr_diag, domip_diag, doms_diag, tprcp, srflag, sr, cnvprcp,& + totprcp, totice, totsnw, totgrp, cnvprcpb, totprcpb, toticeb, totsnwb, totgrpb, rain_cpl, rainc_cpl, snow_cpl, & + pwat, frzr, frzrb, frozr, frozrb, tsnowp, tsnowpb, rhonewsn1, exticeden, & drain_cpl, dsnow_cpl, lsm, lsm_ruc, lsm_noahmp, raincprv, rainncprv, iceprv, snowprv, & graupelprv, draincprv, drainncprv, diceprv, dsnowprv, dgraupelprv, dtp, dfi_radar_max_intervals, & dtend, dtidx, index_of_temperature, index_of_process_mp,ldiag3d, qdiag3d,dqdt_qmicro, lssav, num_dfi_radar, & @@ -37,7 +38,7 @@ subroutine GFS_MP_generic_post_run( integer, intent(in) :: im, levs, kdt, nrcm, nncl, ntcw, ntrac, num_dfi_radar, index_of_process_dfi_radar integer, intent(in) :: imp_physics, imp_physics_gfdl, imp_physics_thompson, imp_physics_mg, imp_physics_fer_hires integer, intent(in) :: imp_physics_nssl - logical, intent(in) :: cal_pre, lssav, ldiag3d, qdiag3d, cplflx, cplchm, cpllnd, progsigma + logical, intent(in) :: cal_pre, lssav, ldiag3d, qdiag3d, cplflx, cplchm, cpllnd, progsigma, exticeden integer, intent(in) :: index_of_temperature,index_of_process_mp integer :: dfi_radar_max_intervals @@ -46,7 +47,7 @@ subroutine GFS_MP_generic_post_run( integer :: ix_dfi_radar(:) real(kind=kind_phys), dimension(:,:), intent(inout) :: gt0 - real(kind=kind_phys), intent(in) :: dtf, frain, con_g, rainmin + real(kind=kind_phys), intent(in) :: dtf, frain, con_g, rainmin, rhowater real(kind=kind_phys), dimension(:), intent(in) :: rain1, xlat, xlon, tsfc real(kind=kind_phys), dimension(:), intent(inout) :: ice, snow, graupel, rainc real(kind=kind_phys), dimension(:), intent(in) :: rain0, ice0, snow0, graupel0 @@ -81,6 +82,13 @@ subroutine GFS_MP_generic_post_run( real(kind=kind_phys), dimension(:), intent(inout) :: diceprv real(kind=kind_phys), dimension(:), intent(inout) :: dsnowprv real(kind=kind_phys), dimension(:), intent(inout) :: dgraupelprv + real(kind=kind_phys), dimension(:), intent(inout) :: frzr + real(kind=kind_phys), dimension(:), intent(inout) :: frzrb + real(kind=kind_phys), dimension(:), intent(inout) :: frozr + real(kind=kind_phys), dimension(:), intent(inout) :: frozrb + real(kind=kind_phys), dimension(:), intent(inout) :: tsnowp + real(kind=kind_phys), dimension(:), intent(inout) :: tsnowpb + real(kind=kind_phys), dimension(:), intent(inout) :: rhonewsn1 real(kind=kind_phys), dimension(:,:), intent(inout) :: dqdt_qmicro real(kind=kind_phys), dimension(:,:), intent(inout) :: prevsq real(kind=kind_phys), intent(in) :: dtp @@ -101,6 +109,9 @@ subroutine GFS_MP_generic_post_run( real(kind=kind_phys) :: crain, csnow, onebg, tem, total_precip, tem1, tem2, ttend real(kind=kind_phys), dimension(im) :: domr, domzr, domip, doms, t850, work1 + real :: snowrat,grauprat,icerat,curat,prcpncfr,prcpcufr + real :: rhonewsnow,rhoprcpice,rhonewgr,rhonewice + ! Initialize CCPP error handling variables errmsg = '' errflg = 0 @@ -111,6 +122,68 @@ subroutine GFS_MP_generic_post_run( rain(i) = rainc(i) + frain * rain1(i) ! time-step convective plus explicit enddo +! compute surface snowfall, graupel/sleet, freezing rain and precip ice density + if (imp_physics == imp_physics_gfdl .or. imp_physics == imp_physics_thompson .or. imp_physics == imp_physics_nssl ) then + do i = 1, im + if (gt0(i,1) .le. 273) then + frzr(i) = frzr(i) + rain0(i) + frzrb(i) = frzrb(i) + rain0(i) + endif + tsnowp(i) = tsnowp(i) + snow0(i) + tsnowpb(i) = tsnowpb(i) + snow0(i) + frozr(i) = frozr(i) + graupel0(i) + frozrb(i) = frozrb(i) + graupel0(i) + enddo +!Compute the variable precip ice density for specific LSM schemes and options + if (exticeden) then + snowrat = 0. + grauprat = 0. + icerat = 0. + prcpncfr = 0. + prcpcufr = 0. + curat = 0. + prcpncfr = 0. + prcpcufr = 0. + rhonewsnow = 0. + rhonewgr = 0. + rhonewice = 0. + rhoprcpice = 0. + do i = 1, im + rhonewsn1(i)= 200. + prcpncfr = rain1(i)*sr(i) + if(sr(i) > 0..and. gt0(i,1) < 273.) then + prcpcufr = max(0.,rainc(i)*sr(i)) + else + if(gt0(i,1) < 273.) then + prcpcufr = max(0.,rainc(i)) + else + prcpcufr = 0. + endif ! gt0(i,1) < 273. + endif ! frzfrac > 0. +! + if((prcpncfr + prcpcufr) > 0.) then +! -- calculate snow, graupel and ice fractions in falling frozen precip + snowrat=min(1.,max(0.,snow0(i)/(prcpncfr + prcpcufr))) + grauprat=min(1.,max(0.,graupel0(i)/(prcpncfr + prcpcufr))) + icerat=min(1.,max(0.,(prcpncfr-snow0(i)-graupel0(i)) & + /(prcpncfr + prcpcufr))) + curat=min(1.,max(0.,(prcpcufr/(prcpncfr + prcpcufr)))) + + rhonewsnow=min(125.,1000.0/max(8.,(17.*tanh((276.65-gt0(i,1))*0.15)))) + rhonewgr=min(500.,rhowater/max(2.,(3.5*tanh((274.15-gt0(i,1))*0.3333)))) + rhonewice=rhonewsnow +!--- compute density of "precip ice" from weighted contribution +! of snow, graupel and ice fractions + + rhoprcpice = min(500.,max(58.8,(rhonewsnow*snowrat + & + rhonewgr*grauprat + rhonewice*icerat + rhonewgr*curat))) +! from now on rhonewsn1 is the density of falling frozen precipitation + rhonewsn1(i)=rhoprcpice + endif + enddo + endif + endif + !> - If requested (e.g. Zhao-Carr MP scheme), call calpreciptype() to calculate dominant !! precipitation type. ! DH* TODO - Fix wrong code in non-CCPP build (GFS_physics_driver) diff --git a/physics/GFS_MP_generic_post.meta b/physics/GFS_MP_generic_post.meta index 5216b7157..fa1cfafe0 100644 --- a/physics/GFS_MP_generic_post.meta +++ b/physics/GFS_MP_generic_post.meta @@ -150,6 +150,14 @@ type = real kind = kind_phys intent = in +[rhowater] + standard_name = fresh_liquid_water_density_at_0c + long_name = density of liquid water + units = kg m-3 + dimensions = () + type = real + kind = kind_phys + intent = in [dtf] standard_name = timestep_for_dynamics long_name = dynamics timestep @@ -278,6 +286,69 @@ type = real kind = kind_phys intent = inout +[frzr] + standard_name = cumulative_lwe_thickness_of_surface_freezing_rain_amount + long_name = accumulated surface freezing rain + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[frzrb] + standard_name = cumulative_lwe_thickness_of_surface_freezing_rain_amount_in_bucket + long_name = accumulated surface freezing rain in bucket + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[frozr] + standard_name = cumulative_lwe_thickness_of_surface_graupel_amount + long_name = accumulated surface graupel + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[frozrb] + standard_name = cumulative_lwe_thickness_of_surface_graupel_amount_in_bucket + long_name = accumulated surface graupel in bucket + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[tsnowp] + standard_name = cumulative_lwe_thickness_of_surface_snow_amount + long_name = accumulated surface snow + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[tsnowpb] + standard_name = cumulative_lwe_thickness_of_surface_snow_amount_in_bucket + long_name = accumulated surface snow in bucket + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[rhonewsn1] + standard_name = surface_frozen_precipitation_density + long_name = density of precipitation ice + units = kg m-3 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[exticeden] + standard_name = do_external_surface_frozen_precipitation_density + long_name = flag for calculating frozen precip ice density outside of the LSM + units = flag + dimensions = () + type = logical + intent = in [save_t] standard_name = air_temperature_save long_name = air temperature before entering a physics scheme diff --git a/physics/GFS_cloud_diagnostics.F90 b/physics/GFS_cloud_diagnostics.F90 index 0e3f730e5..86dc2b518 100644 --- a/physics/GFS_cloud_diagnostics.F90 +++ b/physics/GFS_cloud_diagnostics.F90 @@ -3,7 +3,6 @@ module GFS_cloud_diagnostics use machine, only: kind_phys - use physparam, only: icldflg use module_radiation_clouds, only: gethml ! Module parameters (imported directly from radiation_cloud.f) @@ -19,10 +18,6 @@ module GFS_cloud_diagnostics ! Version tag and last revision date character(40), parameter :: VTAGCLD='UFS-cloud-diagnostics vX.x May 2020 ' - - ! Module variables - integer :: & - llyr = 2 ! Upper limit of boundary layer clouds public GFS_cloud_diagnostics_run @@ -36,51 +31,54 @@ module GFS_cloud_diagnostics !> \section arg_table_GFS_cloud_diagnostics_run !! \htmlinclude GFS_cloud_diagnostics_run.html !! - subroutine GFS_cloud_diagnostics_run(nCol, nLev, iovr_rand, iovr_maxrand, iovr_max, & - iovr_dcorr, iovr_exp, iovr_exprand, lsswr, lslwr, lat, de_lgth, p_lay, & + subroutine GFS_cloud_diagnostics_run(nCol, nLev, iovr, iovr_rand, iovr_maxrand, & + iovr_max, iovr_dcorr, iovr_exp, iovr_exprand, lsswr, lslwr, lat, de_lgth, p_lay, & cld_frac, p_lev, deltaZ, cloud_overlap_param, precip_overlap_param, con_pi, & - mtopa, mbota, cldsa, errmsg, errflg) + top_at_1, si, mtopa, mbota, cldsa, errmsg, errflg) implicit none ! Inputs - integer, intent(in) :: & - nCol, & ! Number of horizontal grid-points - nLev ! Number of vertical-layers - integer, intent(in) :: & - iovr_rand, & ! Flag for random cloud overlap method - iovr_maxrand, & ! Flag for maximum-random cloud overlap method - iovr_max, & ! Flag for maximum cloud overlap method - iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method - iovr_exp, & ! Flag for exponential cloud overlap method - iovr_exprand ! Flag for exponential-random cloud overlap method - logical, intent(in) :: & - lsswr, & ! Call SW radiation? - lslwr ! Call LW radiation - real(kind_phys), intent(in) :: & - con_pi ! Physical constant: pi + integer, intent(in) :: & + nCol, & ! Number of horizontal grid-points + nLev ! Number of vertical-layers + integer, intent(in) :: & + iovr, & ! Choice of cloud-overlap method + iovr_rand, & ! Flag for random cloud overlap method + iovr_maxrand, & ! Flag for maximum-random cloud overlap method + iovr_max, & ! Flag for maximum cloud overlap method + iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method + iovr_exp, & ! Flag for exponential cloud overlap method + iovr_exprand ! Flag for exponential-random cloud overlap method + logical, intent(in) :: & + lsswr, & ! Call SW radiation? + lslwr, & ! Call LW radiation? + top_at_1 ! Vertical ordering flag + real(kind_phys), intent(in) :: & + con_pi ! Physical constant: pi real(kind_phys), dimension(:), intent(in) :: & - lat, & ! Latitude - de_lgth ! Decorrelation length + lat, & ! Latitude + de_lgth, & ! Decorrelation length + si ! Vertical sigma coordinate real(kind_phys), dimension(:,:), intent(in) :: & - p_lay, & ! Pressure at model-layer - cld_frac ! Total cloud fraction + p_lay, & ! Pressure at model-layer + cld_frac ! Total cloud fraction real(kind_phys), dimension(:,:), intent(in) :: & - p_lev ! Pressure at model interfaces + p_lev ! Pressure at model interfaces real(kind_phys), dimension(:,:), intent(in) :: & - deltaZ, & ! Layer thickness (m) - cloud_overlap_param, & ! Cloud-overlap parameter - precip_overlap_param ! Precipitation overlap parameter + deltaZ, & ! Layer thickness (m) + cloud_overlap_param, & ! Cloud-overlap parameter + precip_overlap_param ! Precipitation overlap parameter ! Outputs - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - integer,dimension(:,:),intent(out) :: & - mbota, & ! Vertical indices for cloud tops - mtopa ! Vertical indices for cloud bases + character(len=*), intent(out) :: & + errmsg ! Error message + integer, intent(out) :: & + errflg ! Error flag + integer,dimension(:,:),intent(out) :: & + mbota, & ! Vertical indices for cloud tops + mtopa ! Vertical indices for cloud bases real(kind_phys),dimension(:,:), intent(out) :: & - cldsa ! Fraction of clouds for low, middle, high, total and BL + cldsa ! Fraction of clouds for low, middle, high, total and BL ! Local variables integer i,id,iCol,iLay,icld @@ -111,8 +109,8 @@ subroutine GFS_cloud_diagnostics_run(nCol, nLev, iovr_rand, iovr_maxrand, iovr_m ! defined by ptopc. The cloud overlapping method is defined by control flag 'iovr', which may ! be different for lw and sw radiation programs. call gethml(p_lay*0.01, ptop1, cld_frac, cldcnv, deltaZ, de_lgth, cloud_overlap_param,& - nCol, nLev, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, & - iovr_exprand, cldsa, mtopa, mbota) + nCol, nLev, iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, & + iovr_exprand, top_at_1, si, cldsa, mtopa, mbota) end subroutine GFS_cloud_diagnostics_run !> @} diff --git a/physics/GFS_cloud_diagnostics.meta b/physics/GFS_cloud_diagnostics.meta index dd88bbc46..53d1552e6 100644 --- a/physics/GFS_cloud_diagnostics.meta +++ b/physics/GFS_cloud_diagnostics.meta @@ -1,6 +1,7 @@ [ccpp-table-properties] name = GFS_cloud_diagnostics type = scheme + dependencies = machine.F,radiation_clouds.f ######################################################################## [ccpp-arg-table] @@ -20,6 +21,13 @@ dimensions = () type = integer intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = max-random overlap clouds + units = flag + dimensions = () + type = integer + intent = in [iovr_rand] standard_name = flag_for_random_cloud_overlap_method long_name = choice of random cloud overlap method @@ -148,6 +156,21 @@ type = real kind = kind_phys intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation + units = flag + dimensions = () + type = logical + intent = in +[si] + standard_name = sigma_pressure_hybrid_vertical_coordinate + long_name = vertical sigma coordinate for radiation initialization + units = none + dimensions = (vertical_interface_dimension) + type = real + kind = kind_phys + intent = in [mtopa] standard_name = model_layer_number_at_cloud_top long_name = vertical indices for low, middle and high cloud tops diff --git a/physics/GFS_debug.F90 b/physics/GFS_debug.F90 index 5e6419256..5387e6300 100644 --- a/physics/GFS_debug.F90 +++ b/physics/GFS_debug.F90 @@ -1285,7 +1285,7 @@ subroutine GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coup call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%qss_ice ', Interstitial%qss_ice ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%qss_land ', Interstitial%qss_land ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%qss_water ', Interstitial%qss_water ) - call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%radar_reset ', Interstitial%radar_reset ) + call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%fullradar_diag ', Interstitial%fullradar_diag ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%raddt ', Interstitial%raddt ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%raincd ', Interstitial%raincd ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%raincs ', Interstitial%raincs ) diff --git a/physics/GFS_phys_time_vary.fv3.F90 b/physics/GFS_phys_time_vary.fv3.F90 index 796856ad3..42f2bbc15 100644 --- a/physics/GFS_phys_time_vary.fv3.F90 +++ b/physics/GFS_phys_time_vary.fv3.F90 @@ -34,7 +34,6 @@ module GFS_phys_time_vary !--- variables needed for calculating 'sncovr' use namelist_soilveg, only: salp_data, snupx use set_soilveg_mod, only: set_soilveg - use physparam, only : iaermdl ! --- needed for Noah MP init use noahmp_tables, only: laim_table,saim_table,sla_table, & @@ -67,7 +66,7 @@ module GFS_phys_time_vary !>\section gen_GFS_phys_time_vary_init GFS_phys_time_vary_init General Algorithm !> @{ subroutine GFS_phys_time_vary_init ( & - me, master, ntoz, h2o_phys, iaerclm, iccn, iflip, im, levs, & + me, master, ntoz, h2o_phys, iaerclm, iccn, iaermdl, iflip, im, levs, & nx, ny, idate, xlat_d, xlon_d, & jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl,fhour, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & @@ -86,7 +85,7 @@ subroutine GFS_phys_time_vary_init ( implicit none ! Interface variables - integer, intent(in) :: me, master, ntoz, iccn, iflip, im, nx, ny, levs + integer, intent(in) :: me, master, ntoz, iccn, iflip, im, nx, ny, levs, iaermdl logical, intent(in) :: h2o_phys, iaerclm, lsm_cold_start integer, intent(in) :: idate(:) real(kind_phys), intent(in) :: fhour @@ -288,7 +287,7 @@ subroutine GFS_phys_time_vary_init ( !$OMP section !> - Initialize soil vegetation (needed for sncovr calculation further down) - call set_soilveg(me, isot, ivegsrc, nlunit) + call set_soilveg(me, isot, ivegsrc, nlunit, errmsg, errflg) !$OMP end sections @@ -712,7 +711,7 @@ subroutine GFS_phys_time_vary_timestep_init ( imfdeepcnv, cal_pre, random_clds, nscyc, ntoz, h2o_phys, iaerclm, iccn, clstp, & jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl, iflip, & jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, & - jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, in_nm, ccn_nm, & + jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, in_nm, ccn_nm, fn_nml, & imap, jmap, prsl, seed0, rann, nthrds, nx, ny, nsst, tile_num, nlunit, lsoil, lsoil_lsm,& kice, ialb, isot, ivegsrc, input_nml_file, use_ufo, nst_anl, frac_grid, fhcyc, phour, & lakefrac, min_seaice, min_lakeice, smc, slc, stc, smois, sh2o, tslb, tiice, tg3, tref, & @@ -753,6 +752,7 @@ subroutine GFS_phys_time_vary_timestep_init ( integer, intent(in) :: nthrds, nx, ny, nsst, tile_num, nlunit, lsoil integer, intent(in) :: lsoil_lsm, kice, ialb, isot, ivegsrc character(len=*), intent(in) :: input_nml_file(:) + character(len=*), intent(in) :: fn_nml logical, intent(in) :: use_ufo, nst_anl, frac_grid real(kind_phys), intent(in) :: fhcyc, phour, lakefrac(:), min_seaice, min_lakeice, & xlat_d(:), xlon_d(:), landfrac(:) @@ -893,14 +893,14 @@ subroutine GFS_phys_time_vary_timestep_init ( !> - Call gcycle() to repopulate specific time-varying surface properties for AMIP/forecast runs if (nscyc > 0) then if (mod(kdt,nscyc) == 1) THEN - call gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, & + call gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml, & input_nml_file, lsoil, lsoil_lsm, kice, idate, ialb, isot, ivegsrc, & use_ufo, nst_anl, fhcyc, phour, landfrac, lakefrac, min_seaice, min_lakeice,& frac_grid, smc, slc, stc, smois, sh2o, tslb, tiice, tg3, tref, tsfc, & tsfco, tisfc, hice, fice, facsf, facwf, alvsf, alvwf, alnsf, alnwf, & zorli, zorll, zorlo, weasd, slope, snoalb, canopy, vfrac, vtype, & stype, shdmin, shdmax, snowd, cv, cvb, cvt, oro, oro_uf, & - xlat_d, xlon_d, slmsk, imap, jmap) + xlat_d, xlon_d, slmsk, imap, jmap, errmsg, errflg) endif endif diff --git a/physics/GFS_phys_time_vary.fv3.meta b/physics/GFS_phys_time_vary.fv3.meta index f37235975..ce8c6c54b 100644 --- a/physics/GFS_phys_time_vary.fv3.meta +++ b/physics/GFS_phys_time_vary.fv3.meta @@ -44,6 +44,13 @@ dimensions = () type = logical intent = in +[iaermdl] + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 + dimensions = () + type = integer + intent = in [iccn] standard_name = control_for_ice_cloud_condensation_nuclei_forcing long_name = flag for IN and CCN forcing for morrison gettelman microphysics @@ -1285,6 +1292,14 @@ type = real kind = kind_phys intent = inout +[fn_nml] + standard_name = filename_of_namelist + long_name = namelist filename + units = none + dimensions = () + type = character + kind = len=* + intent = in [imap] standard_name = map_of_block_column_number_to_global_i_index long_name = map of local index ix to global index i for this block diff --git a/physics/GFS_phys_time_vary.scm.F90 b/physics/GFS_phys_time_vary.scm.F90 index c70e3232a..74b34e974 100644 --- a/physics/GFS_phys_time_vary.scm.F90 +++ b/physics/GFS_phys_time_vary.scm.F90 @@ -264,7 +264,7 @@ subroutine GFS_phys_time_vary_init ( endif !> - Initialize soil vegetation (needed for sncovr calculation further down) - call set_soilveg(me, isot, ivegsrc, nlunit) + call set_soilveg(me, isot, ivegsrc, nlunit, errmsg, errflg) !> - Call setindxoz() to initialize ozone data if (ntoz > 0) then diff --git a/physics/GFS_rad_time_vary.fv3.F90 b/physics/GFS_rad_time_vary.fv3.F90 index cef530b55..978dc177f 100644 --- a/physics/GFS_rad_time_vary.fv3.F90 +++ b/physics/GFS_rad_time_vary.fv3.F90 @@ -18,10 +18,10 @@ module GFS_rad_time_vary !! subroutine GFS_rad_time_vary_timestep_init (lrseeds, rseeds, & lslwr, lsswr, isubc_lw, isubc_sw, icsdsw, icsdlw, cnx, cny, isc, jsc, & - imap, jmap, sec, kdt, imp_physics, imp_physics_zhao_carr, ps_2delt, & - ps_1delt, t_2delt, t_1delt, qv_2delt, qv_1delt, t, qv, ps, errmsg, errflg) + imap, jmap, sec, kdt, imp_physics, imp_physics_zhao_carr, ipsd0, ipsdlim,& + ps_2delt, ps_1delt, t_2delt, t_1delt, qv_2delt, qv_1delt, t, qv, ps, & + errmsg, errflg) - use physparam, only: ipsd0, ipsdlim, iaerflg use mersenne_twister, only: random_setseed, random_index, random_stat use machine, only: kind_phys use radcons, only: qmin, con_100 @@ -32,7 +32,7 @@ subroutine GFS_rad_time_vary_timestep_init (lrseeds, rseeds, logical, intent(in) :: lrseeds integer, intent(in) :: rseeds(:,:) integer, intent(in) :: isubc_lw, isubc_sw, cnx, cny, isc, jsc, kdt - integer, intent(in) :: imp_physics, imp_physics_zhao_carr + integer, intent(in) :: imp_physics, imp_physics_zhao_carr, ipsd0, ipsdlim logical, intent(in) :: lslwr, lsswr integer, intent(inout) :: icsdsw(:), icsdlw(:) integer, intent(in) :: imap(:), jmap(:) diff --git a/physics/GFS_rad_time_vary.fv3.meta b/physics/GFS_rad_time_vary.fv3.meta index f7a154eea..19eb41dc2 100644 --- a/physics/GFS_rad_time_vary.fv3.meta +++ b/physics/GFS_rad_time_vary.fv3.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_rad_time_vary type = scheme - dependencies = machine.F,mersenne_twister.f,physparam.f,radcons.f90 + dependencies = machine.F,mersenne_twister.f,radcons.f90 ######################################################################## [ccpp-arg-table] @@ -134,6 +134,20 @@ dimensions = () type = integer intent = in +[ipsd0] + standard_name = initial_seed_for_mcica + long_name = initial permutaion seed for mcica radiation + units = 1 + dimensions = () + type = integer + intent = in +[ipsdlim] + standard_name = limit_for_initial_seed_for_mcica + long_name = limit for initial permutaion seed for mcica radiation + units = 1 + dimensions = () + type = integer + intent = in [ps_2delt] standard_name = surface_air_pressure_two_timesteps_back long_name = surface air pressure two timesteps back diff --git a/physics/GFS_rad_time_vary.scm.F90 b/physics/GFS_rad_time_vary.scm.F90 index 924312a2a..3f730eaf5 100644 --- a/physics/GFS_rad_time_vary.scm.F90 +++ b/physics/GFS_rad_time_vary.scm.F90 @@ -18,10 +18,10 @@ module GFS_rad_time_vary !! subroutine GFS_rad_time_vary_timestep_init (lrseeds, rseeds, & lslwr, lsswr, isubc_lw, isubc_sw, icsdsw, icsdlw, cnx, cny, isc, jsc, & - imap, jmap, sec, kdt, imp_physics, imp_physics_zhao_carr, ps_2delt, & - ps_1delt, t_2delt, t_1delt, qv_2delt, qv_1delt, t, qv, ps, errmsg, errflg) + imap, jmap, sec, kdt, imp_physics, imp_physics_zhao_carr, ipsd0, ipsdlim,& + ps_2delt, ps_1delt, t_2delt, t_1delt, qv_2delt, qv_1delt, t, qv, ps, & + errmsg, errflg) - use physparam, only: ipsd0, ipsdlim, iaerflg use mersenne_twister, only: random_setseed, random_index, random_stat use machine, only: kind_phys use radcons, only: qmin, con_100 @@ -32,7 +32,7 @@ subroutine GFS_rad_time_vary_timestep_init (lrseeds, rseeds, logical, intent(in) :: lrseeds integer, intent(in) :: rseeds(:,:) integer, intent(in) :: isubc_lw, isubc_sw, cnx, cny, isc, jsc, kdt - integer, intent(in) :: imp_physics, imp_physics_zhao_carr + integer, intent(in) :: imp_physics, imp_physics_zhao_carr, ipsd0, ipsdlim logical, intent(in) :: lslwr, lsswr integer, intent(inout) :: icsdsw(:), icsdlw(:) integer, intent(in) :: imap(:), jmap(:) diff --git a/physics/GFS_rad_time_vary.scm.meta b/physics/GFS_rad_time_vary.scm.meta index f7a154eea..19eb41dc2 100644 --- a/physics/GFS_rad_time_vary.scm.meta +++ b/physics/GFS_rad_time_vary.scm.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_rad_time_vary type = scheme - dependencies = machine.F,mersenne_twister.f,physparam.f,radcons.f90 + dependencies = machine.F,mersenne_twister.f,radcons.f90 ######################################################################## [ccpp-arg-table] @@ -134,6 +134,20 @@ dimensions = () type = integer intent = in +[ipsd0] + standard_name = initial_seed_for_mcica + long_name = initial permutaion seed for mcica radiation + units = 1 + dimensions = () + type = integer + intent = in +[ipsdlim] + standard_name = limit_for_initial_seed_for_mcica + long_name = limit for initial permutaion seed for mcica radiation + units = 1 + dimensions = () + type = integer + intent = in [ps_2delt] standard_name = surface_air_pressure_two_timesteps_back long_name = surface air pressure two timesteps back diff --git a/physics/GFS_radiation_surface.F90 b/physics/GFS_radiation_surface.F90 index 6a23cb264..feae36fbe 100644 --- a/physics/GFS_radiation_surface.F90 +++ b/physics/GFS_radiation_surface.F90 @@ -17,14 +17,15 @@ module GFS_radiation_surface !> \section arg_table_GFS_radiation_surface_init Argument Table !! \htmlinclude GFS_radiation_surface_init.html !! - subroutine GFS_radiation_surface_init (me, ialb, iems, errmsg, errflg) + subroutine GFS_radiation_surface_init (me, ialb, iems, semis_file, con_pi, errmsg, errflg) - use physparam, only: ialbflg, iemsflg use module_radiation_surface, only: sfc_init implicit none integer, intent(in) :: me, ialb, iems + character(len=26), intent(in) :: semis_file + real(kind_phys), intent(in) :: con_pi character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -32,16 +33,13 @@ subroutine GFS_radiation_surface_init (me, ialb, iems, errmsg, errflg) errmsg = '' errflg = 0 - ialbflg= ialb ! surface albedo control flag - iemsflg= iems ! surface emissivity control flag - if ( me == 0 ) then print *,'In GFS_radiation_surface_init, before calling sfc_init' print *,'ialb=',ialb,' iems=',iems end if ! Call surface initialization routine - call sfc_init ( me, errmsg, errflg ) + call sfc_init ( me, ialb, iems, semis_file, con_pi, errmsg, errflg ) end subroutine GFS_radiation_surface_init @@ -50,13 +48,13 @@ end subroutine GFS_radiation_surface_init !! \htmlinclude GFS_radiation_surface_run.html !! subroutine GFS_radiation_surface_run ( & - im, nf_albd, frac_grid, lslwr, lsswr, lsm, lsm_noahmp, lsm_ruc, & - xlat, xlon, slmsk, lndp_type, n_var_lndp, sfc_alb_pert, & + ialb, im, nf_albd, frac_grid, lslwr, lsswr, lsm, lsm_noahmp, & + lsm_ruc, xlat, xlon, slmsk, lndp_type, n_var_lndp, sfc_alb_pert,& lndp_var_list, lndp_prt_list, landfrac, snodl, snodi, sncovr, & sncovr_ice, fice, zorl, hprime, tsfg, tsfa, tisfc, coszen, & cplice, min_seaice, min_lakeice, lakefrac, use_flake, & alvsf, alnsf, alvwf, alnwf, facsf, facwf, & - semis_lnd, semis_ice, semis_wat, snoalb, use_cice_alb, & + semis_lnd, semis_ice, semis_wat, snoalb, use_cice_alb, con_ttp, & albdvis_lnd, albdnir_lnd, albivis_lnd, albinir_lnd, & albdvis_ice, albdnir_ice, albivis_ice, albinir_ice, & semisbase, semis, sfcalb, sfc_alb_dif, errmsg, errflg) @@ -67,10 +65,10 @@ subroutine GFS_radiation_surface_run ( & implicit none - integer, intent(in) :: im, nf_albd + integer, intent(in) :: im, nf_albd, ialb logical, intent(in) :: frac_grid, lslwr, lsswr, use_cice_alb, cplice integer, intent(in) :: lsm, lsm_noahmp, lsm_ruc, lndp_type, n_var_lndp - real(kind=kind_phys), intent(in) :: min_seaice, min_lakeice + real(kind=kind_phys), intent(in) :: min_seaice, min_lakeice, con_ttp logical, dimension(:), intent(in) :: use_flake real(kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, slmsk, & @@ -184,7 +182,8 @@ subroutine GFS_radiation_surface_run ( & alvsf, alnsf, alvwf, alnwf, facsf, facwf, fice, tisfc, & albdvis_lnd, albdnir_lnd, albivis_lnd, albinir_lnd, & albdvis_ice, albdnir_ice, albivis_ice, albinir_ice, & - im, nf_albd, sfc_alb_pert, lndp_alb, fracl, fraco, fraci, icy, & ! --- inputs + im, nf_albd, sfc_alb_pert, lndp_alb, fracl, fraco, fraci, icy, ialb, & + con_ttp, & ! --- inputs sfcalb ) ! --- outputs !> -# Approximate mean surface albedo from vis- and nir- diffuse values. diff --git a/physics/GFS_radiation_surface.meta b/physics/GFS_radiation_surface.meta index 771cd5f4d..22f2d4f0b 100644 --- a/physics/GFS_radiation_surface.meta +++ b/physics/GFS_radiation_surface.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_radiation_surface type = scheme - dependencies = iounitdef.f,machine.F,physparam.f,radiation_surface.f,set_soilveg_ruc.F90,namelist_soilveg_ruc.F90 + dependencies = iounitdef.f,machine.F,radiation_surface.f,set_soilveg_ruc.F90,namelist_soilveg_ruc.F90 ######################################################################## [ccpp-arg-table] @@ -28,6 +28,22 @@ dimensions = () type = integer intent = in +[semis_file] + standard_name = surface_emissivity_data_file + long_name = surface emissivity data file for radiation + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -55,6 +71,13 @@ dimensions = () type = integer intent = in +[ialb] + standard_name = control_for_surface_albedo + long_name = flag for using climatology alb, based on sfc type + units = flag + dimensions = () + type = integer + intent = in [nf_albd] standard_name = number_of_components_for_surface_albedo long_name = number of IR/VIS/UV compinents for surface albedo @@ -387,6 +410,14 @@ dimensions = () type = logical intent = in +[con_ttp] + standard_name = triple_point_temperature_of_water + long_name = triple point temperature of water + units = K + dimensions = () + type = real + kind = kind_phys + intent = in [albdvis_lnd] standard_name = surface_albedo_direct_visible_over_land long_name = direct surface albedo visible band over land diff --git a/physics/GFS_rrtmg_pre.F90 b/physics/GFS_rrtmg_pre.F90 index d05f02dae..53e1d29b3 100644 --- a/physics/GFS_rrtmg_pre.F90 +++ b/physics/GFS_rrtmg_pre.F90 @@ -17,41 +17,38 @@ module GFS_rrtmg_pre !! \htmlinclude GFS_rrtmg_pre_run.html !! !>\section rrtmg_pre_gen General Algorithm - subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & - n_var_lndp, imfdeepcnv, imfdeepcnv_gf, me, ncnd, ntrac, num_p3d, & - npdf3d, ncnvcld3d, ntqv, ntcw,ntiw, ntlnc, ntinc, ntrnc, ntsnc, ntccn, & - ntrw, ntsw, ntgl, nthl, ntwa, ntoz, & + subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& + ltp, imfdeepcnv, imfdeepcnv_gf, me, ncnd, ntrac, num_p3d, npdf3d, & + ncnvcld3d,ntqv, ntcw,ntiw, ntlnc, ntinc, ntrnc, ntsnc, ntccn, top_at_1,& + ntrw, ntsw, ntgl, nthl, ntwa, ntoz, ntsmoke, ntdust, ntcoarsepm, & ntclamt, nleffr, nieffr, nseffr, lndp_type, kdt, & ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2, & ntss3, ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl, ntchm, & imp_physics,imp_physics_nssl, nssl_ccn_on, nssl_invertccn, & imp_physics_thompson, imp_physics_gfdl, imp_physics_zhao_carr, & imp_physics_zhao_carr_pdf, imp_physics_mg, imp_physics_wsm6, & - imp_physics_fer_hires, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & - iovr_exp, iovr_exprand, idcor_con, idcor_hogan, idcor_oreopoulos, & - julian, yearlen, lndp_var_list, lsswr, lslwr, & - ltaerosol, mraerosol, lgfdlmprad, uni_cld, effr_in, do_mynnedmf, lmfshal, & - lmfdeep2, fhswr, fhlwr, solhr, sup, con_eps, epsm1, fvirt, & - rog, rocp, con_rd, xlat_d, xlat, xlon, coslat, sinlat, tsfc, slmsk, & - prsi, prsl, prslk, tgrs, sfc_wts, mg_cld, effrr_in, pert_clds, & - sppt_wts, sppt_amp, cnvw_in, cnvc_in, qgrs, aer_nm, dx, icloud, & !inputs from here and above + imp_physics_fer_hires, iovr, iovr_rand, iovr_maxrand, iovr_max, & + iovr_dcorr, iovr_exp, iovr_exprand, idcor, idcor_con, idcor_hogan, & + idcor_oreopoulos, dcorr_con, julian, yearlen, lndp_var_list, lsswr, & + lslwr, ltaerosol, mraerosol, lgfdlmprad, uni_cld, effr_in, do_mynnedmf,& + lmfshal, lcnorm, lmfdeep2, lcrick, fhswr, fhlwr, solhr, sup, con_eps, & + epsm1, fvirt, rog, rocp, con_rd, xlat_d, xlat, xlon, coslat, sinlat, & + tsfc, slmsk, prsi, prsl, prslk, tgrs, sfc_wts, mg_cld, effrr_in, & + pert_clds, sppt_wts, sppt_amp, cnvw_in, cnvc_in, qgrs, aer_nm, dx, & + icloud, iaermdl, iaerflg, con_pi, con_g, con_ttp, con_thgni, si, & !inputs from here and above coszen, coszdg, effrl_inout, effri_inout, effrs_inout, & clouds1, clouds2, clouds3, clouds4, clouds5, qci_conv, & !in/out from here and above kd, kt, kb, mtopa, mbota, raddt, tsfg, tsfa, de_lgth, alb1d, delp, dz, & !output from here and below plvl, plyr, tlvl, tlyr, qlyr, olyr, gasvmr_co2, gasvmr_n2o, gasvmr_ch4,& gasvmr_o2, gasvmr_co, gasvmr_cfc11, gasvmr_cfc12, gasvmr_cfc22, & - gasvmr_ccl4, gasvmr_cfc113, aerodp, clouds6, clouds7, clouds8, & + gasvmr_ccl4, gasvmr_cfc113, aerodp,ext550, clouds6, clouds7, clouds8, & clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, & - aero_dir_fdb, smoke_ext, dust_ext, & - spp_wts_rad, spp_rad, rrfs_smoke_band, errmsg, errflg) + aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, errmsg, errflg) use machine, only: kind_phys - use physparam - - use radcons, only: itsfc, qmin, & - qme5, qme6, epsq, prsmin + use radcons, only: itsfc, qmin, qme5, qme6, epsq, prsmin use funcphys, only: fpvs use module_radiation_astronomy,only: coszmn ! sol_init, sol_update @@ -82,7 +79,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & make_IceNumber, & make_DropletNumber, & make_RainNumber - use physparam, only : iaermdl implicit none integer, intent(in) :: im, levs, lm, lmk, lmp, ltp, & @@ -92,6 +88,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & ntcw, ntiw, ntlnc, ntinc, & ntrnc, ntsnc,ntccn, & ntrw, ntsw, ntgl, nthl, ntwa, ntoz, & + ntsmoke, ntdust, ntcoarsepm, & ntclamt, nleffr, nieffr, nseffr, & lndp_type, & kdt, imp_physics, & @@ -102,9 +99,10 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & imp_physics_mg, imp_physics_wsm6, & imp_physics_nssl, & imp_physics_fer_hires, & - yearlen, icloud + yearlen, icloud, iaermdl, iaerflg integer, intent(in) :: & + iovr, & ! choice of cloud-overlap method iovr_rand, & ! Flag for random cloud overlap method iovr_maxrand, & ! Flag for maximum-random cloud overlap method iovr_max, & ! Flag for maximum cloud overlap method @@ -112,31 +110,32 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & iovr_exp, & ! Flag for exponential cloud overlap method iovr_exprand, & ! Flag for exponential-random cloud overlap method idcor_con, & + idcor, & idcor_hogan, & idcor_oreopoulos, & - rrfs_smoke_band ! Band number for rrfs-smoke dust and smoke + ico2 ! Flag for co2 source used in radiation integer, intent(in) :: ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2, ntss3, & ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl, ntchm character(len=3), dimension(:), intent(in) :: lndp_var_list - logical, intent(in) :: lextop, lsswr, lslwr, ltaerosol, lgfdlmprad, & + logical, intent(in) :: lsswr, lslwr, ltaerosol, lgfdlmprad, & uni_cld, effr_in, do_mynnedmf, & - lmfshal, lmfdeep2, pert_clds, mraerosol + lmfshal, lmfdeep2, pert_clds, lcrick,& + lcnorm, top_at_1, lextop, mraerosol logical, intent(in) :: aero_dir_fdb - real(kind=kind_phys), dimension(:,:), intent(in) :: smoke_ext, dust_ext logical, intent(in) :: nssl_ccn_on, nssl_invertccn integer, intent(in) :: spp_rad real(kind_phys), intent(in) :: spp_wts_rad(:,:) - real(kind=kind_phys), intent(in) :: fhswr, fhlwr, solhr, sup, julian, sppt_amp - real(kind=kind_phys), intent(in) :: con_eps, epsm1, fvirt, rog, rocp, con_rd + real(kind=kind_phys), intent(in) :: fhswr, fhlwr, solhr, sup, julian, sppt_amp, dcorr_con + real(kind=kind_phys), intent(in) :: con_eps, epsm1, fvirt, rog, rocp, con_rd, con_pi, con_g, con_ttp, con_thgni real(kind=kind_phys), dimension(:), intent(in) :: xlat_d, xlat, xlon, & coslat, sinlat, tsfc, & - slmsk, dx + slmsk, dx, si real(kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, prslk, & tgrs, sfc_wts, & @@ -156,6 +155,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & clouds2, clouds3, & clouds4, clouds5 real(kind=kind_phys), dimension(:,:), intent(in) :: qci_conv + real(kind=kind_phys), dimension(:), intent(in) :: fdb_coef real(kind=kind_phys), dimension(:), intent(out) :: lwp_ex,iwp_ex, & lwp_fc,iwp_fc @@ -186,6 +186,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & gasvmr_ccl4,& gasvmr_cfc113 real(kind=kind_phys), dimension(:,:), intent(out) :: aerodp + real(kind=kind_phys), dimension(:,:), intent(out) :: ext550 real(kind=kind_phys), dimension(:,:), intent(out) :: clouds6, & clouds7, & clouds8, & @@ -202,7 +203,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & faerlw2,& faerlw3 real(kind=kind_phys), dimension(:,:), intent(out) :: alpha - character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -285,7 +285,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & ! variables if ( lextop ) then - if ( ivflip == 1 ) then ! vertical from sfc upward + if (.not. top_at_1) then ! vertical from sfc upward kd = 0 ! index diff between in/out and local kt = 1 ! index diff between lyr and upper bound kb = 0 ! index diff between lyr and lower bound @@ -301,16 +301,16 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & llb = 1 ! local index at toa level lya = 2 ! local index for the 2nd layer from top lyb = 1 ! local index for the top layer - endif ! end if_ivflip_block + endif ! end if_top_at_1_block else kd = 0 - if ( ivflip == 1 ) then ! vertical from sfc upward + if (.not. top_at_1) then ! vertical from sfc upward kt = 1 ! index diff between lyr and upper bound kb = 0 ! index diff between lyr and lower bound else ! vertical from toa downward kt = 0 ! index diff between lyr and upper bound kb = 1 ! index diff between lyr and lower bound - endif ! end if_ivflip_block + endif ! end if_top_at_1_block endif ! end if_lextop_block raddt = min(fhswr, fhlwr) @@ -337,7 +337,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & ! lsk = 0 - if (ivflip == 0 .and. lm < levs) lsk = levs - lm + if (top_at_1 .and. lm < levs) lsk = levs - lm ! convert pressure unit from pa to mb do k = 1, LM @@ -368,7 +368,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & enddo enddo ! - if (ivflip == 0) then ! input data from toa to sfc + if (top_at_1) then ! input data from toa to sfc if (lsk > 0) then k1 = 1 + kd k2 = k1 + kb @@ -427,8 +427,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & enddo enddo else ! climatological ozone - call getozn (prslk1, xlat, im, lmk, & ! --- inputs - olyr) ! --- outputs + call getozn (prslk1, xlat, im, lmk, top_at_1, & ! --- inputs + olyr) ! --- outputs endif ! end_if_ntoz !> - Call coszmn(), to compute cosine of zenith angle (only when SW is called) @@ -452,8 +452,8 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & ! --- ... set up non-prognostic gas volume mixing ratioes - call getgases (plvl, xlon, xlat, IM, LMK, & ! --- inputs - gasvmr) ! --- outputs + call getgases (plvl, xlon, xlat, IM, LMK, ico2, top_at_1,& ! --- inputs + con_pi, gasvmr) ! --- outputs !CCPP: re-assign gasvmr(:,:,NF_VGAS) to gasvmr_X(:,:) do k = 1, LMK @@ -479,7 +479,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & enddo enddo - if (ivflip == 0) then ! input data from toa to sfc + if (top_at_1) then ! input data from toa to sfc do i = 1, IM tem1d (i) = QME6 tem2da(i,1) = log( plyr(i,1) ) @@ -609,7 +609,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & dzb(i,1) = hzb(i,1) - hz(i,1) enddo - endif ! end_if_ivflip + endif ! end_if_top_at_1 !check print *,' in grrad : calling setaer ' @@ -637,13 +637,28 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & enddo endif +!>--- add smoke and dust --- + if (aero_dir_fdb) then + do k=1,lmk + do i=1,im + aer_nm(i,k,1 )=aer_nm(i,k,1 )+ qgrs(i,k,ntdust)*fdb_coef(1)*1.e-9 ! dust bin1 + aer_nm(i,k,2 )=aer_nm(i,k,2 )+(qgrs(i,k,ntdust)*fdb_coef(2) & + +qgrs(i,k,ntcoarsepm)*fdb_coef(3))*1.e-9 ! dust bin2 + aer_nm(i,k,3 )=aer_nm(i,k,3 )+qgrs(i,k,ntcoarsepm)*fdb_coef(4)*1.e-9 ! dust bin3 + aer_nm(i,k,4 )=aer_nm(i,k,4 )+qgrs(i,k,ntcoarsepm)*fdb_coef(5)*1.e-9 ! dust bin4 + aer_nm(i,k,12)=aer_nm(i,k,12)+qgrs(i,k,ntsmoke)*fdb_coef(6)*1.e-9 ! Smoke BC + aer_nm(i,k,14)=aer_nm(i,k,14)+qgrs(i,k,ntsmoke)*fdb_coef(7)*1.e-9 ! Smoke OA + enddo + enddo + endif + !> - Call module_radiation_aerosols::setaer() to setup aerosols !! property profile for radiation. call setaer (plvl, plyr, prslk1, tvly, rhly, slmsk, & ! --- inputs tracer1, aer_nm, xlon, xlat, IM, LMK, LMP,& - lsswr,lslwr, & - faersw,faerlw,aerodp) ! --- outputs + lsswr, lslwr, iaermdl, iaerflg, top_at_1, con_pi, & + con_rd, con_g, faersw, faerlw, aerodp, ext550, errflg, errmsg) ! --- outputs ! CCPP do j = 1,NBDSW @@ -657,16 +672,6 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & enddo enddo - !> - Add aerosol direct feedback effect by smoke and dust - if(aero_dir_fdb) then ! add smoke/dust extinctions - do k = 1, LMK - do i = 1, IM - ! 550nm (~18000/cm) - faersw1(i,k,rrfs_smoke_band) = faersw1(i,k,rrfs_smoke_band) + MIN(4.,smoke_ext(i,k) + dust_ext(i,k)) - enddo - enddo - endif - do j = 1,NBDLW do k = 1, LMK do i = 1, IM @@ -961,20 +966,21 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, lextop, ltp, & & ( plyr, plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs: & ccnd, ncndl, cnvw, cnvc, tracer1, & & xlat, xlon, slmsk, dz, delp, IM, LM, LMK, LMP, & - & deltaq, sup, me, icloud, kdt, & + & deltaq, sup, dcorr_con, me, icloud, kdt, & & ntrac, ntcw, ntiw, ntrw, ntsw, ntgl, ntclamt, & & imp_physics, imp_physics_nssl, imp_physics_fer_hires, & & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & & imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, & - & imp_physics_mg, iovr_rand, iovr_maxrand, iovr_max, & - & iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, & - & idcor_hogan, idcor_oreopoulos, & + & imp_physics_mg, iovr, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, idcor, idcor_con, & + & idcor_hogan, idcor_oreopoulos, lcrick, lcnorm, & & imfdeepcnv, imfdeepcnv_gf, do_mynnedmf, lgfdlmprad, & & uni_cld, lmfshal, lmfdeep2, cldcov, clouds1, & & effrl, effri, effrr, effrs, effr_in, & & effrl_inout, effri_inout, effrs_inout, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzb, xlat_d, julian, yearlen, gridkm, & + & dzb, xlat_d, julian, yearlen, gridkm, top_at_1, si, & + & con_ttp, con_pi, con_g, con_rd, con_thgni, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & ! --- outputs: & cld_rwp, cld_rerain, cld_swp, cld_resnow, & ! --- outputs: & cldsa, mtopa, mbota, de_lgth, alpha & ! --- outputs: diff --git a/physics/GFS_rrtmg_pre.meta b/physics/GFS_rrtmg_pre.meta index 63ab11d3e..82ffd07c2 100644 --- a/physics/GFS_rrtmg_pre.meta +++ b/physics/GFS_rrtmg_pre.meta @@ -2,7 +2,7 @@ name = GFS_rrtmg_pre type = scheme dependencies = funcphys.f90,iounitdef.f,machine.F,module_bfmicrophysics.f,module_mp_radar.F90,module_mp_thompson.F90 - dependencies = module_mp_thompson_make_number_concentrations.F90,physcons.F90,physparam.f,radcons.f90,radiation_aerosols.f + dependencies = module_mp_thompson_make_number_concentrations.F90,radcons.f90,radiation_aerosols.f dependencies = radiation_astronomy.f,radiation_clouds.f,radiation_gases.f,radlw_param.f,radsw_param.f,surface_perturbation.F90,radiation_cloud_overlap.F90 ######################################################################## @@ -219,6 +219,41 @@ dimensions = () type = integer intent = in +[ntsmoke] + standard_name = index_for_smoke_in_tracer_concentration_array + long_name = tracer index for smoke + units = index + dimensions = () + type = integer + intent = in +[ntdust] + standard_name = index_for_dust_in_tracer_concentration_array + long_name = tracer index for dust + units = index + dimensions = () + type = integer + intent = in +[ntcoarsepm] + standard_name = index_for_coarse_particulate_matter_in_tracer_concentration_array + long_name = tracer index for coarse particulate matter + units = index + dimensions = () + type = integer + intent = in +[iaermdl] + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 + dimensions = () + type = integer + intent = in +[iaerflg] + standard_name = control_for_aerosol_effects_in_radiation + long_name = control of aerosol effects in radiation + units = 1 + dimensions = () + type = integer + intent = in [nssl_ccn_on] standard_name = nssl_ccn_on long_name = CCN activation flag in NSSL micro @@ -450,6 +485,13 @@ dimensions = () type = integer intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = max-random overlap clouds + units = flag + dimensions = () + type = integer + intent = in [iovr_rand] standard_name = flag_for_random_cloud_overlap_method long_name = choice of random cloud overlap method @@ -492,6 +534,20 @@ dimensions = () type = integer intent = in +[dcorr_con] + standard_name = decorrelation_length_used_by_overlap_method + long_name = decorrelation length (default) used by cloud overlap method (iovr) + units = km + dimensions = () + type = real + intent = in +[idcor] + standard_name = flag_for_decorrelation_length_method + long_name = flag for decorrelation length method used in cloud overlap method (iovr) + units = flag + dimensions = () + type = integer + intent = in [idcor_con] standard_name = flag_for_constant_decorrelation_length_method long_name = choice of decorrelation length computation (costant) @@ -606,6 +662,20 @@ dimensions = () type = logical intent = in +[lcrick] + standard_name = flag_for_CRICK_proof_cloud_water + long_name = flag for CRICK-Proof cloud water + units = flag + dimensions = () + type = logical + intent = in +[lcnorm] + standard_name = flag_for_in_cloud_condensate + long_name = flag for cloud condensate normalized by cloud cover + units = flag + dimensions = () + type = logical + intent = in [fhswr] standard_name = period_of_shortwave_radiation_calls long_name = frequency for shortwave radiation @@ -646,6 +716,46 @@ type = real kind = kind_phys intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[con_rd] + standard_name = gas_constant_of_dry_air + long_name = ideal gas constant for dry air + units = J kg-1 K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_g] + standard_name = gravitational_acceleration + long_name = gravitational acceleration + units = m s-2 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_ttp] + standard_name = triple_point_temperature_of_water + long_name = triple point temperature of water + units = K + dimensions = () + type = real + kind = kind_phys + intent = in +[con_thgni] + standard_name = temperature_ice_nucleation_starts + long_name = temperature the H.G.Nuc. ice starts + units = K + dimensions = () + type = real + kind = kind_phys + intent = in [epsm1] standard_name = ratio_of_dry_air_to_water_vapor_gas_constants_minus_one long_name = (rd/rv) - 1 @@ -678,14 +788,6 @@ type = real kind = kind_phys intent = in -[con_rd] - standard_name = gas_constant_of_dry_air - long_name = ideal gas constant for dry air - units = J kg-1 K-1 - dimensions = () - type = real - kind = kind_phys - intent = in [xlat_d] standard_name = latitude_in_degree long_name = latitude in degree north @@ -1183,6 +1285,14 @@ type = real kind = kind_phys intent = out +[ext550] + standard_name = aerosol_optical_depth_at_550nm + long_name = 3d optical extinction for total aerosol species + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = out [clouds6] standard_name = cloud_rain_water_path long_name = cloud rain water path @@ -1327,26 +1437,40 @@ type = real kind = kind_phys intent = out -[aero_dir_fdb] - standard_name = do_smoke_aerosol_direct_feedback - long_name = flag for smoke and dust radiation feedback +[top_at_1] + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical intent = in -[smoke_ext] - standard_name = extinction_coefficient_in_air_due_to_smoke - long_name = extinction coefficient in air due to smoke - units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension) +[si] + standard_name = sigma_pressure_hybrid_vertical_coordinate + long_name = vertical sigma coordinate for radiation initialization + units = none + dimensions = (vertical_interface_dimension) type = real kind = kind_phys intent = in -[dust_ext] - standard_name = extinction_coefficient_in_air_due_to_dust - long_name = extinction coefficient in air due to dust - units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension) +[ico2] + standard_name = control_for_co2 + long_name = prescribed global mean value (old opernl) + units = flag + dimensions = () + type = integer + intent = in +[aero_dir_fdb] + standard_name = do_smoke_aerosol_direct_feedback + long_name = flag for smoke and dust radiation feedback + units = flag + dimensions = () + type = logical + intent = in +[fdb_coef] + standard_name = smoke_dust_direct_fdb_coef + long_name = smoke dust direct feedback coefficents + units = none + dimensions = (7) type = real kind = kind_phys intent = in @@ -1365,13 +1489,6 @@ dimensions = () type = integer intent = in -[rrfs_smoke_band] - standard_name = index_of_shortwave_band_affected_by_smoke - long_name = rrtmg band number that smoke and dust should affect - units = count - dimensions = () - type = integer - intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/GFS_rrtmg_setup.F90 b/physics/GFS_rrtmg_setup.F90 index 86d8fab7b..384d5252d 100644 --- a/physics/GFS_rrtmg_setup.F90 +++ b/physics/GFS_rrtmg_setup.F90 @@ -6,12 +6,7 @@ !> @{ module GFS_rrtmg_setup - use physparam, only : isolar , ictmflg, ico2flg, ioznflg, iaerflg, & - & iaermdl, icldflg, & - & iovrRad=>iovr, lcrick , lcnorm , lnoprec, & - & isubcsw, isubclw, ivflip , ipsd0, & - & iswcliq, & - & kind_phys + use machine, only: kind_phys implicit none @@ -27,14 +22,14 @@ module GFS_rrtmg_setup ! & VTAGRAD='NCEP-Radiation_driver v5.1 Nov 2012 ' ! & VTAGRAD='NCEP-Radiation_driver v5.0 Aug 2012 ' - !> new data input control variables (set/reset in subroutines radinit/radupdate): + !> new data input control variables (set/reset in subroutine radupdate): integer :: month0 = 0 integer :: iyear0 = 0 integer :: monthd = 0 !> control flag for the first time of reading climatological ozone data !! (set/reset in subroutines radinit/radupdate, it is used only if the - !! control parameter ioznflg=0) + !! control parameter ntoz=0) logical :: loz1st = .true. contains @@ -42,13 +37,14 @@ module GFS_rrtmg_setup !> \section arg_table_GFS_rrtmg_setup_init Argument Table !! \htmlinclude GFS_rrtmg_setup_init.html !! - subroutine GFS_rrtmg_setup_init ( & - si, levr, ictm, isol, ico2, iaer, ntcw, & - num_p3d, npdf3d, ntoz, iovr, isubc_sw, isubc_lw, & - icliq_sw, crick_proof, ccnorm, & - imp_physics, & - norad_precip, idate, iflip, & - do_RRTMGP, me, ltp, lextop, errmsg, errflg) + subroutine GFS_rrtmg_setup_init ( si, levr, ictm, isol, solar_file, ico2, & + iaer, ntcw, num_p3d, npdf3d, ntoz, iovr, iovr_rand, iovr_maxrand, & + iovr_max, iovr_dcorr, iovr_exp, iovr_exprand, icliq_sw, lcrick, & + lcnorm, imp_physics, lnoprec, idate, iflip, do_RRTMGP, me, lalw1bd, & + iaermdl, iaerflg, aeros_file, con_pi, con_t0c, con_c, con_boltz, & + con_plnk, con_solr_2008, con_solr_2002, con_g, con_rd, co2usr_file, & + co2cyc_file, rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, isubclw,& + iswmode, ipsd0, ltp, lextop, errmsg, errflg) ! ================= subprogram documentation block ================ ! ! ! ! subprogram: GFS_rrtmg_setup_init - a subprogram to initialize radiation ! @@ -125,14 +121,14 @@ subroutine GFS_rrtmg_setup_init ( & ! =1: max/ran overlapping clouds ! ! =2: maximum overlap clouds (mcica only) ! ! =3: decorrelation-length overlap (mcica only) ! -! =4: exponential overlap clouds -! isubc_sw/isubc_lw: sub-column cloud approx control flag (sw/lw rad) ! +! =4: exponential overlap clouds ! +! isubcsw/isubclw: sub-column cloud approx control flag (sw/lw rad) ! ! =0: with out sub-column cloud approximation ! ! =1: mcica sub-col approx. prescribed random seed ! ! =2: mcica sub-col approx. provided random seed ! -! crick_proof : control flag for eliminating CRICK ! -! ccnorm : control flag for in-cloud condensate mixing ratio! -! norad_precip : control flag for not using precip in radiation ! +! lcrick : control flag for eliminating CRICK ! +! lcnorm : control flag for in-cloud condensate mixing ratio! +! lnoprec : control flag for not using precip in radiation ! ! idate(4) : ncep absolute date and time of initial condition ! ! (hour, month, day, year) ! ! iflip : control flag for direction of vertical index ! @@ -146,35 +142,31 @@ subroutine GFS_rrtmg_setup_init ( & ! ! ! =================================================================== ! ! + use module_radiation_astronomy, only : sol_init + use module_radiation_aerosols, only : aer_init + use module_radiation_gases, only : gas_init + use module_radiation_clouds, only : cld_init + use rrtmg_lw, only : rlwinit + use rrtmg_sw, only : rswinit implicit none ! interface variables real (kind=kind_phys), intent(in) :: si(:) - integer, intent(in) :: levr - integer, intent(in) :: ictm - integer, intent(in) :: isol - integer, intent(in) :: ico2 - integer, intent(in) :: iaer - integer, intent(in) :: ntcw - integer, intent(in) :: num_p3d - integer, intent(in) :: npdf3d - integer, intent(in) :: ntoz - integer, intent(in) :: iovr - integer, intent(in) :: isubc_sw - integer, intent(in) :: isubc_lw - integer, intent(in) :: icliq_sw - logical, intent(in) :: crick_proof - logical, intent(in) :: ccnorm - integer, intent(in) :: imp_physics - logical, intent(in) :: norad_precip + integer, intent(in) :: levr, ictm, isol, ico2, iaer, ntcw, num_p3d, & + ltp, npdf3d, ntoz, iovr, iovr_rand, iovr_maxrand, iovr_max, & + iovr_dcorr, iovr_exp, iovr_exprand, icliq_sw, imp_physics, & + iflip, me, rad_hr_units, icliq_lw, isubcsw, isubclw, iswmode integer, intent(in) :: idate(:) - integer, intent(in) :: iflip - logical, intent(in) :: do_RRTMGP - integer, intent(in) :: me - integer, intent(in) :: ltp - logical, intent(in) :: lextop + logical, intent(in) :: lcrick, lcnorm, lnoprec, do_RRTMGP, lalw1bd, & + inc_minor_gas, lextop + character(len=26),intent(in) :: aeros_file, solar_file, co2usr_file,& + co2cyc_file + real(kind_phys), intent(in) :: con_pi, con_t0c, con_c, con_boltz, & + con_plnk, con_solr_2008, con_solr_2002, con_g, con_rd + integer, intent(inout) :: ipsd0 character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg + integer, intent(out) :: iaermdl, iaerflg ! Initialize the CCPP error handling variables errmsg = '' @@ -188,11 +180,6 @@ subroutine GFS_rrtmg_setup_init ( & return end if - isolar = isol ! solar constant control flag - ictmflg= ictm ! data ic time/date control flag - ico2flg= ico2 ! co2 data source control flag - ioznflg= ntoz ! ozone data source control flag - if ( ictm==0 .or. ictm==-2 ) then iaerflg = mod(iaer, 100) ! no volcanic aerosols for clim hindcast else @@ -201,58 +188,50 @@ subroutine GFS_rrtmg_setup_init ( & iaermdl = iaer/1000 ! control flag for aerosol scheme selection if ( iaermdl < 0 .or. (iaermdl>2 .and. iaermdl/=5) ) then print *, ' Error -- IAER flag is incorrect, Abort' - stop 7777 + errflg = 1 + errmsg = 'ERROR(GFS_rrtmg_setup): IAER flag is incorrect' + return endif -! if ( ntcw > 0 ) then - icldflg = 1 ! prognostic cloud optical prop scheme -! else -! icldflg = 0 ! no support for diag cloud opt prop scheme -! endif - - iswcliq = icliq_sw ! optical property for liquid clouds for sw - - ! iovr comes from the model. In the RRTMG implementation this is stored in phyrparam.f, - ! it comes in from the host-model and is set here. - ! In GP, iovr is passed directly into the routines. - iovrRAD = iovr - lcrick = crick_proof ! control flag for eliminating CRICK - lcnorm = ccnorm ! control flag for in-cld condensate - lnoprec = norad_precip ! precip effect on radiation flag (ferrier microphysics) - isubcsw = isubc_sw ! sub-column cloud approx flag in sw radiation - isubclw = isubc_lw ! sub-column cloud approx flag in lw radiation - - ivflip = iflip ! vertical index direction control flag - ! --- assign initial permutation seed for mcica cloud-radiation - if ( isubc_sw>0 .or. isubc_lw>0 ) then + if ( isubcsw>0 .or. isubclw>0 ) then ! ipsd0 = 17*idate(1)+43*idate(2)+37*idate(3)+23*idate(4) + ipsd0 ipsd0 = 17*idate(1)+43*idate(2)+37*idate(3)+23*idate(4) endif if ( me == 0 ) then - print *,' In rad_initialize (GFS_rrtmg_setup_init), before calling radinit' - print *,' si =',si - print *,' levr=',levr,' ictm=',ictm,' isol=',isol,' ico2=',ico2,& - & ' iaermdl=',iaermdl,' iaerflg=',iaerflg - print *,' np3d=',num_p3d,' ntoz=',ntoz, & - & ' iovr=',iovr,' isubc_sw=',isubc_sw, & - & ' isubc_lw=',isubc_lw,' icliq_sw=',icliq_sw, & - & ' iflip=',iflip,' me=',me - print *,' crick_proof=',crick_proof, & - & ' ccnorm=',ccnorm,' norad_precip=',norad_precip + print *,' In rad_initialize (GFS_rrtmg_setup_init), before calling RRTMG initialization' + print *,' si =',si + print *,' levr=',levr,' ictm=',ictm,' isol=',isol,' ico2=',ico2,& + ' iaermdl=',iaermdl,' iaerflg=',iaerflg + print *,' np3d=',num_p3d,' ntoz=',ntoz, & + ' iovr=',iovr,' isubcsw=',isubcsw, & + ' isubclw=',isubclw,' icliq_sw=',icliq_sw, & + ' iflip=',iflip,' me=',me + print *,' lcrick=',lcrick, & + ' lcnorm=',lcnorm,' lnoprec=',lnoprec + print *, 'lextop=',lextop, ' ltp=',ltp endif - call radinit & -! --- inputs: - & ( si, levr, imp_physics, me, ltp, lextop ) -! --- outputs: -! ( none ) + ! Call initialization routines + call sol_init ( me, isol, solar_file, con_solr_2008,con_solr_2002,& + con_pi ) + call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, & + con_pi, con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) + call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, & + con_pi, errflg, errmsg) + call cld_init ( si, levr, imp_physics, me, con_g, con_rd, errflg, errmsg) + call rlwinit ( me, rad_hr_units, inc_minor_gas, icliq_lw, isubcsw, & + iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & + iovr_exp, iovr_exprand, errflg, errmsg ) + call rswinit ( me, rad_hr_units, inc_minor_gas, icliq_sw, isubclw, & + iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & + iovr_exp, iovr_exprand,iswmode, errflg, errmsg ) if ( me == 0 ) then print *,' Radiation sub-cloud initial seed =',ipsd0, & & ' IC-idate =',idate - print *,' return from rad_initialize (GFS_rrtmg_setup_init) - after calling radinit' + print *,' return from rad_initialize (GFS_rrtmg_setup_init) - after calling RRTMG initialization' endif ! is_initialized = .true. @@ -264,9 +243,9 @@ end subroutine GFS_rrtmg_setup_init !> \section arg_table_GFS_rrtmg_setup_timestep_init Argument Table !! \htmlinclude GFS_rrtmg_setup_timestep_init.html !! - subroutine GFS_rrtmg_setup_timestep_init ( & - idate, jdate, deltsw, deltim, lsswr, me, & - slag, sdec, cdec, solcon, errmsg, errflg) + subroutine GFS_rrtmg_setup_timestep_init (idate, jdate, deltsw, deltim, & + lsswr, me, iaermdl, iaerflg, isol, aeros_file, slag, sdec, cdec, & + solcon, con_pi, co2dat_file, co2gbl_file, ictm, ico2, ntoz, errmsg, errflg) implicit none @@ -275,8 +254,11 @@ subroutine GFS_rrtmg_setup_timestep_init ( & integer, intent(in) :: jdate(:) real(kind=kind_phys), intent(in) :: deltsw real(kind=kind_phys), intent(in) :: deltim + real(kind=kind_phys), intent(in) :: con_pi logical, intent(in) :: lsswr integer, intent(in) :: me + integer, intent(in) :: iaermdl, iaerflg, isol, ictm, ico2, ntoz + character(len=26), intent(in) :: aeros_file, co2dat_file, co2gbl_file real(kind=kind_phys), intent(out) :: slag real(kind=kind_phys), intent(out) :: sdec real(kind=kind_phys), intent(out) :: cdec @@ -295,8 +277,8 @@ subroutine GFS_rrtmg_setup_timestep_init ( & errmsg = '' errflg = 0 - call radupdate(idate,jdate,deltsw,deltim,lsswr,me, & - slag,sdec,cdec,solcon) + call radupdate(idate,jdate,deltsw,deltim,lsswr,me,iaermdl, iaerflg,isol,aeros_file,& + slag,sdec,cdec,solcon,con_pi,co2dat_file,co2gbl_file,ictm,ico2,ntoz,errflg,errmsg) end subroutine GFS_rrtmg_setup_timestep_init @@ -322,229 +304,6 @@ subroutine GFS_rrtmg_setup_finalize (errmsg, errflg) end subroutine GFS_rrtmg_setup_finalize - -! Private functions - -!>Initialization of radiation calculations. - subroutine radinit( si, NLAY, imp_physics, me, ltp, lextop ) -!................................... - -! --- inputs: -! & ( si, NLAY, imp_physics, me ) -! --- outputs: -! ( none ) - -! ================= subprogram documentation block ================ ! -! ! -! subprogram: radinit initialization of radiation calculations ! -! ! -! usage: call radinit ! -! ! -! attributes: ! -! language: fortran 90 ! -! machine: wcoss ! -! ! -! ==================== definition of variables ==================== ! -! ! -! input parameters: ! -! si : model vertical sigma interface ! -! NLAY : number of model vertical layers ! -! imp_physics : MP identifier ! -! me : print control flag ! -! ! -! outputs: (none) ! -! ! -! external module variables: (in module physparam) ! -! isolar : solar constant cntrol flag ! -! = 0: use the old fixed solar constant in "physcon" ! -! =10: use the new fixed solar constant in "physcon" ! -! = 1: use noaa ann-mean tsi tbl abs-scale with cycle apprx! -! = 2: use noaa ann-mean tsi tbl tim-scale with cycle apprx! -! = 3: use cmip5 ann-mean tsi tbl tim-scale with cycl apprx! -! = 4: use cmip5 mon-mean tsi tbl tim-scale with cycl apprx! -! iaerflg : 3-digit aerosol flag (abc for volc, lw, sw) ! -! a:=0 use background stratospheric aerosol ! -! =1 include stratospheric vocanic aeros ! -! b:=0 no topospheric aerosol in lw radiation ! -! =1 compute tropspheric aero in 1 broad band for lw ! -! =2 compute tropspheric aero in multi bands for lw ! -! c:=0 no topospheric aerosol in sw radiation ! -! =1 include tropspheric aerosols for sw ! -! ico2flg : co2 data source control flag ! -! =0: use prescribed global mean co2 (old oper) ! -! =1: use observed co2 annual mean value only ! -! =2: use obs co2 monthly data with 2-d variation ! -! ictmflg : =yyyy#, external data ic time/date control flag ! -! = -2: same as 0, but superimpose seasonal cycle ! -! from climatology data set. ! -! = -1: use user provided external data for the ! -! forecast time, no extrapolation. ! -! = 0: use data at initial cond time, if not ! -! available, use latest, no extrapolation. ! -! = 1: use data at the forecast time, if not ! -! available, use latest and extrapolation. ! -! =yyyy0: use yyyy data for the forecast time, ! -! no further data extrapolation. ! -! =yyyy1: use yyyy data for the fcst. if needed, do ! -! extrapolation to match the fcst time. ! -! ioznflg : ozone data source control flag ! -! =0: use climatological ozone profile ! -! =1: use interactive ozone profile ! -! icldflg : cloud optical property scheme control flag ! -! =0: use diagnostic cloud scheme ! -! =1: use prognostic cloud scheme (default) ! -! imp_physics : cloud microphysics scheme control flag ! -! =99 zhao/carr/sundqvist microphysics scheme ! -! =98 zhao/carr/sundqvist microphysics+pdf cloud&cnvc,cnvw ! -! =11 GFDL cloud microphysics ! -! =8 Thompson microphysics scheme ! -! =6 WSM6 microphysics scheme ! -! =10 MG microphysics scheme ! -! iovr : control flag for cloud overlap in radiation ! -! =0: random overlapping clouds ! -! =1: max/ran overlapping clouds ! -! isubcsw : sub-column cloud approx control flag in sw radiation ! -! isubclw : sub-column cloud approx control flag in lw radiation ! -! =0: with out sub-column cloud approximation ! -! =1: mcica sub-col approx. prescribed random seed ! -! =2: mcica sub-col approx. provided random seed ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! lnoprec : precip effect in radiation flag (ferrier microphysics) ! -! =t: snow/rain has no impact on radiation ! -! =f: snow/rain has impact on radiation ! -! ivflip : vertical index direction control flag ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! -! subroutines called: sol_init, aer_init, gas_init, cld_init, ! -! rlwinit, rswinit ! -! ! -! usage: call radinit ! -! ! -! =================================================================== ! -! - - use module_radiation_astronomy, only : sol_init - use module_radiation_aerosols, only : aer_init - use module_radiation_gases, only : gas_init - use module_radiation_clouds, only : cld_init - use rrtmg_lw, only : rlwinit - use rrtmg_sw, only : rswinit - - implicit none - -! --- inputs: - integer, intent(in) :: NLAY, me, imp_physics, ltp - logical, intent(in) :: lextop - - real (kind=kind_phys), intent(in) :: si(:) - -! --- outputs: (none, to module variables) - -! --- locals: - -! -!===> ... begin here -! -!> -# Set up control variables and external module variables in -!! module physparam - loz1st = (ioznflg == 0) ! first-time clim ozone data read flag - month0 = 0 - iyear0 = 0 - monthd = 0 - - if (me == 0) then -! print *,' NEW RADIATION PROGRAM STRUCTURES -- SEP 01 2004' - print *,' NEW RADIATION PROGRAM STRUCTURES BECAME OPER. ', & - & ' May 01 2007' - print *, VTAGRAD !print out version tag - print *,' - Selected Control Flag settings: ICTMflg=',ictmflg, & - & ' ISOLar =',isolar, ' ICO2flg=',ico2flg,' IAERflg=',iaerflg, & - & ' ICLDflg=',icldflg, & - & ' IMP_PHYSICS=',imp_physics,' IOZNflg=',ioznflg - print *,' IVFLIP=',ivflip,' IOVR=',iovrRad, & - & ' ISUBCSW=',isubcsw,' ISUBCLW=',isubclw - print *,' LCRICK=',lcrick,' LCNORM=',lcnorm,' LNOPREC=',lnoprec - print *,' LTP =',ltp,', add extra top layer =',lextop - - if ( ictmflg==0 .or. ictmflg==-2 ) then - print *,' Data usage is limited by initial condition!' - print *,' No volcanic aerosols' - endif - - if ( isubclw == 0 ) then - print *,' - ISUBCLW=',isubclw,' No McICA, use grid ', & - & 'averaged cloud in LW radiation' - elseif ( isubclw == 1 ) then - print *,' - ISUBCLW=',isubclw,' Use McICA with fixed ', & - & 'permutation seeds for LW random number generator' - elseif ( isubclw == 2 ) then - print *,' - ISUBCLW=',isubclw,' Use McICA with random ', & - & 'permutation seeds for LW random number generator' - else - print *,' - ERROR!!! ISUBCLW=',isubclw,' is not a ', & - & 'valid option ' - stop - endif - - if ( isubcsw == 0 ) then - print *,' - ISUBCSW=',isubcsw,' No McICA, use grid ', & - & 'averaged cloud in SW radiation' - elseif ( isubcsw == 1 ) then - print *,' - ISUBCSW=',isubcsw,' Use McICA with fixed ', & - & 'permutation seeds for SW random number generator' - elseif ( isubcsw == 2 ) then - print *,' - ISUBCSW=',isubcsw,' Use McICA with random ', & - & 'permutation seeds for SW random number generator' - else - print *,' - ERROR!!! ISUBCSW=',isubcsw,' is not a ', & - & 'valid option ' - stop - endif - - if ( isubcsw /= isubclw ) then - print *,' - *** Notice *** ISUBCSW /= ISUBCLW !!!', & - & isubcsw, isubclw - endif - endif - -!> -# Initialization -!! - astronomy initialization routine: -!! call module_radiation_astronomy::sol_init() -!! - aerosols initialization routine: -!! call module_radiation_aerosols::aer_init() -!! - CO2 and other gases intialization routine: -!! call module_radiation_gases::gas_init() -!! - cloud initialization routine: -!! call module_radiation_clouds::cld_init() -!! - LW radiation initialization routine: -!! call module_radlw_main::rlwinit() -!! - SW radiation initialization routine: -!! call module_radsw_main::rswinit() -! Initialization - - call sol_init ( me ) ! --- ... astronomy initialization routine - - call aer_init ( NLAY, me ) ! --- ... aerosols initialization routine - - call gas_init ( me ) ! --- ... co2 and other gases initialization routine - - call cld_init ( si, NLAY, imp_physics, me) ! --- ... cloud initialization routine - - call rlwinit ( me ) ! --- ... lw radiation initialization routine - - call rswinit ( me ) ! --- ... sw radiation initialization routine -! - return -! - end subroutine radinit - !----------------------------------- - !> This subroutine checks and updates time sensitive data used by !! radiation computations. This subroutine needs to be placed inside !! the time advancement loop but outside of the horizontal grid loop. @@ -565,8 +324,9 @@ end subroutine radinit !! \param solcon solar constant adjusted by sun-earth distance \f$(W/m^2)\f$ !> \section gen_radupdate General Algorithm !----------------------------------- - subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & - & slag,sdec,cdec,solcon) + subroutine radupdate( idate,jdate,deltsw,deltim,lsswr,me, iaermdl,& + iaerflg, isol, aeros_file, slag,sdec,cdec,solcon, con_pi, & + co2dat_file,co2gbl_file, ictm, ico2, ntoz, errflg, errmsg) !................................... ! ================= subprogram documentation block ================ ! @@ -598,31 +358,6 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & ! sdec, cdec : sin and cos of the solar declination angle ! ! solcon : sun-earth distance adjusted solar constant (w/m2) ! ! ! -! external module variables: ! -! isolar : solar constant cntrl (in module physparam) ! -! = 0: use the old fixed solar constant in "physcon" ! -! =10: use the new fixed solar constant in "physcon" ! -! = 1: use noaa ann-mean tsi tbl abs-scale with cycle apprx! -! = 2: use noaa ann-mean tsi tbl tim-scale with cycle apprx! -! = 3: use cmip5 ann-mean tsi tbl tim-scale with cycl apprx! -! = 4: use cmip5 mon-mean tsi tbl tim-scale with cycl apprx! -! ictmflg : =yyyy#, external data ic time/date control flag ! -! = -2: same as 0, but superimpose seasonal cycle ! -! from climatology data set. ! -! = -1: use user provided external data for the ! -! forecast time, no extrapolation. ! -! = 0: use data at initial cond time, if not ! -! available, use latest, no extrapolation. ! -! = 1: use data at the forecast time, if not ! -! available, use latest and extrapolation. ! -! =yyyy0: use yyyy data for the forecast time, ! -! no further data extrapolation. ! -! =yyyy1: use yyyy data for the fcst. if needed, do ! -! extrapolation to match the fcst time. ! -! ! -! module variables: ! -! loz1st : first-time clim ozone data read flag ! -! ! ! subroutines called: sol_update, aer_update, gas_update ! ! ! ! =================================================================== ! @@ -634,13 +369,16 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & implicit none ! --- inputs: - integer, intent(in) :: idate(:), jdate(:), me + integer, intent(in) :: idate(:), jdate(:), me, iaermdl, iaerflg, isol, ictm, ntoz, ico2 logical, intent(in) :: lsswr + character(len=26),intent(in) :: aeros_file,co2dat_file,co2gbl_file - real (kind=kind_phys), intent(in) :: deltsw, deltim + real (kind=kind_phys), intent(in) :: deltsw, deltim, con_pi ! --- outputs: real (kind=kind_phys), intent(out) :: slag, sdec, cdec, solcon + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: integer :: iyear, imon, iday, ihour @@ -652,6 +390,11 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & ! !===> ... begin here ! + + ! Initialize the CCPP error handling variables + errmsg = '' + errflg = 0 + !> -# Set up time stamp at fcst time and that for green house gases !! (currently co2 only) ! --- ... time stamp at fcst time @@ -663,7 +406,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & ! --- ... set up time stamp used for green house gases (** currently co2 only) - if ( ictmflg==0 .or. ictmflg==-2 ) then ! get external data at initial condition time + if ( ictm==0 .or. ictm==-2 ) then ! get external data at initial condition time kyear = idate(1) kmon = idate(2) kday = idate(3) @@ -673,7 +416,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & kmon = imon kday = iday khour = ihour - endif ! end if_ictmflg_block + endif ! end if_ictm_block if ( month0 /= imon ) then lmon_chg = .true. @@ -686,12 +429,12 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & !! time interpolation. if (lsswr) then - if ( isolar == 0 .or. isolar == 10 ) then + if ( isol == 0 .or. isol == 10 ) then lsol_chg = .false. elseif ( iyear0 /= iyear ) then lsol_chg = .true. else - lsol_chg = ( isolar==4 .and. lmon_chg ) + lsol_chg = ( isol==4 .and. lmon_chg ) endif iyear0 = iyear @@ -699,7 +442,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & ! --- inputs: & ( jdate,kyear,deltsw,deltim,lsol_chg, me, & ! --- outputs: - & slag,sdec,cdec,solcon & + & slag,sdec,cdec,solcon,con_pi,errmsg,errflg & & ) endif ! end_if_lsswr_block @@ -707,7 +450,7 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & !> -# Call module_radiation_aerosols::aer_update(), monthly update, no !! time interpolation if ( lmon_chg ) then - call aer_update ( iyear, imon, me ) + call aer_update ( iyear, imon, me, iaermdl, aeros_file, errflg, errmsg ) endif !> -# Call co2 and other gases update routine: @@ -719,7 +462,8 @@ subroutine radupdate( idate,jdate,deltsw,deltim,lsswr, me, & lco2_chg = .false. endif - call gas_update ( kyear,kmon,kday,khour,loz1st,lco2_chg, me ) + call gas_update ( kyear,kmon,kday,khour,loz1st,lco2_chg, me, co2dat_file, & + co2gbl_file, ictm, ico2, ntoz, errflg, errmsg ) if ( loz1st ) loz1st = .false. diff --git a/physics/GFS_rrtmg_setup.meta b/physics/GFS_rrtmg_setup.meta index 599f974f4..adf6d8750 100644 --- a/physics/GFS_rrtmg_setup.meta +++ b/physics/GFS_rrtmg_setup.meta @@ -1,8 +1,8 @@ [ccpp-table-properties] name = GFS_rrtmg_setup type = scheme - dependencies = iounitdef.f,module_bfmicrophysics.f,physparam.f,radcons.f90,radiation_aerosols.f,radiation_astronomy.f,radiation_clouds.f - dependencies = module_mp_thompson.F90,radiation_gases.f,radlw_main.F90,radlw_param.f,radsw_main.F90,radsw_param.f + dependencies = iounitdef.f,module_bfmicrophysics.f,radcons.f90,radiation_aerosols.f,radiation_astronomy.f,radiation_clouds.f + dependencies = module_mp_thompson.F90,radiation_gases.f,radlw_main.F90,radlw_param.f,radsw_main.F90,radsw_param.f,machine.F ######################################################################## [ccpp-arg-table] @@ -37,6 +37,30 @@ dimensions = () type = integer intent = in +[solar_file] + standard_name = solar_constant_file + long_name = external solar constant data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[con_solr_2008] + standard_name = solar_constant_2008 + long_name = solar constant Tim 2008 + units = W m-2 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_solr_2002] + standard_name = solar_constant_2002 + long_name= solar constant Liu 2002 + units = W m-2 + dimensions = () + type = real + kind = kind_phys + intent = in [ico2] standard_name = control_for_co2 long_name = prescribed global mean value (old opernl) @@ -86,20 +110,69 @@ dimensions = () type = integer intent = in -[isubc_sw] +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[isubcsw] standard_name = flag_for_sw_clouds_grid_approximation long_name = flag for sw clouds sub-grid approximation units = flag dimensions = () type = integer intent = in -[isubc_lw] +[isubclw] standard_name = flag_for_lw_clouds_sub_grid_approximation long_name = flag for lw clouds sub-grid approximation units = flag dimensions = () type = integer intent = in +[iswmode] + standard_name = control_for_sw_scattering_choice + long_name = control of rrtmg shortwave scattering choice + units = 1 + dimensions = () + type = integer + intent = in [icliq_sw] standard_name = control_for_shortwave_radiation_liquid_clouds long_name = sw optical property for liquid clouds @@ -107,14 +180,14 @@ dimensions = () type = integer intent = in -[crick_proof] +[lcrick] standard_name = flag_for_CRICK_proof_cloud_water long_name = flag for CRICK-Proof cloud water units = flag dimensions = () type = logical intent = in -[ccnorm] +[lcnorm] standard_name = flag_for_in_cloud_condensate long_name = flag for cloud condensate normalized by cloud cover units = flag @@ -128,7 +201,7 @@ dimensions = () type = integer intent = in -[norad_precip] +[lnoprec] standard_name = flag_for_turning_off_precipitation_radiative_effect long_name = radiation precip flag for Ferrier/Moorthi units = flag @@ -163,6 +236,114 @@ dimensions = () type = integer intent = in +[aeros_file] + standard_name = aerosol_data_file + long_name = aerosol data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2usr_file] + standard_name = co2_user_data_table_file + long_name = co2 user defined data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2cyc_file] + standard_name = co2_clim_monthly_cycle_data_table_file + long_name = co2 climotological monthly cycle data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[rad_hr_units] + standard_name = control_for_radiation_heating_rate_units + long_name = control of heating rate units + units = 1 + dimensions = () + type = integer + intent = in +[inc_minor_gas] + standard_name = flag_to_include_minor_gases_in_rrtmg + long_name = flag to include minor trace gases in rrtmg + units = flag + dimensions = () + type = logical + intent = in +[icliq_lw] + standard_name = flag_for_optical_property_for_liquid_clouds_for_longwave_radiation + long_name = lw optical property for liquid clouds + units = flag + dimensions = () + type = integer + intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[con_c] + standard_name = speed_of_light_in_vacuum + long_name = speed of light in vacuum + units = m s-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_plnk] + standard_name = planck_constant + long_name = Planck constant + units = J s-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_boltz] + standard_name = boltzmann_constant + long_name = Boltzmann constant + units = J K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_t0c] + standard_name = temperature_at_zero_celsius + long_name = temperature at 0 degree Celsius + units = K + dimensions = () + type = real + kind = kind_phys + intent = in +[con_rd] + standard_name = gas_constant_of_dry_air + long_name = ideal gas constant for dry air + units = J kg-1 K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_g] + standard_name = gravitational_acceleration + long_name = gravitational acceleration + units = m s-2 + dimensions = () + type = real + kind = kind_phys + intent = in +[lalw1bd] + standard_name = do_longwave_aerosol_band_properties + long_name = control of band or multiband longwave aerosol properties + units = 1 + dimensions = () + type = logical + intent = in [ltp] standard_name = extra_top_layer long_name = extra top layer for radiation @@ -177,6 +358,27 @@ dimensions = () type = logical intent = in +[ipsd0] + standard_name = initial_seed_for_mcica + long_name = initial permutaion seed for mcica radiation + units = 1 + dimensions = () + type = integer + intent = inout +[iaermdl] + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 + dimensions = () + type = integer + intent = out +[iaerflg] + standard_name = control_for_aerosol_effects_in_radiation + long_name = control of aerosol effects in radiation + units = 1 + dimensions = () + type = integer + intent = out [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -241,6 +443,80 @@ dimensions = () type = integer intent = in +[iaermdl] + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 + dimensions = () + type = integer + intent = in +[iaerflg] + standard_name = control_for_aerosol_effects_in_radiation + long_name = control of aerosol effects in radiation + units = 1 + dimensions = () + type = integer + intent = in +[isol] + standard_name = control_for_solar_constant + long_name = use prescribed solar constant + units = flag + dimensions = () + type = integer + intent = in +[aeros_file] + standard_name = aerosol_data_file + long_name = aerosol data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2dat_file] + standard_name = co2_monthly_obs_data_table_file + long_name = co2 monthly observation data table + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2gbl_file] + standard_name = co2_global_annual_mean_data_table_file + long_name = co2 global annual mean data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[ictm] + standard_name = flag_for_initial_time_date_control + long_name = flag for initial conditions and forcing + units = flag + dimensions = () + type = integer + intent = in +[ico2] + standard_name = control_for_co2 + long_name = prescribed global mean value (old opernl) + units = flag + dimensions = () + type = integer + intent = in +[ntoz] + standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for ozone mixing ratio + units = index + dimensions = () + type = integer + intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [slag] standard_name = equation_of_time long_name = equation of time (radian) diff --git a/physics/GFS_rrtmgp_cloud_mp.F90 b/physics/GFS_rrtmgp_cloud_mp.F90 index 9ca340763..32104b7f8 100644 --- a/physics/GFS_rrtmgp_cloud_mp.F90 +++ b/physics/GFS_rrtmgp_cloud_mp.F90 @@ -27,7 +27,7 @@ module GFS_rrtmgp_cloud_mp reice_min = 10.0, & ! Minimum ice size allowed by GFDL MP scheme reice_max = 150.0 ! Maximum ice size allowed by GFDL MP scheme - public GFS_rrtmgp_cloud_mp_run + public GFS_rrtmgp_cloud_mp_init, GFS_rrtmgp_cloud_mp_run, GFS_rrtmgp_cloud_mp_finalize contains @@ -45,7 +45,7 @@ module GFS_rrtmgp_cloud_mp subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, & i_cldrain, i_cldsnow, i_cldgrpl, i_cldtot, i_cldliq_nc, i_cldice_nc, i_twa, kdt, & imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, doSWrad, doLWrad, effr_in, lmfshal, & - ltaerosol,mraerosol, icloud, imp_physics, imp_physics_thompson, imp_physics_gfdl, & + ltaerosol,mraerosol, icloud, imp_physics, imp_physics_thompson, imp_physics_gfdl, & lgfdlmprad, do_mynnedmf, uni_cld, lmfdeep2, p_lev, p_lay, t_lay, qs_lay, q_lay, & relhum, lsmask, xlon, xlat, dx, tv_lay, effrin_cldliq, effrin_cldice, & effrin_cldrain, effrin_cldsnow, tracer, cnv_mixratio, cld_cnv_frac, qci_conv, & @@ -462,6 +462,7 @@ subroutine cloud_mp_MYNN(nCol, nLev, lsmask, t_lay, p_lev, p_lay, qs_lay, relhum enddo end subroutine cloud_mp_MYNN + !> \ingroup GFS_rrtmgp_cloud_mp !! Compute cloud radiative properties for SAMF convective cloud scheme. !! @@ -484,47 +485,48 @@ subroutine cloud_mp_SAMF(nCol, nLev, t_lay, p_lev, p_lay, qs_lay, relhum, nCol, & ! Number of horizontal grid points nLev ! Number of vertical layers real(kind_phys), intent(in) :: & - con_g, & ! Physical constant: gravitational constant - con_ttp, & ! Triple point temperature of water (K) + con_g, & ! Physical constant: gravity (m s-2) + con_ttp, & ! Triple point temperature of water (K) alpha0 ! real(kind_phys), dimension(:,:),intent(in) :: & - t_lay, & ! Temperature at layer centers (K) - p_lev, & ! Pressure at layer interfaces (Pa) - p_lay, & ! - qs_lay, & ! - relhum, & ! - cnv_mixratio ! Convective cloud mixing-ratio (kg/kg) + t_lay, & ! Temperature at layer-centers (K) + p_lev, & ! Pressure at layer-interfaces (Pa) + p_lay, & ! Presure at layer-centers (Pa) + qs_lay, & ! Specific-humidity at layer-centers (kg/kg) + relhum, & ! Relative-humidity (1) + cnv_mixratio ! Convective cloud mixing-ratio (kg/kg) ! Outputs real(kind_phys), dimension(:,:),intent(inout) :: & cld_cnv_lwp, & ! Convective cloud liquid water path cld_cnv_reliq, & ! Convective cloud liquid effective radius cld_cnv_iwp, & ! Convective cloud ice water path cld_cnv_reice, & ! Convective cloud ice effecive radius - cld_cnv_frac ! Convective cloud-fraction (1) + cld_cnv_frac ! Convective cloud-fraction ! Local integer :: iCol, iLay - real(kind_phys) :: tem1, deltaP, clwc + real(kind_phys) :: tem0, tem1, deltaP, clwc + tem0 = 1.0e5/con_g do iLay = 1, nLev do iCol = 1, nCol if (cnv_mixratio(iCol,iLay) > 0._kind_phys) then tem1 = min(1.0, max(0.0, (con_ttp-t_lay(iCol,iLay))*0.05)) deltaP = abs(p_lev(iCol,iLay+1)-p_lev(iCol,iLay))*0.01 - clwc = max(0.0, cnv_mixratio(iCol,iLay)) * con_g * deltaP - cld_cnv_iwp(iCol,iLay) = clwc * tem1 - cld_cnv_lwp(iCol,iLay) = clwc - cld_cnv_iwp(iCol,iLay) + clwc = max(0.0, cnv_mixratio(iCol,iLay)) * tem0 * deltaP + cld_cnv_iwp(iCol,iLay) = clwc * tem1 + cld_cnv_lwp(iCol,iLay) = clwc - cld_cnv_iwp(iCol,iLay) cld_cnv_reliq(iCol,iLay) = reliq_def cld_cnv_reice(iCol,iLay) = reice_def ! Xu-Randall (1996) cloud-fraction. - cld_cnv_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), & + cld_cnv_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), & qs_lay(iCol,iLay), relhum(iCol,iLay), cnv_mixratio(iCol,iLay), alpha0) endif enddo enddo end subroutine cloud_mp_SAMF - + !> \ingroup GFS_rrtmgp_cloud_mp !! This routine computes the cloud radiative properties for a "unified cloud". !! - "unified cloud" implies that the cloud-fraction is PROVIDED. @@ -656,7 +658,6 @@ subroutine cloud_mp_uni(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_cldrai enddo ! nLev end subroutine cloud_mp_uni - !> \ingroup GFS_rrtmgp_cloud_mp !! This routine computes the cloud radiative properties for the Thompson cloud micro- !! physics scheme. @@ -834,11 +835,11 @@ function cld_frac_XuRandall(p_lay, qs_lay, relhum, cld_mr, alpha) return end function -!> \ingroup GFS_rrtmgp_cloud_mp -!! This routine is a wrapper to update the Thompson effective particle sizes used by the -!! RRTMGP radiation scheme. -!! -!! \section cmp_reff_Thompson_gen General Algorithm + ! ###################################################################################### + ! This routine is a wrapper to update the Thompson effective particle sizes used by the + ! RRTMGP radiation scheme. + ! + ! ###################################################################################### subroutine cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice_nc, & i_cldliq_nc, i_twa, q_lay, p_lay, t_lay, tracer, con_eps, con_rd, ltaerosol, & mraerosol, lsmask, effrin_cldliq, effrin_cldice, effrin_cldsnow) @@ -922,4 +923,5 @@ subroutine cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice enddo end subroutine cmp_reff_Thompson + end module GFS_rrtmgp_cloud_mp diff --git a/physics/GFS_rrtmgp_cloud_mp.meta b/physics/GFS_rrtmgp_cloud_mp.meta index 1eb870da8..b782e73b4 100644 --- a/physics/GFS_rrtmgp_cloud_mp.meta +++ b/physics/GFS_rrtmgp_cloud_mp.meta @@ -345,9 +345,9 @@ kind = kind_phys intent = inout [tracer] - standard_name = chemical_tracers - long_name = chemical tracers - units = g g-1 + standard_name = tracer_concentration + long_name = model layer mean tracer concentration + units = kg kg-1 dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) type = real kind = kind_phys diff --git a/physics/GFS_rrtmgp_cloud_overlap.F90 b/physics/GFS_rrtmgp_cloud_overlap.F90 index b294b4a99..0094f8165 100644 --- a/physics/GFS_rrtmgp_cloud_overlap.F90 +++ b/physics/GFS_rrtmgp_cloud_overlap.F90 @@ -100,6 +100,7 @@ subroutine GFS_rrtmgp_cloud_overlap_run(nCol, nLev, yearlen, doSWrad, doLWrad, ! ! Cloud decorrelation length ! + de_lgth(:) = 0. if (idcor == idcor_hogan) then call cmp_dcorr_lgth(nCol, lat, con_pi, de_lgth) endif @@ -116,7 +117,6 @@ subroutine GFS_rrtmgp_cloud_overlap_run(nCol, nLev, yearlen, doSWrad, doLWrad, if (iovr == iovr_dcorr .or. iovr == iovr_exp .or. iovr == iovr_exprand) then call get_alpha_exper(nCol, nLev, iovr, iovr_exprand, deltaZc*0.001, de_lgth, cld_frac, cloud_overlap_param) else - de_lgth(:) = 0. cloud_overlap_param(:,:) = 0. endif @@ -127,7 +127,6 @@ subroutine GFS_rrtmgp_cloud_overlap_run(nCol, nLev, yearlen, doSWrad, doLWrad, if (iovr_convcld == iovr_dcorr .or. iovr_convcld == iovr_exp .or. iovr_convcld == iovr_exprand) then call get_alpha_exper(nCol, nLev, iovr_convcld, iovr_exprand, deltaZc*0.001, de_lgth, cld_cnv_frac, cnv_cloud_overlap_param) else - de_lgth(:) = 0. cnv_cloud_overlap_param(:,:) = 0. endif endif diff --git a/physics/GFS_rrtmgp_cloud_overlap.meta b/physics/GFS_rrtmgp_cloud_overlap.meta index f7d12bed5..cf6a05217 100644 --- a/physics/GFS_rrtmgp_cloud_overlap.meta +++ b/physics/GFS_rrtmgp_cloud_overlap.meta @@ -210,8 +210,8 @@ kind = kind_phys intent = in [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical diff --git a/physics/GFS_rrtmgp_lw_post.F90 b/physics/GFS_rrtmgp_lw_post.F90 deleted file mode 100644 index afd56dcf1..000000000 --- a/physics/GFS_rrtmgp_lw_post.F90 +++ /dev/null @@ -1,188 +0,0 @@ -!> \file GFS_rrtmgp_lw_post.F90 -!! -!> \defgroup GFS_rrtmgp_lw_post GFS_rrtmgp_lw_post.F90 -!! -!! \brief RRTMGP Longwave post-processing routine. -!! -module GFS_rrtmgp_lw_post - use machine, only: kind_phys - use module_radlw_parameters, only: topflw_type, sfcflw_type - use mo_heating_rates, only: compute_heating_rate - use radiation_tools, only: check_error_msg - implicit none - - public GFS_rrtmgp_lw_post_run - -contains - -!>\defgroup gfs_rrtmgp_lw_post_mod GFS RRTMGP-LW Post Module -!> \section arg_table_GFS_rrtmgp_lw_post_run -!! \htmlinclude GFS_rrtmgp_lw_post.html -!! -!! \ingroup GFS_rrtmgp_lw_post -!! -!! \brief The all-sky longwave radiation tendency is computed, the clear-sky tendency is computed -!! if requested. -!! -!! RRTMGP surface and TOA fluxes are copied to fields that persist between radiation/physics -!! calls. -!! -!! (optional) Save additional diagnostics. -!! -!! \section GFS_rrtmgp_lw_post_run - ! ######################################################################################## - subroutine GFS_rrtmgp_lw_post_run (nCol, nLev, lslwr, do_lw_clrsky_hr, save_diag, fhlwr, & - p_lev, t_lay, tsfa, fluxlwUP_allsky, fluxlwDOWN_allsky, fluxlwUP_clrsky, iSFC, iTOA,& - fluxlwDOWN_clrsky, raddt, cldsa, mtopa, mbota, cld_frac, cldtaulw, fluxr, sfcdlw, & - sfculw, sfcflw, tsflw, htrlw, htrlwu, topflw, htrlwc, errmsg, errflg) - - ! Inputs - integer, intent(in) :: & - nCol, & ! Horizontal loop extent - nLev, & ! Number of vertical layers - iSFC, & ! Vertical index for surface level - iTOA ! Vertical index for TOA level - logical, intent(in) :: & - lslwr, & ! Logical flags for lw radiation calls - do_lw_clrsky_hr, & ! Output clear-sky SW heating-rate? - save_diag ! Output radiation diagnostics? - real(kind_phys), intent(in) :: & - fhlwr ! Frequency for SW radiation - real(kind_phys), dimension(nCol), intent(in) :: & - tsfa ! Lowest model layer air temperature for radiation (K) - real(kind_phys), dimension(nCol, nLev), intent(in) :: & - t_lay ! Temperature @ model layer centers (K) - real(kind_phys), dimension(nCol, nLev+1), intent(in) :: & - p_lev, & ! Pressure @ model layer-interfaces (Pa) - fluxlwUP_allsky, & ! RRTMGP longwave all-sky flux (W/m2) - fluxlwDOWN_allsky, & ! RRTMGP longwave all-sky flux (W/m2) - fluxlwUP_clrsky, & ! RRTMGP longwave clear-sky flux (W/m2) - fluxlwDOWN_clrsky ! RRTMGP longwave clear-sky flux (W/m2) - real(kind_phys), intent(in) :: & - raddt ! Radiation time step - real(kind_phys), dimension(nCol,5), intent(in) :: & - cldsa ! Fraction of clouds for low, middle, high, total and BL - integer, dimension(nCol,3), intent(in) ::& - mbota, & ! vertical indices for low, middle and high cloud tops - mtopa ! vertical indices for low, middle and high cloud bases - real(kind_phys), dimension(nCol,nLev), intent(in) :: & - cld_frac, & ! Total cloud fraction in each layer - cldtaulw ! approx 10.mu band layer cloud optical depth - - real(kind=kind_phys), dimension(:,:), intent(inout) :: fluxr - - ! Outputs (mandatory) - real(kind_phys), dimension(nCol), intent(inout) :: & - sfcdlw, & ! Total sky sfc downward lw flux (W/m2) - sfculw, & ! Total sky sfc upward lw flux (W/m2) - tsflw ! surface air temp during lw calculation (K) - type(sfcflw_type), dimension(nCol), intent(inout) :: & - sfcflw ! LW radiation fluxes at sfc - real(kind_phys), dimension(nCol,nLev), intent(inout) :: & - htrlw, & ! LW all-sky heating rate - htrlwu ! Heating-rate updated in-between radiation calls. - type(topflw_type), dimension(nCol), intent(out) :: & - topflw ! lw_fluxes_top_atmosphere - character(len=*), intent(out) :: & - errmsg - integer, intent(out) :: & - errflg - - ! Outputs (optional) - real(kind_phys),dimension(nCol, nLev),intent(inout),optional :: & - htrlwc ! Longwave clear-sky heating-rate (K/sec) - - ! Local variables - integer :: i, j, k, itop, ibtc - real(kind_phys) :: tem0d, tem1, tem2 - real(kind_phys),dimension(nCol,nLev) :: hlwc - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. lslwr) return - ! ####################################################################################### - ! Compute LW heating-rates. - ! ####################################################################################### - ! Clear-sky heating-rate (optional) - if (do_lw_clrsky_hr) then - call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & - fluxlwUP_clrsky, & ! IN - RRTMGP upward longwave clear-sky flux profiles (W/m2) - fluxlwDOWN_clrsky, & ! IN - RRTMGP downward longwave clear-sky flux profiles (W/m2) - p_lev, & ! IN - Pressure @ layer-interfaces (Pa) - htrlwc)) ! OUT - Longwave clear-sky heating rate (K/sec) - endif - - ! All-sky heating-rate (mandatory) - call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & - fluxlwUP_allsky, & ! IN - RRTMGP upward longwave all-sky flux profiles (W/m2) - fluxlwDOWN_allsky, & ! IN - RRTMGP downward longwave all-sky flux profiles (W/m2) - p_lev, & ! IN - Pressure @ layer-interfaces (Pa) - htrlw)) ! OUT - Longwave all-sky heating rate (K/sec) - - ! ####################################################################################### - ! Save LW outputs. - ! (Copy fluxes from RRTMGP types into model radiation types.) - ! ####################################################################################### - ! TOA fluxes - topflw(:)%upfxc = fluxlwUP_allsky(:,iTOA) - topflw(:)%upfx0 = fluxlwUP_clrsky(:,iTOA) - - ! Surface fluxes - sfcflw(:)%upfxc = fluxlwUP_allsky(:,iSFC) - sfcflw(:)%upfx0 = fluxlwUP_clrsky(:,iSFC) - sfcflw(:)%dnfxc = fluxlwDOWN_allsky(:,iSFC) - sfcflw(:)%dnfx0 = fluxlwDOWN_clrsky(:,iSFC) - - ! Save surface air temp for diurnal adjustment at model t-steps - tsflw (:) = tsfa(:) - - ! Radiation fluxes for other physics processes - sfcdlw(:) = sfcflw(:)%dnfxc - sfculw(:) = sfcflw(:)%upfxc - - ! Heating-rate at radiation timestep, used for adjustment between radiation calls. - htrlwu = htrlw - - ! ####################################################################################### - ! Save LW diagnostics - ! - For time averaged output quantities (including total-sky and clear-sky SW and LW - ! fluxes at TOA and surface; conventional 3-domain cloud amount, cloud top and base - ! pressure, and cloud top temperature; aerosols AOD, etc.), store computed results in - ! corresponding slots of array fluxr with appropriate time weights. - ! - Collect the fluxr data for wrtsfc - ! ####################################################################################### - if (save_diag) then - do i=1,nCol - ! LW all-sky fluxes - fluxr(i,1 ) = fluxr(i,1 ) + fhlwr * fluxlwUP_allsky( i,iTOA) ! total sky top lw up - fluxr(i,19) = fluxr(i,19) + fhlwr * fluxlwDOWN_allsky(i,iSFC) ! total sky sfc lw dn - fluxr(i,20) = fluxr(i,20) + fhlwr * fluxlwUP_allsky( i,iSFC) ! total sky sfc lw up - ! LW clear-sky fluxes - fluxr(i,28) = fluxr(i,28) + fhlwr * fluxlwUP_clrsky( i,iTOA) ! clear sky top lw up - fluxr(i,30) = fluxr(i,30) + fhlwr * fluxlwDOWN_clrsky(i,iSFC) ! clear sky sfc lw dn - fluxr(i,33) = fluxr(i,33) + fhlwr * fluxlwUP_clrsky( i,iSFC) ! clear sky sfc lw up - enddo - - ! Save cld frac,toplyr,botlyr and top temp, note that the order of h,m,l cloud is reversed for - ! the fluxr output. save interface pressure (pa) of top/bot - do j = 1, 3 - do i = 1, nCol - tem0d = raddt * cldsa(i,j) - itop = mtopa(i,j) - ibtc = mbota(i,j) - - ! Add optical depth and emissivity output - tem2 = 0. - do k=ibtc,itop - tem2 = tem2 + cldtaulw(i,k) ! approx 10. mu channel - enddo - fluxr(i,46-j) = fluxr(i,46-j) + tem0d * (1.0-exp(-tem2)) - enddo - enddo - endif - - end subroutine GFS_rrtmgp_lw_post_run - -end module GFS_rrtmgp_lw_post diff --git a/physics/GFS_rrtmgp_lw_post.meta b/physics/GFS_rrtmgp_lw_post.meta deleted file mode 100644 index d458b25f3..000000000 --- a/physics/GFS_rrtmgp_lw_post.meta +++ /dev/null @@ -1,253 +0,0 @@ -[ccpp-table-properties] - name = GFS_rrtmgp_lw_post - type = scheme - dependencies = iounitdef.f,machine.F,radiation_aerosols.f,radlw_param.f,rte-rrtmgp/extensions/mo_fluxes_byband.F90,radiation_tools.F90,rte-rrtmgp/rte/mo_fluxes.F90,rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90,rte-rrtmgp/extensions/mo_heating_rates.F90 - -######################################################################## -[ccpp-arg-table] - name = GFS_rrtmgp_lw_post_run - type = scheme -[nCol] - standard_name = horizontal_loop_extent - long_name = horizontal loop extent - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[iSFC] - standard_name = vertical_index_for_surface_in_RRTMGP - long_name = index for surface layer in RRTMGP - units = flag - dimensions = () - type = integer - intent = in -[iTOA] - standard_name = vertical_index_for_TOA_in_RRTMGP - long_name = index for TOA layer in RRTMGP - units = flag - dimensions = () - type = integer - intent = in -[lslwr] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[do_lw_clrsky_hr] - standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep_assuming_clear_sky - long_name = flag to output lw heating rate - units = flag - dimensions = () - type = logical - intent = in -[save_diag] - standard_name = flag_for_diagnostics - long_name = logical flag for storing diagnostics - units = flag - dimensions = () - type = logical - intent = in -[fhlwr] - standard_name = period_of_longwave_radiation_calls - long_name = frequency for longwave radiation - units = s - dimensions = () - type = real - kind = kind_phys - intent = in -[tsfa] - standard_name = surface_air_temperature_for_radiation - long_name = lowest model layer air temperature for radiation - units = K - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature at vertical layer for radiation calculation - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure level - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[fluxlwUP_allsky] - standard_name = RRTMGP_lw_flux_profile_upward_allsky - long_name = RRTMGP upward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[fluxlwDOWN_allsky] - standard_name = RRTMGP_lw_flux_profile_downward_allsky - long_name = RRTMGP downward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[fluxlwUP_clrsky] - standard_name = RRTMGP_lw_flux_profile_upward_clrsky - long_name = RRTMGP upward longwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[fluxlwDOWN_clrsky] - standard_name = RRTMGP_lw_flux_profile_downward_clrsky - long_name = RRTMGP downward longwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[raddt] - standard_name = time_step_for_radiation - long_name = radiation time step - units = s - dimensions = () - type = real - kind = kind_phys - intent = in -[cldsa] - standard_name = cloud_area_fraction_for_radiation - long_name = fraction of clouds for low, middle, high, total and BL - units = frac - dimensions = (horizontal_loop_extent,5) - type = real - kind = kind_phys - intent = in -[mtopa] - standard_name = model_layer_number_at_cloud_top - long_name = vertical indices for low, middle and high cloud tops - units = index - dimensions = (horizontal_loop_extent,3) - type = integer - intent = in -[mbota] - standard_name = model_layer_number_at_cloud_base - long_name = vertical indices for low, middle and high cloud bases - units = index - dimensions = (horizontal_loop_extent,3) - type = integer - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cldtaulw] - standard_name = cloud_optical_depth_layers_at_10mu_band - long_name = approx 10mu band layer cloud optical depth - units = none - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[fluxr] - standard_name = cumulative_radiation_diagnostic - long_name = time-accumulated 2D radiation-related diagnostic fields - units = mixed - dimensions = (horizontal_loop_extent,number_of_diagnostics_variables_for_radiation) - type = real - kind = kind_phys - intent = inout -[sfcdlw] - standard_name = surface_downwelling_longwave_flux_on_radiation_timestep - long_name = total sky sfc downward lw flux - units = W m-2 - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = inout -[sfculw] - standard_name = surface_upwelling_longwave_flux_on_radiation_timestep - long_name = total sky sfc upward lw flux - units = W m-2 - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = inout -[sfcflw] - standard_name = surface_lw_fluxes_assuming_total_and_clear_sky_on_radiation_timestep - long_name = lw radiation fluxes at sfc - units = W m-2 - dimensions = (horizontal_loop_extent) - type = sfcflw_type - intent = inout -[tsflw] - standard_name = air_temperature_at_surface_adjacent_layer_on_radiation_timestep - long_name = surface air temp during lw calculation - units = K - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = inout -[htrlw] - standard_name = tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep - long_name = total sky lw heating rate - units = K s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[htrlwu] - standard_name = updated_tendency_of_air_temperature_due_to_longwave_heating_on_physics_timestep - long_name = total sky longwave heating rate on physics time step - units = K s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[topflw] - standard_name = lw_fluxes_top_atmosphere - long_name = lw radiation fluxes at top - units = W m-2 - dimensions = (horizontal_loop_extent) - type = topflw_type - intent = out -[htrlwc] - standard_name = tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_timestep - long_name = longwave clear sky heating rate - units = K s-1 - dimensions = (horizontal_loop_extent,adjusted_vertical_layer_dimension_for_radiation) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/GFS_rrtmgp_post.F90 b/physics/GFS_rrtmgp_post.F90 new file mode 100644 index 000000000..22fe2fc21 --- /dev/null +++ b/physics/GFS_rrtmgp_post.F90 @@ -0,0 +1,394 @@ +!> \file GFS_rrtmgp_post.F90 +!! +!> \defgroup GFS_rrtmgp_post GFS_rrtmgp_post.F90 +!! +!! \brief RRTMGP post-processing routine. +!! +module GFS_rrtmgp_post + use machine, only: kind_phys + use module_radlw_parameters, only: topflw_type, sfcflw_type + use module_radsw_parameters, only: topfsw_type, sfcfsw_type, cmpfsw_type + use mo_heating_rates, only: compute_heating_rate + use radiation_tools, only: check_error_msg + implicit none + + public GFS_rrtmgp_post_run + +contains + ! ######################################################################################## +!>\defgroup gfs_rrtmgp_post_mod GFS RRTMGP Post Module +!> \section arg_table_GFS_rrtmgp_post_run +!! \htmlinclude GFS_rrtmgp_post.html +!! +!! \ingroup GFS_rrtmgp_post +!! +!! \brief The all-sky radiation tendency is computed, the clear-sky tendency is computed +!! if requested. +!! +!! RRTMGP surface and TOA fluxes are copied to fields that persist between radiation/physics +!! calls. +!! +!! (optional) Save additional diagnostics. +!! +!! \section GFS_rrtmgp_post_run + ! ######################################################################################## + subroutine GFS_rrtmgp_post_run (nCol, nLev, nDay, iSFC, iTOA, idxday, doLWrad, doSWrad, & + do_lw_clrsky_hr, do_sw_clrsky_hr, save_diag, fhlwr, fhswr, sfc_alb_nir_dir, & + sfc_alb_nir_dif, sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, p_lev, tsfa, coszen, coszdg, & + fluxlwDOWN_clrsky, fluxlwUP_allsky, fluxlwDOWN_allsky, fluxlwUP_clrsky, & + fluxswDOWN_clrsky, fluxswUP_allsky, fluxswDOWN_allsky, fluxswUP_clrsky, & + raddt, aerodp, cldsa, mtopa, mbota, cld_frac, cldtaulw, cldtausw, scmpsw, fluxr, & + sfcdlw, sfculw, sfcflw, tsflw, htrlw, htrlwu, topflw, nirbmdi, nirdfdi, visbmdi, & + visdfdi, nirbmui, nirdfui, visbmui, visdfui, sfcnsw, sfcdsw, htrsw, sfcfsw, topfsw, & + htrswc, htrlwc, errmsg, errflg) + + ! Inputs + integer, intent(in) :: & + nCol, & ! Horizontal loop extent + nLev, & ! Number of vertical layers + nDay, & ! Number of daylit columns + iSFC, & ! Vertical index for surface level + iTOA ! Vertical index for TOA level + integer, intent(in), dimension(:) :: & + idxday ! Index array for daytime points + integer, intent(in), dimension(:,:) :: & + mbota, & ! Vertical indices for low, middle and high cloud tops + mtopa ! ertical indices for low, middle and high cloud bases + logical, intent(in) :: & + doLWrad, & ! Logical flags for lw radiation calls + doSWrad, & ! Logical flags for sw radiation calls + do_lw_clrsky_hr, & ! Output clear-sky LW heating-rate? + do_sw_clrsky_hr, & ! Output clear-sky SW heating-rate? + save_diag ! Output radiation diagnostics? + real(kind_phys), intent(in) :: & + fhlwr, & ! Frequency for LW radiation calls + fhswr ! Frequency for SW radiation calls + real(kind_phys), dimension(:), intent(in) :: & + tsfa, & ! Lowest model layer air temperature for radiation (K) + coszen, & ! Cosine(SZA) + coszdg, & ! Cosine(SZA), daytime + sfc_alb_nir_dir, & ! Surface albedo (direct) + sfc_alb_nir_dif, & ! Surface albedo (diffuse) + sfc_alb_uvvis_dir, & ! Surface albedo (direct) + sfc_alb_uvvis_dif ! Surface albedo (diffuse) + real(kind_phys), dimension(:,:), intent(in) :: & + p_lev, & ! Pressure @ model layer-interfaces (Pa) + fluxlwUP_allsky, & ! RRTMGP longwave all-sky flux (W/m2) + fluxlwDOWN_allsky, & ! RRTMGP longwave all-sky flux (W/m2) + fluxlwUP_clrsky, & ! RRTMGP longwave clear-sky flux (W/m2) + fluxlwDOWN_clrsky, & ! RRTMGP longwave clear-sky flux (W/m2) + fluxswUP_allsky, & ! RRTMGP shortwave all-sky flux (W/m2) + fluxswDOWN_allsky, & ! RRTMGP shortwave all-sky flux (W/m2) + fluxswUP_clrsky, & ! RRTMGP shortwave clear-sky flux (W/m2) + fluxswDOWN_clrsky ! RRTMGP shortwave clear-sky flux (W/m2) + real(kind_phys), intent(in) :: & + raddt ! Radiation time step + real(kind_phys), dimension(:,:), intent(in) :: & + aerodp, & ! Vertical integrated optical depth for various aerosol species + cldsa, & ! Fraction of clouds for low, middle, high, total and BL + cld_frac, & ! Total cloud fraction in each layer + cldtaulw, & ! approx 10.mu band layer cloud optical depth + cldtausw ! approx .55mu band layer cloud optical depth + type(cmpfsw_type), dimension(:), intent(in) :: & + scmpsw ! 2D surface fluxes, components: + ! uvbfc - total sky downward uv-b flux at (W/m2) + ! uvbf0 - clear sky downward uv-b flux at (W/m2) + ! nirbm - downward nir direct beam flux (W/m2) + ! nirdf - downward nir diffused flux (W/m2) + ! visbm - downward uv+vis direct beam flux (W/m2) + ! visdf - downward uv+vis diffused flux (W/m2) + + + real(kind=kind_phys), dimension(:,:), intent(inout) :: fluxr + + ! Outputs (mandatory) + real(kind_phys), dimension(:), intent(inout) :: & + tsflw, & ! LW sfc air temp during calculation (K) + sfcdlw, & ! LW sfc all-sky downward flux (W/m2) + sfculw, & ! LW sfc all-sky upward flux (W/m2) + nirbmdi, & ! SW sfc nir beam downward flux (W/m2) + nirdfdi, & ! SW sfc nir diff downward flux (W/m2) + visbmdi, & ! SW sfc uv+vis beam downward flux (W/m2) + visdfdi, & ! SW sfc uv+vis diff downward flux (W/m2) + nirbmui, & ! SW sfc nir beam upward flux (W/m2) + nirdfui, & ! SW sfc nir diff upward flux (W/m2) + visbmui, & ! SW sfc uv+vis beam upward flux (W/m2) + visdfui, & ! SW sfc uv+vis diff upward flux (W/m2) + sfcnsw, & ! SW sfc all-sky net flux (W/m2) flux into ground + sfcdsw ! SW sfc all-sky downward flux (W/m2) + real(kind_phys), dimension(:,:), intent(inout) :: & + htrlw, & ! LW all-sky heating rate (K/s) + htrsw, & ! SW all-sky heating rate (K/s) + htrlwu ! LW all-sky heating-rate updated in-between radiation calls. + type(sfcflw_type), dimension(:), intent(inout) :: & + sfcflw ! LW radiation fluxes at sfc + type(sfcfsw_type), dimension(:), intent(inout) :: & + sfcfsw ! SW radiation fluxes at sfc + type(topfsw_type), dimension(:), intent(inout) :: & + topfsw ! SW fluxes at top atmosphere + type(topflw_type), dimension(:), intent(inout) :: & + topflw ! LW fluxes at top atmosphere + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error code + + ! Outputs (optional) + real(kind_phys),dimension(:,:),intent(inout),optional :: & + htrlwc, & ! LW clear-sky heating-rate (K/s) + htrswc ! SW clear-sky heating rate (K/s) + + ! Local variables + integer :: i, j, k, itop, ibtc + real(kind_phys) :: tem0d, tem1, tem2 + real(kind_phys), dimension(nDay, nLev) :: thetaTendClrSky, thetaTendAllSky + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + if (.not. (doLWrad .or. doSWrad)) return + + if (doLWRad) then + ! ####################################################################################### + ! Compute LW heating-rates. + ! ####################################################################################### + + ! Clear-sky heating-rate (optional) + if (do_lw_clrsky_hr) then + call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & + fluxlwUP_clrsky, & ! IN - RRTMGP upward longwave clear-sky flux profiles (W/m2) + fluxlwDOWN_clrsky, & ! IN - RRTMGP downward longwave clear-sky flux profiles (W/m2) + p_lev, & ! IN - Pressure @ layer-interfaces (Pa) + htrlwc)) ! OUT - Longwave clear-sky heating rate (K/sec) + endif + + ! All-sky heating-rate (mandatory) + call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & + fluxlwUP_allsky, & ! IN - RRTMGP upward longwave all-sky flux profiles (W/m2) + fluxlwDOWN_allsky, & ! IN - RRTMGP downward longwave all-sky flux profiles (W/m2) + p_lev, & ! IN - Pressure @ layer-interfaces (Pa) + htrlw)) ! OUT - Longwave all-sky heating rate (K/sec) + + ! ####################################################################################### + ! Save LW outputs. + ! (Copy fluxes from RRTMGP types into model radiation types.) + ! ####################################################################################### + ! TOA fluxes + + topflw(:)%upfxc = fluxlwUP_allsky(:,iTOA) + topflw(:)%upfx0 = fluxlwUP_clrsky(:,iTOA) + + ! Surface fluxes + sfcflw(:)%upfxc = fluxlwUP_allsky(:,iSFC) + sfcflw(:)%upfx0 = fluxlwUP_clrsky(:,iSFC) + sfcflw(:)%dnfxc = fluxlwDOWN_allsky(:,iSFC) + sfcflw(:)%dnfx0 = fluxlwDOWN_clrsky(:,iSFC) + + ! Save surface air temp for diurnal adjustment at model t-steps + tsflw (:) = tsfa(:) + + ! Radiation fluxes for other physics processes + sfcdlw(:) = sfcflw(:)%dnfxc + sfculw(:) = sfcflw(:)%upfxc + + ! Heating-rate at radiation timestep, used for adjustment between radiation calls. + htrlwu = htrlw + + ! ####################################################################################### + ! Save LW diagnostics + ! - For time averaged output quantities (including total-sky and clear-sky SW and LW + ! fluxes at TOA and surface; conventional 3-domain cloud amount, cloud top and base + ! pressure, and cloud top temperature; aerosols AOD, etc.), store computed results in + ! corresponding slots of array fluxr with appropriate time weights. + ! - Collect the fluxr data for wrtsfc + ! ####################################################################################### + if (save_diag) then + do i=1,nCol + ! LW all-sky fluxes + fluxr(i,1 ) = fluxr(i,1 ) + fhlwr * fluxlwUP_allsky( i,iTOA) ! total sky top lw up + fluxr(i,19) = fluxr(i,19) + fhlwr * fluxlwDOWN_allsky(i,iSFC) ! total sky sfc lw dn + fluxr(i,20) = fluxr(i,20) + fhlwr * fluxlwUP_allsky( i,iSFC) ! total sky sfc lw up + ! LW clear-sky fluxes + fluxr(i,28) = fluxr(i,28) + fhlwr * fluxlwUP_clrsky( i,iTOA) ! clear sky top lw up + fluxr(i,30) = fluxr(i,30) + fhlwr * fluxlwDOWN_clrsky(i,iSFC) ! clear sky sfc lw dn + fluxr(i,33) = fluxr(i,33) + fhlwr * fluxlwUP_clrsky( i,iSFC) ! clear sky sfc lw up + enddo + + ! Save cld frac,toplyr,botlyr and top temp, note that the order of h,m,l cloud is reversed for + ! the fluxr output. save interface pressure (pa) of top/bot + do j = 1, 3 + do i = 1, nCol + tem0d = raddt * cldsa(i,j) + itop = mtopa(i,j) + ibtc = mbota(i,j) + + ! Add optical depth and emissivity output + tem2 = 0. + do k=ibtc,itop + tem2 = tem2 + cldtaulw(i,k) ! approx 10. mu channel + enddo + fluxr(i,46-j) = fluxr(i,46-j) + tem0d * (1.0-exp(-tem2)) + enddo + enddo + endif + endif + ! ####################################################################################### + ! ####################################################################################### + ! ####################################################################################### + ! ####################################################################################### + ! ####################################################################################### + ! ####################################################################################### + if (doSWRad) then + if (nDay .gt. 0) then + ! ################################################################################# + ! Compute SW heating-rates + ! ################################################################################# + + ! Clear-sky heating-rate (optional) + if (do_sw_clrsky_hr) then + htrswc(:,:) = 0._kind_phys + call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & + fluxswUP_clrsky(idxday(1:nDay),:), & ! IN - Shortwave upward clear-sky flux profiles (W/m2) + fluxswDOWN_clrsky(idxday(1:nDay),:), & ! IN - Shortwave downward clear-sky flux profiles (W/m2) + p_lev(idxday(1:nDay),:), & ! IN - Pressure at model-interface (Pa) + thetaTendClrSky)) ! OUT - Clear-sky heating-rate (K/sec) + htrswc(idxday(1:nDay),:)=thetaTendClrSky !**NOTE** GP doesn't use radiation levels, it uses the model fields. Not sure if this is necessary + endif + + ! All-sky heating-rate (mandatory) + htrsw(:,:) = 0._kind_phys + call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & + fluxswUP_allsky(idxday(1:nDay),:), & ! IN - Shortwave upward all-sky flux profiles (W/m2) + fluxswDOWN_allsky(idxday(1:nDay),:), & ! IN - Shortwave downward all-sky flux profiles (W/m2) + p_lev(idxday(1:nDay),:), & ! IN - Pressure at model-interface (Pa) + thetaTendAllSky)) ! OUT - All-sky heating-rate (K/sec) + htrsw(idxday(1:nDay),:) = thetaTendAllSky + + ! ################################################################################# + ! Save SW outputs + ! (Copy fluxes from RRTMGP types into model radiation types.) + ! ################################################################################# + + ! TOA fluxes + topfsw(:)%upfxc = fluxswUP_allsky(:,iTOA) + topfsw(:)%upfx0 = fluxswUP_clrsky(:,iTOA) + topfsw(:)%dnfxc = fluxswDOWN_allsky(:,iTOA) + + ! Surface fluxes + sfcfsw(:)%upfxc = fluxswUP_allsky(:,iSFC) + sfcfsw(:)%upfx0 = fluxswUP_clrsky(:,iSFC) + sfcfsw(:)%dnfxc = fluxswDOWN_allsky(:,iSFC) + sfcfsw(:)%dnfx0 = fluxswDOWN_clrsky(:,iSFC) + + ! Surface down and up spectral component fluxes + ! - Save two spectral bands' surface downward and upward fluxes for output. + do i=1,nCol + nirbmdi(i) = scmpsw(i)%nirbm + nirdfdi(i) = scmpsw(i)%nirdf + visbmdi(i) = scmpsw(i)%visbm + visdfdi(i) = scmpsw(i)%visdf + nirbmui(i) = scmpsw(i)%nirbm * sfc_alb_nir_dir(i) + nirdfui(i) = scmpsw(i)%nirdf * sfc_alb_nir_dif(i) + visbmui(i) = scmpsw(i)%visbm * sfc_alb_uvvis_dir(i) + visdfui(i) = scmpsw(i)%visdf * sfc_alb_uvvis_dif(i) + enddo + else ! if_nday_block + ! ################################################################################# + ! Dark everywhere + ! ################################################################################# + htrsw(:,:) = 0.0 + sfcfsw = sfcfsw_type( 0.0, 0.0, 0.0, 0.0 ) + topfsw = topfsw_type( 0.0, 0.0, 0.0 ) + do i=1,nCol + nirbmdi(i) = 0.0 + nirdfdi(i) = 0.0 + visbmdi(i) = 0.0 + visdfdi(i) = 0.0 + nirbmui(i) = 0.0 + nirdfui(i) = 0.0 + visbmui(i) = 0.0 + visdfui(i) = 0.0 + enddo + + if (do_sw_clrsky_hr) then + htrswc(:,:) = 0 + endif + endif ! end_if_nday + + ! Radiation fluxes for other physics processes + do i=1,nCol + sfcnsw(i) = sfcfsw(i)%dnfxc - sfcfsw(i)%upfxc + sfcdsw(i) = sfcfsw(i)%dnfxc + enddo + + ! ################################################################################# + ! Save SW diagnostics + ! - For time averaged output quantities (including total-sky and clear-sky SW and LW + ! fluxes at TOA and surface; conventional 3-domain cloud amount, cloud top and base + ! pressure, and cloud top temperature; aerosols AOD, etc.), store computed results in + ! corresponding slots of array fluxr with appropriate time weights. + ! - Collect the fluxr data for wrtsfc + ! ################################################################################# + if (save_diag) then + do i=1,nCol + fluxr(i,34) = aerodp(i,1) ! total aod at 550nm + fluxr(i,35) = aerodp(i,2) ! DU aod at 550nm + fluxr(i,36) = aerodp(i,3) ! BC aod at 550nm + fluxr(i,37) = aerodp(i,4) ! OC aod at 550nm + fluxr(i,38) = aerodp(i,5) ! SU aod at 550nm + fluxr(i,39) = aerodp(i,6) ! SS aod at 550nm + if (coszen(i) > 0.) then + ! SW all-sky fluxes + tem0d = fhswr * coszdg(i) / coszen(i) + fluxr(i,2 ) = fluxr(i,2) + topfsw(i)%upfxc * tem0d ! total sky top sw up + fluxr(i,3 ) = fluxr(i,3) + sfcfsw(i)%upfxc * tem0d + fluxr(i,4 ) = fluxr(i,4) + sfcfsw(i)%dnfxc * tem0d ! total sky sfc sw dn + ! SW uv-b fluxes + fluxr(i,21) = fluxr(i,21) + scmpsw(i)%uvbfc * tem0d ! total sky uv-b sw dn + fluxr(i,22) = fluxr(i,22) + scmpsw(i)%uvbf0 * tem0d ! clear sky uv-b sw dn + ! SW TOA incoming fluxes + fluxr(i,23) = fluxr(i,23) + topfsw(i)%dnfxc * tem0d ! top sw dn + ! SW SFC flux components + fluxr(i,24) = fluxr(i,24) + visbmdi(i) * tem0d ! uv/vis beam sw dn + fluxr(i,25) = fluxr(i,25) + visdfdi(i) * tem0d ! uv/vis diff sw dn + fluxr(i,26) = fluxr(i,26) + nirbmdi(i) * tem0d ! nir beam sw dn + fluxr(i,27) = fluxr(i,27) + nirdfdi(i) * tem0d ! nir diff sw dn + ! SW clear-sky fluxes + fluxr(i,29) = fluxr(i,29) + topfsw(i)%upfx0 * tem0d + fluxr(i,31) = fluxr(i,31) + sfcfsw(i)%upfx0 * tem0d + fluxr(i,32) = fluxr(i,32) + sfcfsw(i)%dnfx0 * tem0d + endif + enddo + + ! Save total and boundary-layer clouds + do i=1,nCol + fluxr(i,17) = fluxr(i,17) + raddt * cldsa(i,4) + fluxr(i,18) = fluxr(i,18) + raddt * cldsa(i,5) + enddo + + ! Save cld frac,toplyr,botlyr and top temp, note that the order of h,m,l cloud + ! is reversed for the fluxr output. save interface pressure (pa) of top/bot + do j = 1, 3 + do i = 1, nCol + tem0d = raddt * cldsa(i,j) + itop = mtopa(i,j) + ibtc = mbota(i,j) + fluxr(i, 8-j) = fluxr(i, 8-j) + tem0d + fluxr(i,11-j) = fluxr(i,11-j) + tem0d * p_lev(i,itop) + fluxr(i,14-j) = fluxr(i,14-j) + tem0d * p_lev(i,ibtc) + fluxr(i,17-j) = fluxr(i,17-j) + tem0d * p_lev(i,itop) + + ! Add optical depth and emissivity output + tem1 = 0. + do k=ibtc,itop + tem1 = tem1 + cldtausw(i,k) ! approx .55 mu channel + enddo + fluxr(i,43-j) = fluxr(i,43-j) + tem0d * tem1 + enddo + enddo + endif + endif + + end subroutine GFS_rrtmgp_post_run +end module GFS_rrtmgp_post diff --git a/physics/GFS_rrtmgp_sw_post.meta b/physics/GFS_rrtmgp_post.meta similarity index 71% rename from physics/GFS_rrtmgp_sw_post.meta rename to physics/GFS_rrtmgp_post.meta index 7da3b10b0..e4bc3e5dc 100644 --- a/physics/GFS_rrtmgp_sw_post.meta +++ b/physics/GFS_rrtmgp_post.meta @@ -1,14 +1,13 @@ [ccpp-table-properties] - name = GFS_rrtmgp_sw_post + name = GFS_rrtmgp_post type = scheme - dependencies = iounitdef.f,machine.F,radiation_aerosols.f,radsw_param.f,rte-rrtmgp/extensions/mo_fluxes_byband.F90 - dependencies = rte-rrtmgp/rte/mo_fluxes.F90,rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90,rte-rrtmgp/extensions/mo_heating_rates.F90,radiation_tools.F90 + dependencies = iounitdef.f,machine.F,radiation_aerosols.f,radlw_param.f,radiation_tools.F90,rte-rrtmgp/extensions/mo_heating_rates.F90 ######################################################################## [ccpp-arg-table] - name = GFS_rrtmgp_sw_post_run + name = GFS_rrtmgp_post_run type = scheme -[ncol] +[nCol] standard_name = horizontal_loop_extent long_name = horizontal loop extent units = count @@ -50,7 +49,7 @@ dimensions = (horizontal_loop_extent) type = integer intent = in -[lsswr] +[doSWrad] standard_name = flag_for_calling_shortwave_radiation long_name = logical flags for sw radiation calls units = flag @@ -64,6 +63,20 @@ dimensions = () type = logical intent = in +[doLWrad] + standard_name = flag_for_calling_longwave_radiation + long_name = logical flags for lw radiation calls + units = flag + dimensions = () + type = logical + intent = in +[do_lw_clrsky_hr] + standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep_assuming_clear_sky + long_name = flag to output lw heating rate + units = flag + dimensions = () + type = logical + intent = in [save_diag] standard_name = flag_for_diagnostics long_name = logical flag for storing diagnostics @@ -71,6 +84,14 @@ dimensions = () type = logical intent = in +[fhlwr] + standard_name = period_of_longwave_radiation_calls + long_name = frequency for longwave radiation + units = s + dimensions = () + type = real + kind = kind_phys + intent = in [fhswr] standard_name = period_of_shortwave_radiation_calls long_name = frequency for shortwave radiation @@ -95,22 +116,6 @@ type = real kind = kind_phys intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature at vertical layer for radiation calculation - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure level - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in [sfc_alb_nir_dir] standard_name = surface_albedo_due_to_near_IR_direct long_name = surface albedo due to near IR direct beam @@ -143,6 +148,54 @@ type = real kind = kind_phys intent = in +[tsfa] + standard_name = surface_air_temperature_for_radiation + long_name = lowest model layer air temperature for radiation + units = K + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[p_lev] + standard_name = air_pressure_at_interface_for_RRTMGP + long_name = air pressure level + units = Pa + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[fluxlwUP_allsky] + standard_name = RRTMGP_lw_flux_profile_upward_allsky + long_name = RRTMGP upward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[fluxlwDOWN_allsky] + standard_name = RRTMGP_lw_flux_profile_downward_allsky + long_name = RRTMGP downward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[fluxlwUP_clrsky] + standard_name = RRTMGP_lw_flux_profile_upward_clrsky + long_name = RRTMGP upward longwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[fluxlwDOWN_clrsky] + standard_name = RRTMGP_lw_flux_profile_downward_clrsky + long_name = RRTMGP downward longwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in [fluxswUP_allsky] standard_name = RRTMGP_sw_flux_profile_upward_allsky long_name = RRTMGP upward shortwave all-sky flux profile @@ -199,16 +252,16 @@ type = real kind = kind_phys intent = in -[mbota] - standard_name = model_layer_number_at_cloud_base - long_name = vertical indices for low, middle and high cloud bases +[mtopa] + standard_name = model_layer_number_at_cloud_top + long_name = vertical indices for low, middle and high cloud tops units = index dimensions = (horizontal_loop_extent,3) type = integer intent = in -[mtopa] - standard_name = model_layer_number_at_cloud_top - long_name = vertical indices for low, middle and high cloud tops +[mbota] + standard_name = model_layer_number_at_cloud_base + long_name = vertical indices for low, middle and high cloud bases units = index dimensions = (horizontal_loop_extent,3) type = integer @@ -221,6 +274,14 @@ type = real kind = kind_phys intent = in +[cldtaulw] + standard_name = cloud_optical_depth_layers_at_10mu_band + long_name = approx 10mu band layer cloud optical depth + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [cldtausw] standard_name = cloud_optical_depth_layers_at_0p55mu_band long_name = approx .55mu band layer cloud optical depth @@ -229,6 +290,13 @@ type = real kind = kind_phys intent = in +[scmpsw] + standard_name = components_of_surface_downward_shortwave_fluxes + long_name = derived type for special components of surface downward shortwave fluxes + units = W m-2 + dimensions = (horizontal_loop_extent) + type = cmpfsw_type + intent = in [fluxr] standard_name = cumulative_radiation_diagnostic long_name = time-accumulated 2D radiation-related diagnostic fields @@ -237,6 +305,60 @@ type = real kind = kind_phys intent = inout +[sfcdlw] + standard_name = surface_downwelling_longwave_flux_on_radiation_timestep + long_name = total sky sfc downward lw flux + units = W m-2 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[sfculw] + standard_name = surface_upwelling_longwave_flux_on_radiation_timestep + long_name = total sky sfc upward lw flux + units = W m-2 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[sfcflw] + standard_name = surface_lw_fluxes_assuming_total_and_clear_sky_on_radiation_timestep + long_name = lw radiation fluxes at sfc + units = W m-2 + dimensions = (horizontal_loop_extent) + type = sfcflw_type + intent = inout +[tsflw] + standard_name = air_temperature_at_surface_adjacent_layer_on_radiation_timestep + long_name = surface air temp during lw calculation + units = K + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[htrlw] + standard_name = tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep + long_name = total sky lw heating rate + units = K s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[htrlwu] + standard_name = updated_tendency_of_air_temperature_due_to_longwave_heating_on_physics_timestep + long_name = total sky longwave heating rate on physics time step + units = K s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[topflw] + standard_name = lw_fluxes_top_atmosphere + long_name = lw radiation fluxes at top + units = W m-2 + dimensions = (horizontal_loop_extent) + type = topflw_type + intent = inout [nirbmdi] standard_name = surface_downwelling_direct_nir_shortwave_flux_on_radiation_timestep long_name = sfc nir beam sw downward flux @@ -347,12 +469,13 @@ type = real kind = kind_phys intent = inout -[scmpsw] - standard_name = components_of_surface_downward_shortwave_fluxes - long_name = derived type for special components of surface downward shortwave fluxes - units = W m-2 - dimensions = (horizontal_loop_extent) - type = cmpfsw_type +[htrlwc] + standard_name = tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_timestep + long_name = longwave clear sky heating rate + units = K s-1 + dimensions = (horizontal_loop_extent,adjusted_vertical_layer_dimension_for_radiation) + type = real + kind = kind_phys intent = inout [errmsg] standard_name = ccpp_error_message diff --git a/physics/GFS_rrtmgp_pre.F90 b/physics/GFS_rrtmgp_pre.F90 index 755b977b3..009eb8c38 100644 --- a/physics/GFS_rrtmgp_pre.F90 +++ b/physics/GFS_rrtmgp_pre.F90 @@ -5,19 +5,15 @@ !! \brief This module contains code to prepare model fields for use by the RRTMGP !! radiation scheme. module GFS_rrtmgp_pre - use machine, only: & - kind_phys !< Working type - use funcphys, only: & - fpvs !< Function ot compute sat. vapor pressure over liq. - use module_radiation_astronomy, only: & - coszmn - use module_radiation_gases, only: & - NF_VGAS, & !< Number of active gas species - getgases, & !< Routine to setup trace gases - getozn !< Routine to setup ozone - ! RRTMGP types - use mo_gas_concentrations, only: ty_gas_concs - use radiation_tools, only: check_error_msg,cmp_tlev + use machine, only: kind_phys + use funcphys, only: fpvs + use module_radiation_astronomy, only: coszmn + use module_radiation_gases, only: NF_VGAS, getgases, getozn + use mo_gas_concentrations, only: ty_gas_concs + use radiation_tools, only: check_error_msg,cmp_tlev + use rrtmgp_lw_gas_optics, only: lw_gas_props + + implicit none real(kind_phys), parameter :: & amd = 28.9644_kind_phys, & !< Molecular weight of dry-air (g/mol) @@ -25,6 +21,9 @@ module GFS_rrtmgp_pre amo3 = 47.9982_kind_phys, & !< Modelular weight of ozone (g/mol) amdw = amd/amw, & !< Molecular weight of dry air / water vapor amdo3 = amd/amo3 !< Molecular weight of dry air / ozone + real(kind_phys), parameter :: eps = 1.0e-6_kind_phys + real(kind_phys), parameter :: oneminus = 1.0_kind_phys - eps + real(kind_phys), parameter :: ftiny = 1.0e-12_kind_phys ! Save trace gas indices. integer :: iStr_h2o, iStr_co2, iStr_o3, iStr_n2o, iStr_ch4, iStr_o2, iStr_ccl4, & @@ -111,27 +110,26 @@ end subroutine GFS_rrtmgp_pre_init !! !! \section GFS_rrtmgp_pre_run ! ######################################################################################### - subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhswr, fhlwr, & + subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, i_o3, doSWrad, doLWrad, fhswr, fhlwr, & xlat, xlon, prsl, tgrs, prslk, prsi, qgrs, tsfc, coslat, sinlat, con_g, con_rd, & - con_eps, con_epsm1, con_fvirt, con_epsqs, solhr, minGPpres, maxGPpres, minGPtemp, & - maxGPtemp, raddt, p_lay, t_lay, p_lev, t_lev, tsfg, tsfa, qs_lay, q_lay, tv_lay, & - relhum, tracer, deltaZ, deltaZc, deltaP, active_gases_array, gas_concentrations, & - tsfc_radtime, coszen, coszdg, top_at_1, iSFC, iTOA, errmsg, errflg) + con_eps, con_epsm1, con_fvirt, con_epsqs, solhr, raddt, p_lay, t_lay, p_lev, t_lev, & + vmr_o2, vmr_h2o, vmr_o3, vmr_ch4, & + vmr_n2o, vmr_co2, tsfg, tsfa, qs_lay, q_lay, tv_lay, & + relhum, deltaZ, deltaZc, deltaP, active_gases_array, & + tsfc_radtime, coszen, coszdg, top_at_1, iSFC, iTOA, nDay, idxday, semis, & + sfc_emiss_byband, ico2, con_pi, errmsg, errflg) ! Inputs integer, intent(in) :: & + me, & ! MPI rank nCol, & ! Number of horizontal grid points nLev, & ! Number of vertical layers - nTracers, & ! Number of tracers from model. + ico2, & ! Flag for co2 radiation scheme i_o3 ! Index into tracer array for ozone logical, intent(in) :: & - lsswr, & ! Call SW radiation? - lslwr ! Call LW radiation + doSWrad, & ! Call SW radiation? + doLWrad ! Call LW radiation real(kind_phys), intent(in) :: & - minGPtemp, & ! Minimum temperature allowed in RRTMGP. - maxGPtemp, & ! Maximum ... - minGPpres, & ! Minimum pressure allowed in RRTMGP. - maxGPpres, & ! Maximum pressure allowed in RRTMGP. fhswr, & ! Frequency of SW radiation call. fhlwr ! Frequency of LW radiation call. real(kind_phys), intent(in) :: & @@ -141,13 +139,15 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw con_epsm1, & ! Physical constant: Epsilon (Rd/Rv) minus one con_fvirt, & ! Physical constant: Inverse of epsilon minus one con_epsqs, & ! Physical constant: Minimum saturation mixing-ratio (kg/kg) + con_pi, & ! Physical constant: Pi solhr ! Time in hours after 00z at the current timestep real(kind_phys), dimension(:), intent(in) :: & xlon, & ! Longitude xlat, & ! Latitude tsfc, & ! Surface skin temperature (K) coslat, & ! Cosine(latitude) - sinlat ! Sine(latitude) + sinlat, & ! Sine(latitude) + semis real(kind_phys), dimension(:,:), intent(in) :: & prsl, & ! Pressure at model-layer centers (Pa) tgrs, & ! Temperature at model-layer centers (K) @@ -163,9 +163,11 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw errmsg ! Error message integer, intent(out) :: & errflg, & ! Error flag + nDay + integer, intent(inout) :: & iSFC, & ! Vertical index for surface iTOA ! Vertical index for TOA - logical, intent(out) :: & + logical, intent(inout) :: & top_at_1 ! Vertical ordering flag real(kind_phys), intent(inout) :: & raddt ! Radiation time-step @@ -175,6 +177,8 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw tsfc_radtime, & ! Surface temperature at radiation timestep coszen, & ! Cosine of SZA coszdg ! Cosine of SZA, daytime + integer, dimension(:), intent(inout) :: & + idxday ! Indices for daylit points real(kind_phys), dimension(:,:), intent(inout) :: & p_lay, & ! Pressure at model-layer t_lay, & ! Temperature at model layer @@ -186,15 +190,12 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw deltaZc, & ! Layer thickness (m) (between layer centers) deltaP, & ! Layer thickness (Pa) p_lev, & ! Pressure at model-interface - t_lev ! Temperature at model-interface - real(kind_phys), dimension(:,:,:),intent(inout) :: & - tracer ! Array containing trace gases - type(ty_gas_concs), intent(inout) :: & - gas_concentrations ! RRTMGP DDT: gas volumne mixing ratios + sfc_emiss_byband, & ! + t_lev, & ! Temperature at model-interface + vmr_o2, vmr_h2o, vmr_o3, vmr_ch4, vmr_n2o, vmr_co2 ! Local variables integer :: i, j, iCol, iBand, iLay, iLev, iSFC_ilev - real(kind_phys),dimension(nCol,nLev) :: vmr_o3, vmr_h2o real(kind_phys) :: es, tem1, tem2, pfac real(kind_phys), dimension(nLev+1) :: hgtb real(kind_phys), dimension(nLev) :: hgtc @@ -205,8 +206,10 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! Initialize CCPP error handling variables errmsg = '' errflg = 0 - - if (.not. (lsswr .or. lslwr)) return + + nday = 0 + idxday = 0 + if (.not. (doSWrad .or. doLWrad)) return ! ####################################################################################### ! What is vertical ordering? @@ -242,27 +245,29 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! Bound temperature/pressure at layer centers. do iLay=1,nLev do iCol=1,NCOL - if (t_lay(iCol,iLay) .le. minGPtemp) then - t_lay(iCol,iLay) = minGPtemp + epsilon(minGPtemp) + if (t_lay(iCol,iLay) .le. lw_gas_props%get_temp_min()) then + t_lay(iCol,iLay) = lw_gas_props%get_temp_min() + epsilon(lw_gas_props%get_temp_min()) endif - if (p_lay(iCol,iLay) .le. minGPpres) then - p_lay(iCol,iLay) = minGPpres + epsilon(minGPpres) + if (p_lay(iCol,iLay) .le. lw_gas_props%get_press_min()) then + p_lay(iCol,iLay) = lw_gas_props%get_press_min() + epsilon(lw_gas_props%get_press_min()) endif - if (t_lay(iCol,iLay) .ge. maxGPtemp) then - t_lay(iCol,iLay) = maxGPtemp - epsilon(maxGPtemp) + if (t_lay(iCol,iLay) .ge. lw_gas_props%get_temp_max()) then + t_lay(iCol,iLay) = lw_gas_props%get_temp_max() - epsilon(lw_gas_props%get_temp_max()) endif - if (p_lay(iCol,iLay) .ge. maxGPpres) then - p_lay(iCol,iLay) = maxGPpres - epsilon(maxGPpres) + if (p_lay(iCol,iLay) .ge. lw_gas_props%get_press_max()) then + p_lay(iCol,iLay) = lw_gas_props%get_press_max() - epsilon(lw_gas_props%get_press_max()) endif enddo enddo ! Temperature at layer-interfaces - call cmp_tlev(nCol,nLev,minGPpres,p_lay,t_lay,p_lev,tsfc,t_lev) + call cmp_tlev(nCol,nLev,lw_gas_props%get_press_min(),p_lay,t_lay,p_lev,tsfc,t_lev) do iLev=1,nLev+1 do iCol=1,nCol - if (t_lev(iCol,iLev) .le. minGPtemp) t_lev(iCol,iLev) = minGPtemp + epsilon(minGPtemp) - if (t_lev(iCol,iLev) .ge. maxGPtemp) t_lev(iCol,iLev) = maxGPtemp - epsilon(maxGPtemp) + if (t_lev(iCol,iLev) .le. lw_gas_props%get_temp_min()) t_lev(iCol,iLev) = & + lw_gas_props%get_temp_min() + epsilon(lw_gas_props%get_temp_min()) + if (t_lev(iCol,iLev) .ge. lw_gas_props%get_temp_max()) t_lev(iCol,iLev) = & + lw_gas_props%get_temp_max() - epsilon(lw_gas_props%get_temp_max()) enddo enddo @@ -336,43 +341,31 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! ####################################################################################### ! Get layer ozone mass mixing ratio ! ####################################################################################### - ! First recast remaining all tracers (except sphum) forcing them all to be positive - do j = 2, nTracers - tracer(1:NCOL,:,j) = qgrs(1:NCOL,:,j) - where(tracer(:,:,j) .lt. 0.0) tracer(:,:,j) = 0._kind_phys - enddo if (i_o3 > 0) then do iLay=1,nlev do iCol=1,NCOL - o3_lay(iCol,iLay) = max( con_epsqs, tracer(iCol,iLay,i_o3) ) + o3_lay(iCol,iLay) = max( con_epsqs, qgrs(iCol,iLay,i_o3) ) enddo enddo ! OR Use climatological ozone data else - call getozn (prslk(1:NCOL,:), xlat, nCol, nLev, o3_lay) + call getozn (prslk(1:NCOL,:), xlat, nCol, nLev, top_at_1, o3_lay) endif ! ####################################################################################### ! Set gas concentrations for RRTMGP ! ####################################################################################### ! Call getgases(), to set up non-prognostic gas volume mixing ratios (gas_vmr). - call getgases (p_lev/100., xlon, xlat, nCol, nLev, gas_vmr) + call getgases (p_lev/100., xlon, xlat, nCol, nLev, ico2, top_at_1, con_pi, gas_vmr) + vmr_o2 = gas_vmr(:,:,4) + vmr_ch4 = gas_vmr(:,:,3) + vmr_n2o = gas_vmr(:,:,2) + vmr_co2 = gas_vmr(:,:,1) ! Compute volume mixing-ratios for ozone (mmr) and specific-humidity. vmr_h2o = merge((q_lay/(1-q_lay))*amdw, 0., q_lay .ne. 1.) vmr_o3 = merge(o3_lay*amdo3, 0., o3_lay .gt. 0.) - - ! Populate RRTMGP DDT w/ gas-concentrations - gas_concentrations%ncol = nCol - gas_concentrations%nlay = nLev - gas_concentrations%gas_name(:) = active_gases_array(:) - gas_concentrations%concs(istr_o2)%conc(:,:) = gas_vmr(:,:,4) - gas_concentrations%concs(istr_co2)%conc(:,:) = gas_vmr(:,:,1) - gas_concentrations%concs(istr_ch4)%conc(:,:) = gas_vmr(:,:,3) - gas_concentrations%concs(istr_n2o)%conc(:,:) = gas_vmr(:,:,2) - gas_concentrations%concs(istr_h2o)%conc(:,:) = vmr_h2o(:,:) - gas_concentrations%concs(istr_o3)%conc(:,:) = vmr_o3(:,:) ! ####################################################################################### ! Radiation time step (output) (Is this really needed?) (Used by some diagnostics) @@ -382,16 +375,38 @@ subroutine GFS_rrtmgp_pre_run(me, nCol, nLev, nTracers, i_o3, lsswr, lslwr, fhsw ! ####################################################################################### ! Setup surface ground temperature and ground/air skin temperature if required. ! ####################################################################################### + iSFC_ilev = 1 + if (top_at_1) iSFC_ilev = iSFC + 1 + tsfg(1:NCOL) = t_lev(1:NCOL,iSFC_ilev) tsfa(1:NCOL) = t_lay(1:NCOL,iSFC) ! ####################################################################################### ! Compute cosine of zenith angle (only when SW is called) ! ####################################################################################### - if (lsswr) then + if (doSWrad) then call coszmn (xlon, sinlat, coslat, solhr, nCol, me, coszen, coszdg) + ! For SW gather daylit points + nday = 0 + idxday = 0 + do iCol = 1, nCol + if (coszen(iCol) >= 0.0001) then + nday = nday + 1 + idxday(nday) = iCol + endif + enddo + else + nday = 0 + idxday = 0 endif + ! ####################################################################################### + ! Surface emissivity + ! ####################################################################################### + do iBand=1,lw_gas_props%get_nband() + sfc_emiss_byband(iBand,:) = semis + enddo + end subroutine GFS_rrtmgp_pre_run end module GFS_rrtmgp_pre diff --git a/physics/GFS_rrtmgp_pre.meta b/physics/GFS_rrtmgp_pre.meta index 88face855..abb07b825 100644 --- a/physics/GFS_rrtmgp_pre.meta +++ b/physics/GFS_rrtmgp_pre.meta @@ -2,7 +2,7 @@ name = GFS_rrtmgp_pre type = scheme dependencies = funcphys.f90,iounitdef.f,machine.F,module_bfmicrophysics.f,physcons.F90,radcons.f90,radiation_aerosols.f - dependencies = radiation_astronomy.f,radiation_clouds.f,radiation_gases.f,radiation_tools.F90,rrtmg_lw_cloud_optics.F90 + dependencies = radiation_astronomy.f,radiation_gases.f,radiation_tools.F90,rrtmg_lw_cloud_optics.F90 ######################################################################## [ccpp-arg-table] @@ -72,21 +72,14 @@ dimensions = () type = integer intent = in -[nTracers] - standard_name = number_of_tracers - long_name = number of tracers - units = count - dimensions = () - type = integer - intent = in -[lsswr] +[doSWrad] standard_name = flag_for_calling_shortwave_radiation long_name = logical flags for sw radiation calls units = flag dimensions = () type = logical intent = in -[lslwr] +[doLWrad] standard_name = flag_for_calling_longwave_radiation long_name = logical flags for lw radiation calls units = flag @@ -252,37 +245,20 @@ type = real kind = kind_phys intent = in -[minGPpres] - standard_name = minimum_pressure_in_RRTMGP - long_name = minimum pressure allowed in RRTMGP - units = Pa - dimensions = () - type = real - kind = kind_phys - intent = in -[maxGPpres] - standard_name = maximum_pressure_in_RRTMGP - long_name = maximum pressure allowed in RRTMGP - units = Pa - dimensions = () - type = real - kind = kind_phys - intent = in -[minGPtemp] - standard_name = minimum_temperature_in_RRTMGP - long_name = minimum temperature allowed in RRTMGP - units = K +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none dimensions = () type = real kind = kind_phys intent = in -[maxGPtemp] - standard_name = maximum_temperature_in_RRTMGP - long_name = maximum temperature allowed in RRTMGP - units = K +[ico2] + standard_name = control_for_co2 + long_name = prescribed global mean value (old opernl) + units = flag dimensions = () - type = real - kind = kind_phys + type = integer intent = in [raddt] standard_name = time_step_for_radiation @@ -349,26 +325,26 @@ kind = kind_phys intent = inout [top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation units = flag dimensions = () type = logical - intent = out + intent = inout [iSFC] standard_name = vertical_index_for_surface_in_RRTMGP long_name = index for surface layer in RRTMGP units = flag dimensions = () type = integer - intent = out + intent = inout [iTOA] standard_name = vertical_index_for_TOA_in_RRTMGP long_name = index for TOA layer in RRTMGP units = flag dimensions = () type = integer - intent = out + intent = inout [tsfc_radtime] standard_name = surface_skin_temperature_on_radiation_timestep long_name = surface skin temperature on radiation timestep @@ -425,11 +401,51 @@ type = real kind = kind_phys intent = inout -[tracer] - standard_name = chemical_tracers - long_name = chemical tracers - units = g g-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) +[vmr_o2] + standard_name = volume_mixing_ratio_for_o2 + long_name = molar mixing ratio of o2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[vmr_h2o] + standard_name = volume_mixing_ratio_for_h2o + long_name = molar mixing ratio of h2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[vmr_o3] + standard_name = volume_mixing_ratio_for_o3 + long_name = molar mixing ratio of o3 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[vmr_ch4] + standard_name = volume_mixing_ratio_for_ch4 + long_name = molar mixing ratio of ch4 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[vmr_n2o] + standard_name = volume_mixing_ratio_for_n2o + long_name = molar mixing ratio of n2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[vmr_co2] + standard_name = volume_mixing_ratio_for_co2 + long_name = molar mixing ratio of co2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = inout @@ -441,13 +457,6 @@ type = character kind = len=* intent = in -[gas_concentrations] - standard_name = Gas_concentrations_for_RRTMGP_suite - long_name = DDT containing gas concentrations for RRTMGP radiation scheme - units = DDT - dimensions = () - type = ty_gas_concs - intent = inout [coszdg] standard_name = cosine_of_solar_zenith_angle_on_radiation_timestep long_name = daytime mean cosz over rad call period @@ -464,6 +473,36 @@ type = real kind = kind_phys intent = inout +[semis] + standard_name = surface_longwave_emissivity + long_name = surface lw emissivity in fraction + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[sfc_emiss_byband] + standard_name = surface_emissivity_in_each_RRTMGP_LW_band + long_name = surface emissivity in each RRTMGP LW band + units = none + dimensions = (number_of_longwave_bands,horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[nday] + standard_name = daytime_points_dimension + long_name = daytime points dimension + units = count + dimensions = () + type = integer + intent = inout +[idxday] + standard_name = daytime_points + long_name = daytime points + units = index + dimensions = (horizontal_loop_extent) + type = integer + intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/GFS_rrtmgp_setup.F90 b/physics/GFS_rrtmgp_setup.F90 index 3cd8af019..76db14279 100644 --- a/physics/GFS_rrtmgp_setup.F90 +++ b/physics/GFS_rrtmgp_setup.F90 @@ -6,15 +6,12 @@ module GFS_rrtmgp_setup use module_radiation_astronomy, only : sol_init, sol_update use module_radiation_aerosols, only : aer_init, aer_update use module_radiation_gases, only : gas_init, gas_update - ! use GFS_cloud_diagnostics, only : hml_cloud_diagnostics_initialize - ! *NOTE* These parameters below are required radiation_****** modules. They are not - ! directly used by the RRTMGP routines. - use physparam, only : isolar, ictmflg, ico2flg, ioznflg, iaerflg, & - iaermdl, ivflip implicit none public GFS_rrtmgp_setup_init, GFS_rrtmgp_setup_timestep_init, GFS_rrtmgp_setup_finalize - + + private + ! Version tag and last revision date character(40), parameter :: & VTAGRAD='NCEP-RRTMGP_driver v1.0 Sep 2019 ' @@ -28,7 +25,7 @@ module GFS_rrtmgp_setup is_initialized = .false. ! Control flag for the first time of reading climatological ozone data ! (set/reset in subroutines GFS_rrtmgp_setup_init/GFS_rrtmgp_setup_timestep_init, it is used only if - ! the control parameter ioznflg=0) + ! the control parameter ntoz=0) logical :: loz1st = .true. contains @@ -40,8 +37,9 @@ module GFS_rrtmgp_setup subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, imp_physics_zhao_carr, & imp_physics_zhao_carr_pdf, imp_physics_mg, si, levr, ictm, isol, ico2, iaer, & - ntcw, num_p3d, ntoz, iovr, isubc_sw, isubc_lw, icliq_sw, crick_proof, ccnorm, & - norad_precip, idate, iflip, me, errmsg, errflg) + ntcw, ntoz, iovr, isubc_sw, isubc_lw, lalw1bd, idate, me, aeros_file, & + iaermdl, iaerflg, con_pi, con_t0c, con_c, con_boltz, con_plnk, solar_file, & + con_solr_2008, con_solr_2002, co2usr_file, co2cyc_file, ipsd0, errmsg, errflg) ! Inputs logical, intent(in) :: do_RRTMGP @@ -54,19 +52,24 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, imp_physics_zhao_carr, & ! Flag for zhao-carr scheme imp_physics_zhao_carr_pdf, & ! Flag for zhao-carr+PDF scheme imp_physics_mg ! Flag for MG scheme + real(kind_phys), intent(in) :: & + con_pi, con_t0c, con_c, con_boltz, con_plnk, con_solr_2008, con_solr_2002 real(kind_phys), dimension(:), intent(in) :: & si integer, intent(in) :: levr, ictm, isol, ico2, iaer, & - ntcw, num_p3d, ntoz, iovr, isubc_sw, isubc_lw, & - icliq_sw, iflip, me + ntcw, ntoz, iovr, isubc_sw, isubc_lw, & + me logical, intent(in) :: & - crick_proof, ccnorm, norad_precip + lalw1bd integer, intent(in), dimension(:) :: & idate + character(len=26),intent(in) :: aeros_file, solar_file, co2usr_file, co2cyc_file ! Outputs - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg + integer, intent(inout) :: ipsd0 + integer, intent(out) :: iaermdl, iaerflg ! Initialize the CCPP error handling variables errmsg = '' @@ -82,12 +85,6 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, end if ! Set radiation parameters - isolar = isol ! solar constant control flag - ictmflg = ictm ! data ic time/date control flag - ico2flg = ico2 ! co2 data source control flag - ioznflg = ntoz ! ozone data source control flag - ivflip = iflip ! vertical index direction control flag - if ( ictm==0 .or. ictm==-2 ) then iaerflg = mod(iaer, 100) ! no volcanic aerosols for clim hindcast else @@ -99,6 +96,11 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, errflg = 1 return endif + + ! Assign initial permutation seed for mcica cloud-radiation + if ( isubc_sw>0 .or. isubc_lw>0 ) then + ipsd0 = 17*idate(1)+43*idate(2)+37*idate(3)+23*idate(4) + endif if ( me == 0 ) then print *,' In rad_initialize (GFS_rrtmgp_setup_init), before calling radinit' @@ -107,39 +109,27 @@ subroutine GFS_rrtmgp_setup_init(do_RRTMGP, imp_physics, imp_physics_fer_hires, ' ictm = ',ictm, & ' isol = ',isol, & ' ico2 = ',ico2, & - ' iaer = ',iaer, & - ' ntcw = ',ntcw - print *,' np3d = ',num_p3d, & + ' iaermdl = ',iaermdl, & + ' iaerflg = ',iaerflg, & + ' ntcw = ',ntcw, & ' ntoz = ',ntoz, & ' iovr = ',iovr, & ' isubc_sw = ',isubc_sw, & ' isubc_lw = ',isubc_lw, & - ' icliq_sw = ',icliq_sw, & - ' iflip = ',iflip, & + ' ipsd0 = ',ipsd0, & ' me = ',me endif - - loz1st = (ioznflg == 0) ! first-time clim ozone data read flag + + loz1st = (ntoz == 0) ! first-time clim ozone data read flag month0 = 0 iyear0 = 0 monthd = 0 -!> -# Initialization -!! - astronomy initialization routine: -!! call module_radiation_astronomy::sol_init() -!! - aerosols initialization routine: -!! call module_radiation_aerosols::aer_init() -!! - CO2 and other gases intialization routine: -!! call module_radiation_gases::gas_init() - ! Call initialization routines.. - call sol_init ( me ) - call aer_init ( levr, me ) - call gas_init ( me ) - !call hml_cloud_diagnostics_initialize(imp_physics, imp_physics_fer_hires, & - ! imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & - ! imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, imp_physics_mg, levr, me, si,& - ! errflg) + call sol_init ( me, isol, solar_file, con_solr_2008, con_solr_2002, con_pi ) + call aer_init ( levr, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, con_t0c, & + con_c, con_boltz, con_plnk, errflg, errmsg) + call gas_init ( me, co2usr_file, co2cyc_file, ico2, ictm, ntoz, con_pi, errflg, errmsg ) if ( me == 0 ) then print *,' return from rad_initialize (GFS_rrtmgp_setup_init) - after calling radinit' @@ -156,16 +146,20 @@ end subroutine GFS_rrtmgp_setup_init !> \section arg_table_GFS_rrtmgp_setup_timestep_init !! \htmlinclude GFS_rrtmgp_setup_timestep_init.html !! - subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, me, & - slag, sdec, cdec, solcon, errmsg, errflg) + subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, doSWrad, me, & + iaermdl, aeros_file, isol, slag, sdec, cdec, solcon, con_pi, co2dat_file, & + co2gbl_file, ictm, ico2, ntoz, errmsg, errflg) ! Inputs integer, intent(in) :: idate(:) integer, intent(in) :: jdate(:) real(kind_phys), intent(in) :: deltsw real(kind_phys), intent(in) :: deltim - logical, intent(in) :: lsswr + logical, intent(in) :: doSWrad + real(kind_phys), intent(in) :: con_pi integer, intent(in) :: me + integer, intent(in) :: iaermdl,isol,ictm,ico2,ntoz + character(len=26), intent(in) :: aeros_file,co2dat_file,co2gbl_file ! Outputs real(kind_phys), intent(out) :: slag @@ -201,7 +195,7 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, ! Set up time stamp used for green house gases (** currently co2 only) ! get external data at initial condition time - if ( ictmflg==0 .or. ictmflg==-2 ) then + if ( ictm==0 .or. ictm==-2 ) then kyear = idate(1) kmon = idate(2) kday = idate(3) @@ -222,21 +216,21 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, endif ! Update solar forcing... - if (lsswr) then - if ( isolar == 0 .or. isolar == 10 ) then + if (doSWrad) then + if ( isol == 0 .or. isol == 10 ) then lsol_chg = .false. elseif ( iyear0 /= iyear ) then lsol_chg = .true. else - lsol_chg = ( isolar==4 .and. lmon_chg ) + lsol_chg = ( isol==4 .and. lmon_chg ) endif iyear0 = iyear - call sol_update(jdate, kyear, deltsw, deltim, lsol_chg, me, slag, sdec, cdec, solcon) + call sol_update(jdate, kyear, deltsw, deltim, lsol_chg, me, slag, sdec, cdec, solcon, con_pi, errmsg, errflg) endif ! Update aerosols... if ( lmon_chg ) then - call aer_update ( iyear, imon, me ) + call aer_update ( iyear, imon, me, iaermdl, aeros_file, errflg, errmsg) endif ! Update trace gases (co2 only)... @@ -246,7 +240,8 @@ subroutine GFS_rrtmgp_setup_timestep_init (idate, jdate, deltsw, deltim, lsswr, else lco2_chg = .false. endif - call gas_update (kyear, kmon, kday, khour, loz1st, lco2_chg, me ) + call gas_update (kyear, kmon, kday, khour, loz1st, lco2_chg, me, co2dat_file, & + co2gbl_file, ictm, ico2, ntoz, errflg, errmsg ) if ( loz1st ) loz1st = .false. diff --git a/physics/GFS_rrtmgp_setup.meta b/physics/GFS_rrtmgp_setup.meta index 41bf63ac8..c4f7cfaa5 100644 --- a/physics/GFS_rrtmgp_setup.meta +++ b/physics/GFS_rrtmgp_setup.meta @@ -1,8 +1,8 @@ [ccpp-table-properties] name = GFS_rrtmgp_setup type = scheme - dependencies = iounitdef.f,machine.F,module_bfmicrophysics.f,physparam.f,radiation_aerosols.f,radiation_astronomy.f - dependencies = module_mp_thompson.F90,radiation_clouds.f,radiation_gases.f + dependencies = iounitdef.f,machine.F,module_bfmicrophysics.f,radiation_aerosols.f,radiation_astronomy.f + dependencies = module_mp_thompson.F90,radiation_gases.f ######################################################################## [ccpp-arg-table] @@ -101,6 +101,30 @@ dimensions = () type = integer intent = in +[solar_file] + standard_name = solar_constant_file + long_name = external solar constant data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[con_solr_2008] + standard_name = solar_constant_2008 + long_name = solar constant Tim 2008 + units = W m-2 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_solr_2002] + standard_name = solar_constant_2002 + long_name= solar constant Liu 2002 + units = W m-2 + dimensions = () + type = real + kind = kind_phys + intent = in [ico2] standard_name = control_for_co2 long_name = prescribed global mean value (old opernl) @@ -122,13 +146,6 @@ dimensions = () type = integer intent = in -[num_p3d] - standard_name = number_of_microphysics_variables_in_xyz_dimensioned_restart_array - long_name = number of 3D arrays needed for microphysics - units = count - dimensions = () - type = integer - intent = in [ntoz] standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array long_name = tracer index for ozone mixing ratio @@ -157,31 +174,10 @@ dimensions = () type = integer intent = in -[icliq_sw] - standard_name = control_for_shortwave_radiation_liquid_clouds - long_name = sw optical property for liquid clouds - units = flag - dimensions = () - type = integer - intent = in -[crick_proof] - standard_name = flag_for_CRICK_proof_cloud_water - long_name = flag for CRICK-Proof cloud water - units = flag - dimensions = () - type = logical - intent = in -[ccnorm] - standard_name = flag_for_in_cloud_condensate - long_name = flag for cloud condensate normalized by cloud cover - units = flag - dimensions = () - type = logical - intent = in -[norad_precip] - standard_name = flag_for_turning_off_precipitation_radiative_effect - long_name = radiation precip flag for Ferrier/Moorthi - units = flag +[lalw1bd] + standard_name = do_longwave_aerosol_band_properties + long_name = control of band or multiband longwave aerosol properties + units = 1 dimensions = () type = logical intent = in @@ -192,13 +188,6 @@ dimensions = (4) type = integer intent = in -[iflip] - standard_name = control_for_vertical_index_direction - long_name = flag for vertical index direction control - units = flag - dimensions = () - type = integer - intent = in [me] standard_name = mpi_rank long_name = current MPI-rank @@ -206,6 +195,91 @@ dimensions = () type = integer intent = in +[aeros_file] + standard_name = aerosol_data_file + long_name = aerosol data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[con_c] + standard_name = speed_of_light_in_vacuum + long_name = speed of light in vacuum + units = m s-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_plnk] + standard_name = planck_constant + long_name = Planck constant + units = J s-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_boltz] + standard_name = boltzmann_constant + long_name = Boltzmann constant + units = J K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_t0c] + standard_name = temperature_at_zero_celsius + long_name = temperature at 0 degree Celsius + units = K + dimensions = () + type = real + kind = kind_phys + intent = in +[co2usr_file] + standard_name = co2_user_data_table_file + long_name = co2 user defined data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2cyc_file] + standard_name = co2_clim_monthly_cycle_data_table_file + long_name = co2 climotological monthly cycle data table file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[ipsd0] + standard_name = initial_seed_for_mcica + long_name = initial permutaion seed for mcica radiation + units = 1 + dimensions = () + type = integer + intent = inout +[iaermdl] + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 + dimensions = () + type = integer + intent = out +[iaerflg] + standard_name = control_for_aerosol_effects_in_radiation + long_name = control of aerosol effects in radiation + units = 1 + dimensions = () + type = integer + intent = out [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -256,7 +330,7 @@ type = real kind = kind_phys intent = in -[lsswr] +[doSWrad] standard_name = flag_for_calling_shortwave_radiation long_name = logical flags for sw radiation calls units = flag @@ -270,6 +344,73 @@ dimensions = () type = integer intent = in +[aeros_file] + standard_name = aerosol_data_file + long_name = aerosol data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2dat_file] + standard_name = co2_monthly_obs_data_table_file + long_name = co2 monthly observation data table + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[co2gbl_file] + standard_name = co2_global_annual_mean_data_table_file + long_name = co2 global annual mean data file + units = none + dimensions = () + type = character + kind = len=26 + intent = in +[ictm] + standard_name = flag_for_initial_time_date_control + long_name = flag for initial conditions and forcing + units = flag + dimensions = () + type = integer + intent = in +[ico2] + standard_name = control_for_co2 + long_name = prescribed global mean value (old opernl) + units = flag + dimensions = () + type = integer + intent = in +[ntoz] + standard_name = index_of_ozone_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for ozone mixing ratio + units = index + dimensions = () + type = integer + intent = in +[iaermdl] + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 + dimensions = () + type = integer + intent = in +[isol] + standard_name = control_for_solar_constant + long_name = use prescribed solar constant + units = flag + dimensions = () + type = integer + intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [slag] standard_name = equation_of_time long_name = equation of time (radian) diff --git a/physics/GFS_rrtmgp_sw_post.F90 b/physics/GFS_rrtmgp_sw_post.F90 deleted file mode 100644 index 87ddc719b..000000000 --- a/physics/GFS_rrtmgp_sw_post.F90 +++ /dev/null @@ -1,286 +0,0 @@ -!> \file GFS_rrtmgp_sw_post.F90 -!! -!> \defgroup GFS_rrtmgp_sw_post GFS_rrtmgp_sw_post.F90 -!! -!! \brief RRTMGP Shortwave post-processing routine. -!! -module GFS_rrtmgp_sw_post - use machine, only: kind_phys - use module_radiation_aerosols, only: NSPC1 - use module_radsw_parameters, only: topfsw_type, sfcfsw_type, cmpfsw_type - use mo_heating_rates, only: compute_heating_rate - use radiation_tools, only: check_error_msg - use rrtmgp_sw_gas_optics, only: sw_gas_props - implicit none - - public GFS_rrtmgp_sw_post_run - -contains - -!>\defgroup gfs_rrtmgp_sw_post_mod GFS RRTMGP-SW Post Module -!> \section arg_table_GFS_rrtmgp_sw_post_run -!! \htmlinclude GFS_rrtmgp_sw_post_run.html -!! -!> \ingroup GFS_rrtmgp_sw_post -!! RRTMGP Shortwave post-processing routine. -!! -!! \brief The all-sky shortwave radiation tendency is computed, the clear-sky tendency is -!! computed if requested. -!! -!! RRTMGP surface and TOA fluxes are copied to fields that persist between radiation/physics -!! calls. -!! -!! (optional) Save additional diagnostics. -!! -!! \section GFS_rrtmgp_sw_post_run - ! ######################################################################################### - subroutine GFS_rrtmgp_sw_post_run (nCol, nLev, nDay, idxday, lsswr, do_sw_clrsky_hr, & - save_diag, fhswr, coszen, coszdg, t_lay, p_lev, sfc_alb_nir_dir, sfc_alb_nir_dif, & - sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, fluxswUP_allsky, & - fluxswDOWN_allsky, fluxswUP_clrsky, fluxswDOWN_clrsky, raddt, aerodp, cldsa, mbota, & - mtopa, cld_frac, cldtausw, fluxr, iSFC, iTOA, & - nirbmdi, nirdfdi, visbmdi, visdfdi, nirbmui, nirdfui, visbmui, visdfui, sfcnsw, & - sfcdsw, htrsw, sfcfsw, topfsw, htrswc, scmpsw, errmsg, errflg) - - ! Inputs - integer, intent(in) :: & - nCol, & ! Horizontal loop extent - nLev, & ! Number of vertical layers - nDay, & ! Number of daylit columns - iSFC, & ! Vertical index for surface level - iTOA ! Vertical index for TOA level - integer, intent(in), dimension(nday) :: & - idxday ! Index array for daytime points - logical, intent(in) :: & - lsswr, & ! Call SW radiation? - do_sw_clrsky_hr, & ! Output clear-sky SW heating-rate? - save_diag ! Output radiation diagnostics? - real(kind_phys), intent(in) :: & - fhswr ! Frequency for SW radiation - real(kind_phys), dimension(nCol), intent(in) :: & - t_lay, & ! Temperature at model layer centers (K) - coszen, & ! Cosine(SZA) - coszdg ! Cosine(SZA), daytime - real(kind_phys), dimension(nCol, nLev+1), intent(in) :: & - p_lev ! Pressure @ model layer-interfaces (Pa) - real(kind_phys), dimension(ncol), intent(in) :: & - sfc_alb_nir_dir, & ! Surface albedo (direct) - sfc_alb_nir_dif, & ! Surface albedo (diffuse) - sfc_alb_uvvis_dir, & ! Surface albedo (direct) - sfc_alb_uvvis_dif ! Surface albedo (diffuse) - real(kind_phys), dimension(nCol, nLev+1), intent(in) :: & - fluxswUP_allsky, & ! SW All-sky flux (W/m2) - fluxswDOWN_allsky, & ! SW All-sky flux (W/m2) - fluxswUP_clrsky, & ! SW Clear-sky flux (W/m2) - fluxswDOWN_clrsky ! SW All-sky flux (W/m2) - real(kind_phys), intent(in) :: & - raddt ! Radiation time step - real(kind_phys), dimension(nCol,NSPC1), intent(in) :: & - aerodp ! Vertical integrated optical depth for various aerosol species - real(kind_phys), dimension(nCol,5), intent(in) :: & - cldsa ! Fraction of clouds for low, middle, high, total and BL - integer, dimension(nCol,3), intent(in) ::& - mbota, & ! vertical indices for low, middle and high cloud tops - mtopa ! vertical indices for low, middle and high cloud bases - real(kind_phys), dimension(nCol,nLev), intent(in) :: & - cld_frac, & ! Total cloud fraction in each layer - cldtausw ! approx .55mu band layer cloud optical depth - type(cmpfsw_type), dimension(nCol), intent(in) :: & - scmpsw ! 2D surface fluxes, components: - ! uvbfc - total sky downward uv-b flux at (W/m2) - ! uvbf0 - clear sky downward uv-b flux at (W/m2) - ! nirbm - downward nir direct beam flux (W/m2) - ! nirdf - downward nir diffused flux (W/m2) - ! visbm - downward uv+vis direct beam flux (W/m2) - ! visdf - downward uv+vis diffused flux (W/m2) - - real(kind=kind_phys), dimension(:,:), intent(inout) :: fluxr - - ! Outputs (mandatory) - real(kind_phys), dimension(nCol), intent(inout) :: & - nirbmdi, & ! sfc nir beam sw downward flux (W/m2) - nirdfdi, & ! sfc nir diff sw downward flux (W/m2) - visbmdi, & ! sfc uv+vis beam sw downward flux (W/m2) - visdfdi, & ! sfc uv+vis diff sw downward flux (W/m2) - nirbmui, & ! sfc nir beam sw upward flux (W/m2) - nirdfui, & ! sfc nir diff sw upward flux (W/m2) - visbmui, & ! sfc uv+vis beam sw upward flux (W/m2) - visdfui, & ! sfc uv+vis diff sw upward flux (W/m2) - sfcnsw, & ! total sky sfc netsw flx into ground - sfcdsw ! - real(kind_phys), dimension(nCol,nLev), intent(inout) :: & - htrsw ! SW all-sky heating rate - type(sfcfsw_type), dimension(nCol), intent(inout) :: & - sfcfsw ! sw radiation fluxes at sfc - type(topfsw_type), dimension(nCol), intent(inout) :: & - topfsw ! sw_fluxes_top_atmosphere - character(len=*), intent(out) :: & - errmsg - integer, intent(out) :: & - errflg - - ! Outputs (optional) - real(kind_phys),dimension(nCol, nLev),intent(inout),optional :: & - htrswc ! Clear-sky heating rate (K/s) - - ! Local variables - integer :: i, j, k, itop, ibtc - real(kind_phys) :: tem0d, tem1, tem2 - real(kind_phys), dimension(nDay, nLev) :: thetaTendClrSky, thetaTendAllSky - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. lsswr) return - if (nDay .gt. 0) then - - ! ####################################################################################### - ! Compute SW heating-rates - ! ####################################################################################### - ! Clear-sky heating-rate (optional) - if (do_sw_clrsky_hr) then - htrswc(:,:) = 0._kind_phys - call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & - fluxswUP_clrsky(idxday(1:nDay),:), & ! IN - Shortwave upward clear-sky flux profiles (W/m2) - fluxswDOWN_clrsky(idxday(1:nDay),:), & ! IN - Shortwave downward clear-sky flux profiles (W/m2) - p_lev(idxday(1:nDay),:), & ! IN - Pressure at model-interface (Pa) - thetaTendClrSky)) ! OUT - Clear-sky heating-rate (K/sec) - htrswc(idxday(1:nDay),:)=thetaTendClrSky !**NOTE** GP doesn't use radiation levels, it uses the model fields. Not sure if this is necessary - endif - - ! All-sky heating-rate (mandatory) - htrsw(:,:) = 0._kind_phys - call check_error_msg('GFS_rrtmgp_post',compute_heating_rate( & - fluxswUP_allsky(idxday(1:nDay),:), & ! IN - Shortwave upward all-sky flux profiles (W/m2) - fluxswDOWN_allsky(idxday(1:nDay),:), & ! IN - Shortwave downward all-sky flux profiles (W/m2) - p_lev(idxday(1:nDay),:), & ! IN - Pressure at model-interface (Pa) - thetaTendAllSky)) ! OUT - All-sky heating-rate (K/sec) - htrsw(idxday(1:nDay),:) = thetaTendAllSky - - ! ####################################################################################### - ! Save SW outputs - ! (Copy fluxes from RRTMGP types into model radiation types.) - ! ####################################################################################### - - ! TOA fluxes - topfsw(:)%upfxc = fluxswUP_allsky(:,iTOA) - topfsw(:)%upfx0 = fluxswUP_clrsky(:,iTOA) - topfsw(:)%dnfxc = fluxswDOWN_allsky(:,iTOA) - - ! Surface fluxes - sfcfsw(:)%upfxc = fluxswUP_allsky(:,iSFC) - sfcfsw(:)%upfx0 = fluxswUP_clrsky(:,iSFC) - sfcfsw(:)%dnfxc = fluxswDOWN_allsky(:,iSFC) - sfcfsw(:)%dnfx0 = fluxswDOWN_clrsky(:,iSFC) - - ! Surface down and up spectral component fluxes - ! - Save two spectral bands' surface downward and upward fluxes for output. - do i=1,nCol - nirbmdi(i) = scmpsw(i)%nirbm - nirdfdi(i) = scmpsw(i)%nirdf - visbmdi(i) = scmpsw(i)%visbm - visdfdi(i) = scmpsw(i)%visdf - nirbmui(i) = scmpsw(i)%nirbm * sfc_alb_nir_dir(i) - nirdfui(i) = scmpsw(i)%nirdf * sfc_alb_nir_dif(i) - visbmui(i) = scmpsw(i)%visbm * sfc_alb_uvvis_dir(i) - visdfui(i) = scmpsw(i)%visdf * sfc_alb_uvvis_dif(i) - enddo - else ! if_nday_block - ! ####################################################################################### - ! Dark everywhere - ! ####################################################################################### - htrsw(:,:) = 0.0 - sfcfsw = sfcfsw_type( 0.0, 0.0, 0.0, 0.0 ) - topfsw = topfsw_type( 0.0, 0.0, 0.0 ) - do i=1,nCol - nirbmdi(i) = 0.0 - nirdfdi(i) = 0.0 - visbmdi(i) = 0.0 - visdfdi(i) = 0.0 - nirbmui(i) = 0.0 - nirdfui(i) = 0.0 - visbmui(i) = 0.0 - visdfui(i) = 0.0 - enddo - - if (do_sw_clrsky_hr) then - htrswc(:,:) = 0 - endif - endif ! end_if_nday - - ! Radiation fluxes for other physics processes - do i=1,nCol - sfcnsw(i) = sfcfsw(i)%dnfxc - sfcfsw(i)%upfxc - sfcdsw(i) = sfcfsw(i)%dnfxc - enddo - - ! ####################################################################################### - ! Save SW diagnostics - ! - For time averaged output quantities (including total-sky and clear-sky SW and LW - ! fluxes at TOA and surface; conventional 3-domain cloud amount, cloud top and base - ! pressure, and cloud top temperature; aerosols AOD, etc.), store computed results in - ! corresponding slots of array fluxr with appropriate time weights. - ! - Collect the fluxr data for wrtsfc - ! ####################################################################################### - if (save_diag) then - do i=1,nCol - fluxr(i,34) = aerodp(i,1) ! total aod at 550nm - fluxr(i,35) = aerodp(i,2) ! DU aod at 550nm - fluxr(i,36) = aerodp(i,3) ! BC aod at 550nm - fluxr(i,37) = aerodp(i,4) ! OC aod at 550nm - fluxr(i,38) = aerodp(i,5) ! SU aod at 550nm - fluxr(i,39) = aerodp(i,6) ! SS aod at 550nm - if (coszen(i) > 0.) then - ! SW all-sky fluxes - tem0d = fhswr * coszdg(i) / coszen(i) - fluxr(i,2 ) = fluxr(i,2) + topfsw(i)%upfxc * tem0d ! total sky top sw up - fluxr(i,3 ) = fluxr(i,3) + sfcfsw(i)%upfxc * tem0d - fluxr(i,4 ) = fluxr(i,4) + sfcfsw(i)%dnfxc * tem0d ! total sky sfc sw dn - ! SW uv-b fluxes - fluxr(i,21) = fluxr(i,21) + scmpsw(i)%uvbfc * tem0d ! total sky uv-b sw dn - fluxr(i,22) = fluxr(i,22) + scmpsw(i)%uvbf0 * tem0d ! clear sky uv-b sw dn - ! SW TOA incoming fluxes - fluxr(i,23) = fluxr(i,23) + topfsw(i)%dnfxc * tem0d ! top sw dn - ! SW SFC flux components - fluxr(i,24) = fluxr(i,24) + visbmdi(i) * tem0d ! uv/vis beam sw dn - fluxr(i,25) = fluxr(i,25) + visdfdi(i) * tem0d ! uv/vis diff sw dn - fluxr(i,26) = fluxr(i,26) + nirbmdi(i) * tem0d ! nir beam sw dn - fluxr(i,27) = fluxr(i,27) + nirdfdi(i) * tem0d ! nir diff sw dn - ! SW clear-sky fluxes - fluxr(i,29) = fluxr(i,29) + topfsw(i)%upfx0 * tem0d - fluxr(i,31) = fluxr(i,31) + sfcfsw(i)%upfx0 * tem0d - fluxr(i,32) = fluxr(i,32) + sfcfsw(i)%dnfx0 * tem0d - endif - enddo - - ! Save total and boundary-layer clouds - do i=1,nCol - fluxr(i,17) = fluxr(i,17) + raddt * cldsa(i,4) - fluxr(i,18) = fluxr(i,18) + raddt * cldsa(i,5) - enddo - - ! Save cld frac,toplyr,botlyr and top temp, note that the order of h,m,l cloud - ! is reversed for the fluxr output. save interface pressure (pa) of top/bot - do j = 1, 3 - do i = 1, nCol - tem0d = raddt * cldsa(i,j) - itop = mtopa(i,j) - ibtc = mbota(i,j) - fluxr(i, 8-j) = fluxr(i, 8-j) + tem0d - fluxr(i,11-j) = fluxr(i,11-j) + tem0d * p_lev(i,itop) - fluxr(i,14-j) = fluxr(i,14-j) + tem0d * p_lev(i,ibtc) - fluxr(i,17-j) = fluxr(i,17-j) + tem0d * p_lev(i,itop) - - ! Add optical depth and emissivity output - tem1 = 0. - do k=ibtc,itop - tem1 = tem1 + cldtausw(i,k) ! approx .55 mu channel - enddo - fluxr(i,43-j) = fluxr(i,43-j) + tem0d * tem1 - enddo - enddo - endif - end subroutine GFS_rrtmgp_sw_post_run - -end module GFS_rrtmgp_sw_post diff --git a/physics/GFS_rrtmgp_sw_pre.F90 b/physics/GFS_rrtmgp_sw_pre.F90 deleted file mode 100644 index 87d0f9ad1..000000000 --- a/physics/GFS_rrtmgp_sw_pre.F90 +++ /dev/null @@ -1,95 +0,0 @@ -!> \file GFS_rrtmgp_sw_pre.F90 -!! This file contains code to gather the sunlit points for the RRTMGP shortwave scheme. -!! -!> \defgroup GFS_rrtmgp_sw_pre RRTMGP Shortwave pre -!! -!! \brief *TODO* Combine with rrtmg_sw_pre.F90, maybe call sw_rad_pre.F90, use by both. -!! -module GFS_rrtmgp_sw_pre - use machine, only: kind_phys - use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp - use rrtmgp_sw_gas_optics, only: sw_gas_props - public GFS_rrtmgp_sw_pre_run -contains - -!> \section arg_table_GFS_rrtmgp_sw_pre_run -!! \htmlinclude GFS_rrtmgp_sw_pre.html -!! -!! \section GFS_rrtmgp_sw_pre RRTMGP shortwave pre routine -!! @{ -!! -!! Gather the sunlit points for shortwave radiation. -!! - ! ######################################################################################### - subroutine GFS_rrtmgp_sw_pre_run(nCol, doSWrad, coszen, nday, idxday, sfc_alb_nir_dir, & - sfc_alb_nir_dif, sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, sfc_alb_nir_dir_byband, & - sfc_alb_nir_dif_byband, sfc_alb_uvvis_dir_byband, sfc_alb_uvvis_dif_byband, errmsg, & - errflg) - - ! Input - integer, intent(in) :: & - nCol ! Number of horizontal grid points - logical,intent(in) :: & - doSWrad ! Call RRTMGP SW radiation? - real(kind_phys), dimension(:), intent(in) :: & - coszen - real(kind_phys), dimension(:), intent(in) :: & - sfc_alb_nir_dir, & ! - sfc_alb_nir_dif, & ! - sfc_alb_uvvis_dir, & ! - sfc_alb_uvvis_dif ! - - ! Outputs - integer, intent(out) :: & - nday ! Number of daylit points - integer, dimension(:), intent(out) :: & - idxday ! Indices for daylit points - real(kind_phys), dimension(:,:), intent(out) :: & - sfc_alb_nir_dir_byband, & ! Surface albedo (direct) - sfc_alb_nir_dif_byband, & ! Surface albedo (diffuse) - sfc_alb_uvvis_dir_byband, & ! Surface albedo (direct) - sfc_alb_uvvis_dif_byband ! Surface albedo (diffuse) - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - - ! Local variables - integer :: i, iBand - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (doSWrad) then - ! #################################################################################### - ! For SW gather daylit points - ! #################################################################################### - nday = 0 - idxday = 0 - do i = 1, nCol - if (coszen(i) >= 0.0001) then - nday = nday + 1 - idxday(nday) = i - endif - enddo - - ! Spread across all SW bands - do iBand=1,sw_gas_props%get_nband() - sfc_alb_nir_dir_byband(iBand,1:nCol) = sfc_alb_nir_dir(1:nCol) - sfc_alb_nir_dif_byband(iBand,1:nCol) = sfc_alb_nir_dif(1:nCol) - sfc_alb_uvvis_dir_byband(iBand,1:nCol) = sfc_alb_uvvis_dir(1:nCol) - sfc_alb_uvvis_dif_byband(iBand,1:nCol) = sfc_alb_uvvis_dif(1:nCol) - enddo - else - nday = 0 - idxday = 0 - sfc_alb_nir_dir_byband(:,1:nCol) = 0. - sfc_alb_nir_dif_byband(:,1:nCol) = 0. - sfc_alb_uvvis_dir_byband(:,1:nCol) = 0. - sfc_alb_uvvis_dif_byband(:,1:nCol) = 0. - endif - - end subroutine GFS_rrtmgp_sw_pre_run -!> @} -end module GFS_rrtmgp_sw_pre diff --git a/physics/GFS_rrtmgp_sw_pre.meta b/physics/GFS_rrtmgp_sw_pre.meta deleted file mode 100644 index 462ab5f18..000000000 --- a/physics/GFS_rrtmgp_sw_pre.meta +++ /dev/null @@ -1,124 +0,0 @@ -[ccpp-table-properties] - name = GFS_rrtmgp_sw_pre - type = scheme - dependencies = machine.F,radiation_astronomy.f,rrtmgp_sw_gas_optics.F90,rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90, - -######################################################################## -[ccpp-arg-table] - name = GFS_rrtmgp_sw_pre_run - type = scheme -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal loop extent - units = count - dimensions = () - type = integer - intent = in -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = logical flags for sw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[nday] - standard_name = daytime_points_dimension - long_name = daytime points dimension - units = count - dimensions = () - type = integer - intent = out -[idxday] - standard_name = daytime_points - long_name = daytime points - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent = out -[coszen] - standard_name = cosine_of_solar_zenith_angle_for_daytime_points_on_radiation_timestep - long_name = mean cos of zenith angle over rad call period - units = none - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_nir_dir] - standard_name = surface_albedo_due_to_near_IR_direct - long_name = surface albedo due to near IR direct beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_nir_dif] - standard_name = surface_albedo_due_to_near_IR_diffused - long_name = surface albedo due to near IR diffused beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_uvvis_dir] - standard_name = surface_albedo_due_to_UV_and_VIS_direct - long_name = surface albedo due to UV+VIS direct beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_uvvis_dif] - standard_name = surface_albedo_due_to_UV_and_VIS_diffused - long_name = surface albedo due to UV+VIS diffused beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_nir_dir_byband] - standard_name = surface_albedo_nearIR_direct - long_name = near-IR (direct) surface albedo (sfc_alb_nir_dir) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = out -[sfc_alb_nir_dif_byband] - standard_name = surface_albedo_nearIR_diffuse - long_name = near-IR (diffuse) surface albedo (sfc_alb_nir_dif) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = out -[sfc_alb_uvvis_dir_byband] - standard_name = surface_albedo_uvvis_direct - long_name = UVVIS (direct) surface albedo (sfc_alb_uvvis_dir) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = out -[sfc_alb_uvvis_dif_byband] - standard_name = surface_albedo_uvvis_diffuse - long_name = UVVIS (diffuse) surface albedo (sfc_alb_uvvis_dif) - units = none - dimensions = (number_of_shortwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = out -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/GFS_surface_composites_pre.F90 b/physics/GFS_surface_composites_pre.F90 index 734f1965b..a8b0a3112 100644 --- a/physics/GFS_surface_composites_pre.F90 +++ b/physics/GFS_surface_composites_pre.F90 @@ -4,7 +4,6 @@ module GFS_surface_composites_pre use machine, only: kind_phys - use physparam, only : iemsflg implicit none diff --git a/physics/GFS_surface_composites_pre.meta b/physics/GFS_surface_composites_pre.meta index e87af3e28..a0e30055f 100644 --- a/physics/GFS_surface_composites_pre.meta +++ b/physics/GFS_surface_composites_pre.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = GFS_surface_composites_pre type = scheme - dependencies = machine.F,physparam.f + dependencies = machine.F ######################################################################## [ccpp-arg-table] diff --git a/physics/cires_ugwp.F90 b/physics/cires_ugwp.F90 index 1fd274939..c648d9647 100644 --- a/physics/cires_ugwp.F90 +++ b/physics/cires_ugwp.F90 @@ -195,11 +195,13 @@ end subroutine cires_ugwp_finalize ! \section det_cires_ugwp CIRES UGWP V0 Scheme Detailed Algorithm subroutine cires_ugwp_run(do_ugwp, me, master, im, levs, ntrac, dtp, kdt, lonr, & oro, oro_uf, hprime, nmtvr, oc, theta, sigma, gamma, elvmax, clx, oa4, & - do_tofd, ldiag_ugwp, cdmbgwd, xlat, xlat_d, sinlat, coslat, area, & - ugrs, vgrs, tgrs, qgrs, prsi, prsl, prslk, phii, phil, & + do_tofd, ldiag_ugwp, cdmbgwd, xlat, xlat_d, sinlat, coslat, & + area, ugrs, vgrs, tgrs, qgrs, prsi, prsl, prslk, phii, phil, & del, kpbl, dusfcg, dvsfcg, gw_dudt, gw_dvdt, gw_dtdt, gw_kdis, & tau_tofd, tau_mtb, tau_ogw, tau_ngw, zmtb, zlwb, zogw, & - dudt_mtb,dudt_ogw, dudt_tms, du3dt_mtb, du3dt_ogw, du3dt_tms, & + dusfc_ms, dvsfc_ms, dusfc_bl, dvsfc_bl, & + dudt_ogw, dtauy2d_ms, dtaux2d_bl, dtauy2d_bl, & + dudt_mtb, dudt_tms, du3dt_mtb, du3dt_ogw, du3dt_tms, & dudt, dvdt, dtdt, rdxzb, con_g, con_pi, con_cp, con_rd, con_rv, con_fvirt, & con_omega, rain, ntke, q_tke, dqdt_tke, lprnt, ipr, & dtend, dtidx, index_of_x_wind, index_of_y_wind, index_of_temperature, & @@ -228,6 +230,9 @@ subroutine cires_ugwp_run(do_ugwp, me, master, im, levs, ntrac, dtp, kdt, lonr real(kind=kind_phys), intent(out), dimension(:) :: tau_mtb, tau_ogw, tau_tofd, tau_ngw real(kind=kind_phys), intent(out), dimension(:, :):: gw_dudt, gw_dvdt, gw_dtdt, gw_kdis real(kind=kind_phys), intent(out), dimension(:, :):: dudt_mtb, dudt_ogw, dudt_tms + real(kind=kind_phys), intent(out), dimension(:) :: dusfc_ms, dvsfc_ms, dusfc_bl, dvsfc_bl + real(kind=kind_phys), intent(out), dimension(:, :) :: dtauy2d_ms + real(kind=kind_phys), intent(out), dimension(:, :) :: dtaux2d_bl, dtauy2d_bl ! dtend is only allocated if ldiag=.true. real(kind=kind_phys), optional, intent(inout) :: dtend(:,:,:) @@ -314,9 +319,11 @@ subroutine cires_ugwp_run(do_ugwp, me, master, im, levs, ntrac, dtp, kdt, lonr ugrs, vgrs, tgrs, qgrs(:,:,1), & kpbl, prsi, del, prsl, prslk, phii, phil, dtp, kdt, & hprime, oc, oa4, clx, theta, sigma, gamma, & - elvmax, dusfcg, dvsfcg, & + elvmax, dusfcg, dvsfcg, dudt_ogw, dtauy2d_ms, & + dtaux2d_bl, dtauy2d_bl, dusfc_ms, dvsfc_ms, & + dusfc_bl, dvsfc_bl, & con_g, con_cp, con_rd, con_rv, lonr, & - nmtvr, cdmbgwd, me, lprnt, ipr, rdxzb, & + nmtvr, cdmbgwd, me, lprnt, ipr, rdxzb, ldiag_ugwp, & errmsg, errflg) if (errflg/=0) return endif diff --git a/physics/cires_ugwp.meta b/physics/cires_ugwp.meta index bf94edd26..d944a635e 100644 --- a/physics/cires_ugwp.meta +++ b/physics/cires_ugwp.meta @@ -596,11 +596,35 @@ type = real kind = kind_phys intent = out -[dudt_mtb] - standard_name = instantaneous_change_in_x_wind_due_to_mountain_blocking_drag - long_name = instantaneous change in x wind due to mountain blocking drag - units = m s-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) +[dusfc_ms] + standard_name = vertically_integrated_x_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = integrated x momentum flux from mesoscale gwd + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = out +[dvsfc_ms] + standard_name = vertically_integrated_y_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = integrated y momentum flux from mesoscale gwd + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = out +[dusfc_bl] + standard_name = vertically_integrated_x_momentum_flux_due_to_blocking_drag + long_name = integrated x momentum flux from blocking drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = out +[dvsfc_bl] + standard_name = vertically_integrated_y_momentum_flux_due_to_blocking_drag + long_name = integrated y momentum flux from blocking drag + units = Pa + dimensions = (horizontal_loop_extent) type = real kind = kind_phys intent = out @@ -612,6 +636,38 @@ type = real kind = kind_phys intent = out +[dtauy2d_ms] + standard_name = tendency_of_y_wind_due_to_mesoscale_orographic_gravity_wave_drag + long_name = instantaneous change in y wind due to orographic gw drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = out +[dtaux2d_bl] + standard_name = tendency_of_x_wind_due_to_blocking_drag + long_name = x wind tendency from blocking drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = out +[dtauy2d_bl] + standard_name = tendency_of_y_wind_due_to_blocking_drag + long_name = y wind tendency from blocking drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = out +[dudt_mtb] + standard_name = instantaneous_change_in_x_wind_due_to_mountain_blocking_drag + long_name = instantaneous change in x wind due to mountain blocking drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = out [dudt_tms] standard_name = tendency_of_x_wind_due_to_turbulent_orographic_form_drag long_name = instantaneous change in x wind due to TOFD diff --git a/physics/cires_ugwpv1_oro.F90 b/physics/cires_ugwpv1_oro.F90 index b0af0f2a1..423a21348 100644 --- a/physics/cires_ugwpv1_oro.F90 +++ b/physics/cires_ugwpv1_oro.F90 @@ -1002,7 +1002,9 @@ subroutine orogw_v1 (im, km, imx, me, master, dtp, kdt, do_tofd, & ! enddo print * - stop + errflg = 1 + errmsg = 'ERROR(orogw_v1): ' + return endif endif diff --git a/physics/cu_gf_deep.F90 b/physics/cu_gf_deep.F90 index e1976d55c..5abb990de 100644 --- a/physics/cu_gf_deep.F90 +++ b/physics/cu_gf_deep.F90 @@ -25,8 +25,8 @@ module cu_gf_deep real(kind=kind_phys), parameter :: pgcd = 0.1 ! !> aerosol awareness, do not use yet! - integer, parameter :: autoconv=2 - integer, parameter :: aeroevap=3 + integer, parameter :: autoconv=1 !2 + integer, parameter :: aeroevap=1 !3 real(kind=kind_phys), parameter :: scav_factor = 0.5 !> still 16 ensembles for clousres integer, parameter:: maxens3=16 diff --git a/physics/drag_suite.F90 b/physics/drag_suite.F90 index eaded9af8..5cb49acff 100644 --- a/physics/drag_suite.F90 +++ b/physics/drag_suite.F90 @@ -7,8 +7,14 @@ module drag_suite contains !> \defgroup gfs_drag_suite_mod GSL drag_suite Module -!> This module contains the CCPP-compliant GSL orographic gravity wave dray scheme. +!> This module contains the CCPP-compliant GSL orographic gravity wave drag scheme. !> @{ +!! +!> \brief This subroutine initializes the orographic gravity wave drag scheme. +!! +!> \section arg_table_drag_suite_init Argument Table +!! \htmlinclude drag_suite_init.html +!! subroutine drag_suite_init(gwd_opt, errmsg, errflg) integer, intent(in) :: gwd_opt @@ -29,7 +35,7 @@ subroutine drag_suite_init(gwd_opt, errmsg, errflg) end if end subroutine drag_suite_init -!> \brief This subroutine includes orographic gravity wave drag, mountain +!> \brief This subroutine includes orographic gravity wave drag, mountain !! blocking, and form drag. !! !> The time tendencies of zonal and meridional wind are altered to @@ -200,16 +206,17 @@ end subroutine drag_suite_init !! an independent process. The next step is to test !! !> \section det_drag_suite GFS Orographic GWD Scheme Detailed Algorithm +!> @{ subroutine drag_suite_run( & & IM,KM,dvdt,dudt,dtdt,U1,V1,T1,Q1,KPBL, & & PRSI,DEL,PRSL,PRSLK,PHII,PHIL,DELTIM,KDT, & & var,oc1,oa4,ol4, & & varss,oc1ss,oa4ss,ol4ss, & & THETA,SIGMA,GAMMA,ELVMAX, & - & dtaux2d_ls,dtauy2d_ls,dtaux2d_bl,dtauy2d_bl, & + & dtaux2d_ms,dtauy2d_ms,dtaux2d_bl,dtauy2d_bl, & & dtaux2d_ss,dtauy2d_ss,dtaux2d_fd,dtauy2d_fd, & & dusfc,dvsfc, & - & dusfc_ls,dvsfc_ls,dusfc_bl,dvsfc_bl, & + & dusfc_ms,dvsfc_ms,dusfc_bl,dvsfc_bl, & & dusfc_ss,dvsfc_ss,dusfc_fd,dvsfc_fd, & & slmsk,br1,hpbl, & & g, cp, rd, rv, fv, pi, imx, cdmbgwd, me, master, & @@ -217,7 +224,7 @@ subroutine drag_suite_run( & & do_gsl_drag_ls_bl, do_gsl_drag_ss, do_gsl_drag_tofd, & & dtend, dtidx, index_of_process_orographic_gwd, & & index_of_temperature, index_of_x_wind, & - & index_of_y_wind, ldiag3d, & + & index_of_y_wind, ldiag3d, ldiag_ugwp, ugwp_seq_update, & & spp_wts_gwd, spp_gwd, errmsg, errflg) ! ******************************************************************** @@ -248,22 +255,22 @@ subroutine drag_suite_run( & ! topographic form drag of Beljaars et al. (2004, QJRMS) ! Activation of each component is done by specifying the integer-parameters ! (defined below) to 0: inactive or 1: active -! gwd_opt_ls = 0 or 1: large-scale -! gwd_opt_bl = 0 or 1: blocking drag -! gwd_opt_ss = 0 or 1: small-scale gravity wave drag -! gwd_opt_fd = 0 or 1: topographic form drag -! 2017-09-25 Michael Toy (from NCEP GFS model) added dissipation heating -! gsd_diss_ht_opt = 0: dissipation heating off -! gsd_diss_ht_opt = 1: dissipation heating on +! gwd_opt_ms = 0 or 1: mesoscale (changed to logical flag) +! gwd_opt_bl = 0 or 1: blocking drag (changed to logical flag) +! gwd_opt_ss = 0 or 1: small-scale gravity wave drag (removed) +! gwd_opt_fd = 0 or 1: topographic form drag (removed) +! 2017-09-25 Michael Toy (from NCEP GFS model) added dissipation heating (logical flags) +! gsd_diss_ht_opt = .false. : dissipation heating off +! gsd_diss_ht_opt = .true. : dissipation heating on ! 2020-08-25 Michael Toy changed logic control for drag component selection ! for CCPP. ! Namelist options: -! do_gsl_drag_ls_bl - logical flag for large-scale GWD + blocking +! do_gsl_drag_ls_bl - logical flag for mesoscale GWD + blocking ! do_gsl_drag_ss - logical flag for small-scale GWD ! do_gsl_drag_tofd - logical flag for turbulent form drag -! Compile-time options (same as before): -! gwd_opt_ls = 0 or 1: large-scale GWD -! gwd_opt_bl = 0 or 1: blocking drag +! Compile-time options (changed from integer switches to logical flags): +! gwd_opt_ms = : mesoscale GWD (active if == .true.) +! gwd_opt_bl = : blocking drag (active if == .true.) ! ! References: ! Hong et al. (2008), wea. and forecasting @@ -366,23 +373,23 @@ subroutine drag_suite_run( & !SPP real(kind=kind_phys), dimension(im) :: var_stoch, varss_stoch, & - varmax_ss_stoch, varmax_fd_stoch + varmax_fd_stoch real(kind=kind_phys), intent(in) :: spp_wts_gwd(:,:) integer, intent(in) :: spp_gwd real(kind=kind_phys), dimension(im) :: rstoch !Output: - real(kind=kind_phys), intent(out) :: & + real(kind=kind_phys), intent(inout) :: & & dusfc(:), dvsfc(:) !Output (optional): - real(kind=kind_phys), intent(out) :: & - & dusfc_ls(:),dvsfc_ls(:), & + real(kind=kind_phys), intent(inout) :: & + & dusfc_ms(:),dvsfc_ms(:), & & dusfc_bl(:),dvsfc_bl(:), & & dusfc_ss(:),dvsfc_ss(:), & & dusfc_fd(:),dvsfc_fd(:) - real(kind=kind_phys), intent(out) :: & - & dtaux2d_ls(:,:),dtauy2d_ls(:,:), & + real(kind=kind_phys), intent(inout) :: & + & dtaux2d_ms(:,:),dtauy2d_ms(:,:), & & dtaux2d_bl(:,:),dtauy2d_bl(:,:), & & dtaux2d_ss(:,:),dtauy2d_ss(:,:), & & dtaux2d_fd(:,:),dtauy2d_fd(:,:) @@ -395,29 +402,40 @@ subroutine drag_suite_run( & ! Each component is tapered off automatically as a function of dx, so best to ! keep them activated (.true.). logical, intent(in) :: & - do_gsl_drag_ls_bl, & ! large-scale gravity wave drag and blocking + do_gsl_drag_ls_bl, & ! mesoscale gravity wave drag and blocking do_gsl_drag_ss, & ! small-scale gravity wave drag (Steeneveld et al. 2008) do_gsl_drag_tofd ! form drag (Beljaars et al. 2004, QJRMS) +! Flag for diagnostic outputs + logical, intent(in) :: ldiag_ugwp + +! Flag for sequential update of u and v between +! LSGWD + BLOCKING and SSGWD + TOFD calculations + logical, intent(in) :: ugwp_seq_update + +! More variables for sequential updating of winds + ! Updated winds + real(kind=kind_phys), dimension(im,km) :: uwnd1, vwnd1 + real(kind=kind_phys) :: tmp1, tmp2 ! temporary variables + ! Additional flags - integer, parameter :: & - gwd_opt_ls = 1, & ! large-scale gravity wave drag - gwd_opt_bl = 1, & ! blocking drag - gsd_diss_ht_opt = 0 + logical, parameter :: & + gwd_opt_ms = .true., & ! mesoscale gravity wave drag + gwd_opt_bl = .true., & ! blocking drag + gsd_diss_ht_opt = .false. ! dissipation heating ! Parameters for bounding the scale-adaptive variability: ! Small-scale GWD + turbulent form drag real(kind=kind_phys), parameter :: dxmin_ss = 1000., & & dxmax_ss = 12000. ! min,max range of tapering (m) -! Large-scale GWD + blocking - real(kind=kind_phys), parameter :: dxmin_ls = 3000., & - & dxmax_ls = 13000. ! min,max range of tapering (m) - real(kind=kind_phys), dimension(im) :: ss_taper, ls_taper ! small- and large-scale tapering factors (-) +! Mesoscale GWD + blocking + real(kind=kind_phys), parameter :: dxmin_ms = 3000., & + & dxmax_ms = 13000. ! min,max range of tapering (m) + real(kind=kind_phys), dimension(im) :: ss_taper, ls_taper ! small- and meso-scale tapering factors (-) ! ! Variables for limiting topographic standard deviation (var) - real(kind=kind_phys), parameter :: varmax_ss = 50., & - varmax_fd = 150., & - beta_ss = 0.1, & + real(kind=kind_phys), parameter :: varmax_ss = 50., & ! varmax_ss not used + varmax_fd = 500., & beta_fd = 0.2 real(kind=kind_phys) :: var_temp, var_temp2 @@ -441,6 +459,7 @@ subroutine drag_suite_run( & real(kind=kind_phys), parameter :: frc = 1.0 real(kind=kind_phys), parameter :: ce = 0.8 real(kind=kind_phys), parameter :: cg = 0.5 + real(kind=kind_phys), parameter :: sgmalolev = 0.5 ! max sigma lvl for dtfac integer,parameter :: kpblmin = 2 ! @@ -457,6 +476,9 @@ subroutine drag_suite_run( & ! logical :: ldrag(im),icrilv(im), & flag(im),kloop1(im) + logical :: prop_test +! + real(kind=kind_phys) :: onebgrcs ! real(kind=kind_phys) :: taub(im),taup(im,km+1), & xn(im),yn(im), & @@ -469,7 +491,7 @@ subroutine drag_suite_run( & brvf(im),xlinv(im), & delks(im),delks1(im), & bnv2(im,km),usqj(im,km), & - taud_ls(im,km),taud_bl(im,km), & + taud_ms(im,km),taud_bl(im,km), & ro(im,km), & vtk(im,km),vtj(im,km), & zlowtop(im),velco(im,km-1), & @@ -523,6 +545,16 @@ subroutine drag_suite_run( & Tdtend = dtidx(index_of_temperature,index_of_process_orographic_gwd) endif + + ! Initialize winds for sequential updating. + ! These are for optional sequential updating of the wind between the + ! LSGWD+BLOCKING and SSGWD+TOFD steps. They are placeholders + ! for the u1,v1 winds that are updated within the scheme if + ! ugwp_seq_update == T, otherwise, they retain the values + ! passed in to the subroutine. + uwnd1(:,:) = u1(:,:) + vwnd1(:,:) = v1(:,:) + !-------------------------------------------------------------------- ! SCALE-ADPTIVE PARAMETER FROM GFS GWD SCHEME !-------------------------------------------------------------------- @@ -565,6 +597,7 @@ subroutine drag_suite_run( & lcap = km lcapp1 = lcap + 1 fdir = mdir / (2.0*pi) + onebgrcs = 1._kind_phys/g*rcs do i=1,im if (slmsk(i)==1. .or. slmsk(i)==2.) then !sea/land/ice mask (=0/1/2) in FV3 @@ -577,14 +610,14 @@ subroutine drag_suite_run( & !--- calculate scale-aware tapering factors do i=1,im - if ( dx(i) .ge. dxmax_ls ) then + if ( dx(i) .ge. dxmax_ms ) then ls_taper(i) = 1. else - if ( dx(i) .le. dxmin_ls) then + if ( dx(i) .le. dxmin_ms) then ls_taper(i) = 0. else - ls_taper(i) = 0.5 * ( SIN(pi*(dx(i)-0.5*(dxmax_ls+dxmin_ls))/ & - (dxmax_ls-dxmin_ls)) + 1. ) + ls_taper(i) = 0.5 * ( SIN(pi*(dx(i)-0.5*(dxmax_ms+dxmin_ms))/ & + (dxmax_ms-dxmin_ms)) + 1. ) endif endif enddo @@ -597,14 +630,12 @@ subroutine drag_suite_run( & do i = its,im var_stoch(i) = var(i) + var(i)*0.75*spp_wts_gwd(i,1) varss_stoch(i) = varss(i) + varss(i)*0.75*spp_wts_gwd(i,1) - varmax_ss_stoch(i) = varmax_ss + varmax_ss*0.75*spp_wts_gwd(i,1) varmax_fd_stoch(i) = varmax_fd + varmax_fd*0.75*spp_wts_gwd(i,1) enddo else do i = its,im var_stoch(i) = var(i) varss_stoch(i) = varss(i) - varmax_ss_stoch(i) = varmax_ss varmax_fd_stoch(i) = varmax_fd enddo endif @@ -659,43 +690,15 @@ subroutine drag_suite_run( & vtj(i,k) = 0.0 vtk(i,k) = 0.0 taup(i,k) = 0.0 - taud_ls(i,k) = 0.0 + taud_ms(i,k) = 0.0 taud_bl(i,k) = 0.0 dtaux2d(i,k) = 0.0 dtauy2d(i,k) = 0.0 enddo enddo ! - if ( (gwd_opt == 33).or.(gwd_opt == 22) ) then - do i = its,im - dusfc_ls(i) = 0.0 - dvsfc_ls(i) = 0.0 - dusfc_bl(i) = 0.0 - dvsfc_bl(i) = 0.0 - dusfc_ss(i) = 0.0 - dvsfc_ss(i) = 0.0 - dusfc_fd(i) = 0.0 - dvsfc_fd(i) = 0.0 - enddo - do k = kts,km - do i = its,im - dtaux2d_ls(i,k)= 0.0 - dtauy2d_ls(i,k)= 0.0 - dtaux2d_bl(i,k)= 0.0 - dtauy2d_bl(i,k)= 0.0 - dtaux2d_ss(i,k)= 0.0 - dtauy2d_ss(i,k)= 0.0 - dtaux2d_fd(i,k)= 0.0 - dtauy2d_fd(i,k)= 0.0 - enddo - enddo - endif - do i = its,im - taup(i,km+1) = 0.0 xlinv(i) = 1.0/xl - dusfc(i) = 0.0 - dvsfc(i) = 0.0 enddo ! ! initialize array for flow-blocking drag @@ -809,8 +812,9 @@ subroutine drag_suite_run( & ! ! END INITIALIZATION; BEGIN GWD CALCULATIONS: ! + IF ( (do_gsl_drag_ls_bl).and. & - ((gwd_opt_ls .EQ. 1).or.(gwd_opt_bl .EQ. 1)) ) then + (gwd_opt_ms.or.gwd_opt_bl) ) then do i=its,im @@ -914,7 +918,7 @@ subroutine drag_suite_run( & xlinv(i) = coefm(i) * cleff tem = fr(i) * fr(i) * oc1(i) gfobnv = gmax * tem / ((tem + cg)*bnv(i)) - if ( gwd_opt_ls .NE. 0 ) then + if ( gwd_opt_ms ) then taub(i) = xlinv(i) * roll(i) * ulow(i) * ulow(i) & * ulow(i) * gfobnv * efact else ! We've gotten what we need for the blocking scheme @@ -930,200 +934,15 @@ subroutine drag_suite_run( & enddo ! do i=its,im -ENDIF ! (do_gsl_drag_ls_bl).and.((gwd_opt_ls .EQ. 1).or.(gwd_opt_bl .EQ. 1)) +ENDIF ! (do_gsl_drag_ls_bl).and.(gwd_opt_ms.or.gwd_opt_bl) -!========================================================= -! add small-scale wavedrag for stable boundary layer -!========================================================= - XNBV=0. - tauwavex0=0. - tauwavey0=0. - density=1.2 - utendwave=0. - vtendwave=0. -! -IF ( do_gsl_drag_ss ) THEN - do i=its,im - if ( ss_taper(i).GT.1.E-02 ) then - ! - ! calculating potential temperature - ! - do k = kts,km - thx(i,k) = t1(i,k)/prslk(i,k) - enddo - ! - do k = kts,km - tvcon = (1.+fv*q1(i,k)) - thvx(i,k) = thx(i,k)*tvcon - enddo - hpbl2 = hpbl(i)+10. - kpbl2 = kpbl(i) - !kvar = MIN(kpbl, k-level of var) - kvar = 1 - do k=kts+1,MAX(kpbl(i),kts+1) -! IF (zl(i,k)>2.*var(i) .or. zl(i,k)>2*varmax) then - IF (zl(i,k)>300.) then - kpbl2 = k - IF (k == kpbl(i)) then - hpbl2 = hpbl(i)+10. - ELSE - hpbl2 = zl(i,k)+10. - ENDIF - exit - ENDIF - enddo - if((xland(i)-1.5).le.0. .and. 2.*varss_stoch(i).le.hpbl(i))then - if(br1(i).gt.0. .and. thvx(i,kpbl2)-thvx(i,kts) > 0.)then - ! Modify xlinv to represent wave number of "typical" small-scale topography -! cleff_ss = 3. * max(dx(i),cleff_ss) -! cleff_ss = 10. * max(dxmax_ss,cleff_ss) -! cleff_ss = 0.1 * 12000. - xlinv(i) = 0.001*pi ! 2km horizontal wavelength - !govrth(i)=g/(0.5*(thvx(i,kpbl(i))+thvx(i,kts))) - govrth(i)=g/(0.5*(thvx(i,kpbl2)+thvx(i,kts))) - !XNBV=sqrt(govrth(i)*(thvx(i,kpbl(i))-thvx(i,kts))/hpbl(i)) - XNBV=sqrt(govrth(i)*(thvx(i,kpbl2)-thvx(i,kts))/hpbl2) -! - !if(abs(XNBV/u1(i,kpbl(i))).gt.xlinv(i))then - if(abs(XNBV/u1(i,kpbl2)).gt.xlinv(i))then - !tauwavex0=0.5*XNBV*xlinv(i)*(2*MIN(varss(i),75.))**2*ro(i,kts)*u1(i,kpbl(i)) - !tauwavex0=0.5*XNBV*xlinv(i)*(2.*MIN(varss(i),40.))**2*ro(i,kts)*u1(i,kpbl2) - !tauwavex0=0.5*XNBV*xlinv(i)*(2.*MIN(varss(i),40.))**2*ro(i,kts)*u1(i,3) - ! Remove limit on varss_stoch - var_temp = varss_stoch(i) - ! Note: This is a semi-implicit treatment of the time differencing - var_temp2 = 0.5*XNBV*xlinv(i)*(2.*var_temp)**2*ro(i,kvar) ! this is greater than zero - tauwavex0=var_temp2*u1(i,kvar)/(1.+var_temp2*deltim) - tauwavex0=tauwavex0*ss_taper(i) - else - tauwavex0=0. - endif -! - !if(abs(XNBV/v1(i,kpbl(i))).gt.xlinv(i))then - if(abs(XNBV/v1(i,kpbl2)).gt.xlinv(i))then - !tauwavey0=0.5*XNBV*xlinv(i)*(2*MIN(varss(i),75.))**2*ro(i,kts)*v1(i,kpbl(i)) - !tauwavey0=0.5*XNBV*xlinv(i)*(2.*MIN(varss(i),40.))**2*ro(i,kts)*v1(i,kpbl2) - !tauwavey0=0.5*XNBV*xlinv(i)*(2.*MIN(varss(i),40.))**2*ro(i,kts)*v1(i,3) - ! Remove limit on varss_stoch - var_temp = varss_stoch(i) - ! Note: This is a semi-implicit treatment of the time differencing - var_temp2 = 0.5*XNBV*xlinv(i)*(2.*var_temp)**2*ro(i,kvar) ! this is greater than zero - tauwavey0=var_temp2*v1(i,kvar)/(1.+var_temp2*deltim) - tauwavey0=tauwavey0*ss_taper(i) - else - tauwavey0=0. - endif - - do k=kts,kpbl(i) !MIN(kpbl2+1,km-1) -!original - !utendwave(i,k)=-1.*tauwavex0*2.*max((1.-zl(i,k)/hpbl(i)),0.)/hpbl(i) - !vtendwave(i,k)=-1.*tauwavey0*2.*max((1.-zl(i,k)/hpbl(i)),0.)/hpbl(i) -!new - utendwave(i,k)=-1.*tauwavex0*2.*max((1.-zl(i,k)/hpbl2),0.)/hpbl2 - vtendwave(i,k)=-1.*tauwavey0*2.*max((1.-zl(i,k)/hpbl2),0.)/hpbl2 -!mod-to be used in HRRRv3/RAPv4 - !utendwave(i,k)=-1.*tauwavex0 * max((1.-zl(i,k)/hpbl2),0.)**2 - !vtendwave(i,k)=-1.*tauwavey0 * max((1.-zl(i,k)/hpbl2),0.)**2 - enddo - endif - endif - - do k = kts,km - dudt(i,k) = dudt(i,k) + utendwave(i,k) - dvdt(i,k) = dvdt(i,k) + vtendwave(i,k) - dusfc(i) = dusfc(i) + utendwave(i,k) * del(i,k) - dvsfc(i) = dvsfc(i) + vtendwave(i,k) * del(i,k) - enddo - if(udtend>0) then - dtend(i,kts:km,udtend) = dtend(i,kts:km,udtend) + utendwave(i,kts:km)*deltim - endif - if(vdtend>0) then - dtend(i,kts:km,vdtend) = dtend(i,kts:km,vdtend) + vtendwave(i,kts:km)*deltim - endif - if ( (gwd_opt == 33).or.(gwd_opt == 22) ) then - do k = kts,km - dusfc_ss(i) = dusfc_ss(i) + utendwave(i,k) * del(i,k) - dvsfc_ss(i) = dvsfc_ss(i) + vtendwave(i,k) * del(i,k) - dtaux2d_ss(i,k) = utendwave(i,k) - dtauy2d_ss(i,k) = vtendwave(i,k) - enddo - endif - - endif ! if (ss_taper(i).GT.1.E-02) - - enddo ! i=its,im - -ENDIF ! if (do_gsl_drag_ss) - -!================================================================ -! Topographic Form Drag from Beljaars et al. (2004, QJRMS, equ. 16): -!================================================================ -IF ( do_gsl_drag_tofd ) THEN - - do i=its,im - - if ( ss_taper(i).GT.1.E-02 ) then - - utendform=0. - vtendform=0. - - IF ((xland(i)-1.5) .le. 0.) then - !(IH*kflt**n1)**-1 = (0.00102*0.00035**-1.9)**-1 = 0.00026615161 - ! Remove limit on varss_stoch - var_temp = varss_stoch(i) - !var_temp = MIN(var_temp, 250.) - a1=0.00026615161*var_temp**2 -! a1=0.00026615161*MIN(varss(i),varmax)**2 -! a1=0.00026615161*(0.5*varss(i))**2 - ! k1**(n1-n2) = 0.003**(-1.9 - -2.8) = 0.003**0.9 = 0.005363 - a2=a1*0.005363 - ! Beljaars H_efold - H_efold = 1500. - DO k=kts,km - wsp=SQRT(u1(i,k)**2 + v1(i,k)**2) - ! alpha*beta*Cmd*Ccorr*2.109 = 12.*1.*0.005*0.6*2.109 = 0.0759 - var_temp = 0.0759*EXP(-(zl(i,k)/H_efold)**1.5)*a2* & - zl(i,k)**(-1.2)*ss_taper(i) ! this is greater than zero - ! Note: This is a semi-implicit treatment of the time differencing - ! per Beljaars et al. (2004, QJRMS) - utendform(i,k) = - var_temp*wsp*u1(i,k)/(1. + var_temp*deltim*wsp) - vtendform(i,k) = - var_temp*wsp*v1(i,k)/(1. + var_temp*deltim*wsp) - !IF(zl(i,k) > 4000.) exit - ENDDO - ENDIF - - do k = kts,km - dudt(i,k) = dudt(i,k) + utendform(i,k) - dvdt(i,k) = dvdt(i,k) + vtendform(i,k) - dusfc(i) = dusfc(i) + utendform(i,k) * del(i,k) - dvsfc(i) = dvsfc(i) + vtendform(i,k) * del(i,k) - enddo - if(udtend>0) then - dtend(i,kts:km,udtend) = dtend(i,kts:km,udtend) + utendform(i,kts:km)*deltim - endif - if(vdtend>0) then - dtend(i,kts:km,vdtend) = dtend(i,kts:km,vdtend) + vtendform(i,kts:km)*deltim - endif - if ( (gwd_opt == 33).or.(gwd_opt == 22) ) then - do k = kts,km - dtaux2d_fd(i,k) = utendform(i,k) - dtauy2d_fd(i,k) = vtendform(i,k) - dusfc_fd(i) = dusfc_fd(i) + utendform(i,k) * del(i,k) - dvsfc_fd(i) = dvsfc_fd(i) + vtendform(i,k) * del(i,k) - enddo - endif - - endif ! if (ss_taper(i).GT.1.E-02) - - enddo ! i=its,im - -ENDIF ! if (do_gsl_drag_tofd) !======================================================= -! More for the large-scale gwd component -IF ( (do_gsl_drag_ls_bl).and.(gwd_opt_ls .EQ. 1) ) THEN +! Mesoscale GWD + blocking +!======================================================= +IF ( (do_gsl_drag_ls_bl).and.(gwd_opt_ms) ) THEN do i=its,im @@ -1188,11 +1007,11 @@ subroutine drag_suite_run( & enddo ! do i=its,im -ENDIF ! (do_gsl_drag_ls_bl).and.(gwd_opt_ls .EQ. 1) +ENDIF ! (do_gsl_drag_ls_bl).and.(gwd_opt_ms) !=============================================================== !COMPUTE BLOCKING COMPONENT !=============================================================== -IF ( (do_gsl_drag_ls_bl) .and. (gwd_opt_bl .EQ. 1) ) THEN +IF ( do_gsl_drag_ls_bl .and. gwd_opt_bl ) THEN do i=its,im @@ -1227,7 +1046,7 @@ subroutine drag_suite_run( & cd = max(2.0-1.0/od(i),0.0) ! New cdmbgwd addition for GSL blocking drag taufb(i,kts) = cdmb * 0.5 * roll(i) * coefm(i) / & - max(dxmax_ls,dxy(i))**2 * cd * dxyp(i) * & + max(dxmax_ms,dxy(i))**2 * cd * dxyp(i) * & olp(i) * zblk * ulow(i)**2 tautem = taufb(i,kts)/float(kblk-kts) do k = kts+1, kblk @@ -1245,10 +1064,10 @@ subroutine drag_suite_run( & enddo ! do i=its,im -ENDIF ! IF ( (do_gsl_drag_ls_bl) .and. (gwd_opt_bl .EQ. 1) ) +ENDIF ! IF ( do_gsl_drag_ls_bl .and. gwd_opt_bl ) !=========================================================== IF ( (do_gsl_drag_ls_bl) .and. & - (gwd_opt_ls .EQ. 1 .OR. gwd_opt_bl .EQ. 1) ) THEN + (gwd_opt_ms .OR. gwd_opt_bl) ) THEN do i=its,im @@ -1257,44 +1076,59 @@ subroutine drag_suite_run( & ! ! calculate - (g)*d(tau)/d(pressure) and deceleration terms dtaux, dtauy ! +! First, set taup (momentum flux) at model top equal to that of the layer +! interface just below the top, i.e., taup(km) +! The idea is to allow the momentum flux to go out the 'top'. This +! ensures there is no GWD force at the top layer. +! + taup(i,km+1) = taup(i,km) do k = kts,km - taud_ls(i,k) = 1. * (taup(i,k+1) - taup(i,k)) * csg / del(i,k) - taud_bl(i,k) = 1. * (taufb(i,k+1) - taufb(i,k)) * csg / del(i,k) + taud_ms(i,k) = (taup(i,k+1) - taup(i,k)) * csg / del(i,k) + taud_bl(i,k) = (taufb(i,k+1) - taufb(i,k)) * csg / del(i,k) enddo ! -! limit de-acceleration (momentum deposition ) at top to 1/2 value -! the idea is some stuff must go out the 'top' - do klcap = lcap,km - taud_ls(i,klcap) = taud_ls(i,klcap) * factop - taud_bl(i,klcap) = taud_bl(i,klcap) * factop - enddo ! -! if the gravity wave drag would force a critical line -! in the lower ksmm1 layers during the next deltim timestep, -! then only apply drag until that critical line is reached. +! if the gravity wave drag + blocking would force a critical line +! in the layers below pressure-based 'sigma' level = sgmalolev during the next deltim +! timestep, then only apply drag until that critical line is reached, i.e., +! reduce drag to limit resulting wind components to zero +! Note: 'sigma' = prsi(k)/prsi(k=1), where prsi(k=1) is the surface pressure ! do k = kts,kpblmax-1 - if (k .le. kbl(i)) then - if ((taud_ls(i,k)+taud_bl(i,k)).ne.0.) & + if (prsi(i,k).ge.sgmalolev*prsi(i,1)) then + if ((taud_ms(i,k)+taud_bl(i,k)).ne.0.) & dtfac(i) = min(dtfac(i),abs(velco(i,k) & - /(deltim*rcs*(taud_ls(i,k)+taud_bl(i,k))))) + /(deltim*rcs*(taud_ms(i,k)+taud_bl(i,k))))) + else + exit endif enddo ! do k = kts,km - taud_ls(i,k) = taud_ls(i,k)*dtfac(i)* ls_taper(i) *(1.-rstoch(i)) + taud_ms(i,k) = taud_ms(i,k)*dtfac(i)* ls_taper(i) *(1.-rstoch(i)) taud_bl(i,k) = taud_bl(i,k)*dtfac(i)* ls_taper(i) *(1.-rstoch(i)) - dtaux = taud_ls(i,k) * xn(i) - dtauy = taud_ls(i,k) * yn(i) + dtaux = taud_ms(i,k) * xn(i) + dtauy = taud_ms(i,k) * yn(i) dtauxb = taud_bl(i,k) * xn(i) dtauyb = taud_bl(i,k) * yn(i) - !add blocking and large-scale contributions to tendencies - dudt(i,k) = dtaux + dtauxb + dudt(i,k) - dvdt(i,k) = dtauy + dtauyb + dvdt(i,k) + !add blocking and mesoscale contributions to tendencies + tmp1 = dtaux + dtauxb + tmp2 = dtauy + dtauyb + dudt(i,k) = tmp1 + dudt(i,k) + dvdt(i,k) = tmp2 + dvdt(i,k) + + ! Update winds if sequential updating is selected + ! and SSGWD and TOFD will be calculated + ! Note: uwnd1 and vwnd1 replace u1 and u2,respectively, + ! for the SSGWD and TOFD calculations + if ( ugwp_seq_update .and. (do_gsl_drag_ss.or.do_gsl_drag_tofd) ) then + uwnd1(i,k) = uwnd1(i,k) + tmp1*deltim + vwnd1(i,k) = vwnd1(i,k) + tmp2*deltim + endif - if ( gsd_diss_ht_opt .EQ. 1 ) then + if ( gsd_diss_ht_opt ) then ! Calculate dissipation heating ! Initial kinetic energy (at t0-dt) eng0 = 0.5*( (rcs*u1(i,k))**2. + (rcs*v1(i,k))**2. ) @@ -1308,35 +1142,31 @@ subroutine drag_suite_run( & endif endif - dusfc(i) = dusfc(i) + taud_ls(i,k)*xn(i)*del(i,k) + & - taud_bl(i,k)*xn(i)*del(i,k) - dvsfc(i) = dvsfc(i) + taud_ls(i,k)*yn(i)*del(i,k) + & - taud_bl(i,k)*yn(i)*del(i,k) + dusfc(i) = dusfc(i) - onebgrcs * ( taud_ms(i,k)*xn(i)*del(i,k) + & + taud_bl(i,k)*xn(i)*del(i,k) ) + dvsfc(i) = dvsfc(i) - onebgrcs * ( taud_ms(i,k)*yn(i)*del(i,k) + & + taud_bl(i,k)*yn(i)*del(i,k) ) if(udtend>0) then - dtend(i,k,udtend) = dtend(i,k,udtend) + (taud_ls(i,k) * & + dtend(i,k,udtend) = dtend(i,k,udtend) + (taud_ms(i,k) * & xn(i) + taud_bl(i,k) * xn(i)) * deltim endif if(vdtend>0) then - dtend(i,k,vdtend) = dtend(i,k,vdtend) + (taud_ls(i,k) * & + dtend(i,k,vdtend) = dtend(i,k,vdtend) + (taud_ms(i,k) * & yn(i) + taud_bl(i,k) * yn(i)) * deltim endif enddo - ! Finalize dusfc and dvsfc diagnostics - dusfc(i) = (-1./g*rcs) * dusfc(i) - dvsfc(i) = (-1./g*rcs) * dvsfc(i) - - if ( (gwd_opt == 33).or.(gwd_opt == 22) ) then + if ( ldiag_ugwp ) then do k = kts,km - dtaux2d_ls(i,k) = taud_ls(i,k) * xn(i) - dtauy2d_ls(i,k) = taud_ls(i,k) * yn(i) + dtaux2d_ms(i,k) = taud_ms(i,k) * xn(i) + dtauy2d_ms(i,k) = taud_ms(i,k) * yn(i) dtaux2d_bl(i,k) = taud_bl(i,k) * xn(i) dtauy2d_bl(i,k) = taud_bl(i,k) * yn(i) - dusfc_ls(i) = dusfc_ls(i) + dtaux2d_ls(i,k) * del(i,k) - dvsfc_ls(i) = dvsfc_ls(i) + dtauy2d_ls(i,k) * del(i,k) - dusfc_bl(i) = dusfc_bl(i) + dtaux2d_bl(i,k) * del(i,k) - dvsfc_bl(i) = dvsfc_bl(i) + dtauy2d_bl(i,k) * del(i,k) + dusfc_ms(i) = dusfc_ms(i) - onebgrcs * dtaux2d_ms(i,k) * del(i,k) + dvsfc_ms(i) = dvsfc_ms(i) - onebgrcs * dtauy2d_ms(i,k) * del(i,k) + dusfc_bl(i) = dusfc_bl(i) - onebgrcs * dtaux2d_bl(i,k) * del(i,k) + dvsfc_bl(i) = dvsfc_bl(i) - onebgrcs * dtauy2d_bl(i,k) * del(i,k) enddo endif @@ -1344,20 +1174,217 @@ subroutine drag_suite_run( & enddo ! do i=its,im -ENDIF ! (do_gsl_drag_ls_bl).and.(gwd_opt_ls.EQ.1 .OR. gwd_opt_bl.EQ.1) +ENDIF ! (do_gsl_drag_ls_bl).and.(gwd_opt_ms .OR. gwd_opt_bl) -if ( (gwd_opt == 33).or.(gwd_opt == 22) ) then - ! Finalize dusfc and dvsfc diagnostics - do i = its,im - dusfc_ls(i) = (-1./g*rcs) * dusfc_ls(i) - dvsfc_ls(i) = (-1./g*rcs) * dvsfc_ls(i) - dusfc_bl(i) = (-1./g*rcs) * dusfc_bl(i) - dvsfc_bl(i) = (-1./g*rcs) * dvsfc_bl(i) - dusfc_ss(i) = (-1./g*rcs) * dusfc_ss(i) - dvsfc_ss(i) = (-1./g*rcs) * dvsfc_ss(i) - dusfc_fd(i) = (-1./g*rcs) * dusfc_fd(i) - dvsfc_fd(i) = (-1./g*rcs) * dvsfc_fd(i) - enddo + +!==================================================================== +! Calculate small-scale gravity wave drag for stable boundary layer +!==================================================================== + XNBV=0. + tauwavex0=0. + tauwavey0=0. + density=1.2 + utendwave=0. + vtendwave=0. +! +IF ( do_gsl_drag_ss ) THEN + + do i=its,im + + if ( ss_taper(i).GT.1.E-02 ) then + ! + ! calculating potential temperature + ! + do k = kts,km + thx(i,k) = t1(i,k)/prslk(i,k) + enddo + ! + do k = kts,km + tvcon = (1.+fv*q1(i,k)) + thvx(i,k) = thx(i,k)*tvcon + enddo + + hpbl2 = hpbl(i)+10. + kpbl2 = kpbl(i) + !kvar = MIN(kpbl, k-level of var) + kvar = 1 + do k=kts+1,MAX(kpbl(i),kts+1) +! IF (zl(i,k)>2.*var(i) .or. zl(i,k)>2*varmax) then + IF (zl(i,k)>300.) then + kpbl2 = k + IF (k == kpbl(i)) then + hpbl2 = hpbl(i)+10. + ELSE + hpbl2 = zl(i,k)+10. + ENDIF + exit + ENDIF + enddo + if((xland(i)-1.5).le.0. .and. 2.*varss_stoch(i).le.hpbl(i))then + if(br1(i).gt.0. .and. thvx(i,kpbl2)-thvx(i,kts) > 0.)then + ! Modify xlinv to represent wave number of "typical" small-scale topography +! cleff_ss = 3. * max(dx(i),cleff_ss) +! cleff_ss = 10. * max(dxmax_ss,cleff_ss) +! cleff_ss = 0.1 * 12000. + xlinv(i) = 0.001*pi ! 2km horizontal wavelength + !govrth(i)=g/(0.5*(thvx(i,kpbl(i))+thvx(i,kts))) + govrth(i)=g/(0.5*(thvx(i,kpbl2)+thvx(i,kts))) + !XNBV=sqrt(govrth(i)*(thvx(i,kpbl(i))-thvx(i,kts))/hpbl(i)) + XNBV=sqrt(govrth(i)*(thvx(i,kpbl2)-thvx(i,kts))/hpbl2) +! + ! check for possibility of vertical wave propagation + ! (avoids division by zero if uwnd1(i,kpbl2).eq.0.) + if (uwnd1(i,kpbl2).eq.0.) then + prop_test = .true. + elseif (abs(XNBV/uwnd1(i,kpbl2)).gt.xlinv(i)) then + prop_test = .true. + else + prop_test = .false. + endif + if (prop_test) then + ! Remove limit on varss_stoch + var_temp = varss_stoch(i) + ! Note: This is a semi-implicit treatment of the time differencing + var_temp2 = 0.5*XNBV*xlinv(i)*(2.*var_temp)**2*ro(i,kvar) ! this is greater than zero + tauwavex0=var_temp2*uwnd1(i,kvar)/(1.+var_temp2*deltim) + tauwavex0=tauwavex0*ss_taper(i) + else + tauwavex0=0. + endif +! + ! check for possibility of vertical wave propagation + ! (avoids division by zero if vwnd1(i,kpbl2).eq.0.) + if (vwnd1(i,kpbl2).eq.0.) then + prop_test = .true. + elseif (abs(XNBV/vwnd1(i,kpbl2)).gt.xlinv(i)) then + prop_test = .true. + else + prop_test = .false. + endif + if (prop_test) then + ! Remove limit on varss_stoch + var_temp = varss_stoch(i) + ! Note: This is a semi-implicit treatment of the time differencing + var_temp2 = 0.5*XNBV*xlinv(i)*(2.*var_temp)**2*ro(i,kvar) ! this is greater than zero + tauwavey0=var_temp2*vwnd1(i,kvar)/(1.+var_temp2*deltim) + tauwavey0=tauwavey0*ss_taper(i) + else + tauwavey0=0. + endif + + do k=kts,kpbl(i) !MIN(kpbl2+1,km-1) +!original + !utendwave(i,k)=-1.*tauwavex0*2.*max((1.-zl(i,k)/hpbl(i)),0.)/hpbl(i) + !vtendwave(i,k)=-1.*tauwavey0*2.*max((1.-zl(i,k)/hpbl(i)),0.)/hpbl(i) +!new + utendwave(i,k)=-1.*tauwavex0*2.*max((1.-zl(i,k)/hpbl2),0.)/hpbl2 + vtendwave(i,k)=-1.*tauwavey0*2.*max((1.-zl(i,k)/hpbl2),0.)/hpbl2 +!mod-to be used in HRRRv3/RAPv4 + !utendwave(i,k)=-1.*tauwavex0 * max((1.-zl(i,k)/hpbl2),0.)**2 + !vtendwave(i,k)=-1.*tauwavey0 * max((1.-zl(i,k)/hpbl2),0.)**2 + enddo + endif + endif + + do k = kts,km + dudt(i,k) = dudt(i,k) + utendwave(i,k) + dvdt(i,k) = dvdt(i,k) + vtendwave(i,k) + dusfc(i) = dusfc(i) - onebgrcs * utendwave(i,k) * del(i,k) + dvsfc(i) = dvsfc(i) - onebgrcs * vtendwave(i,k) * del(i,k) + enddo + if(udtend>0) then + dtend(i,kts:km,udtend) = dtend(i,kts:km,udtend) + utendwave(i,kts:km)*deltim + endif + if(vdtend>0) then + dtend(i,kts:km,vdtend) = dtend(i,kts:km,vdtend) + vtendwave(i,kts:km)*deltim + endif + if ( ldiag_ugwp ) then + do k = kts,km + dusfc_ss(i) = dusfc_ss(i) + utendwave(i,k) * del(i,k) + dvsfc_ss(i) = dvsfc_ss(i) + vtendwave(i,k) * del(i,k) + dtaux2d_ss(i,k) = utendwave(i,k) + dtauy2d_ss(i,k) = vtendwave(i,k) + enddo + endif + + endif ! if (ss_taper(i).GT.1.E-02) + + enddo ! i=its,im + +ENDIF ! if (do_gsl_drag_ss) + + +!=================================================================== +! Topographic Form Drag from Beljaars et al. (2004, QJRMS, equ. 16): +!=================================================================== +IF ( do_gsl_drag_tofd ) THEN + + do i=its,im + + if ( ss_taper(i).GT.1.E-02 ) then + + utendform=0. + vtendform=0. + + IF ((xland(i)-1.5) .le. 0.) then + !(IH*kflt**n1)**-1 = (0.00102*0.00035**-1.9)**-1 = 0.00026615161 + var_temp = MIN(varss_stoch(i),varmax_fd_stoch(i)) + & + MAX(0.,beta_fd*(varss_stoch(i)-varmax_fd_stoch(i))) + a1=0.00026615161*var_temp**2 +! a1=0.00026615161*MIN(varss(i),varmax)**2 +! a1=0.00026615161*(0.5*varss(i))**2 + ! k1**(n1-n2) = 0.003**(-1.9 - -2.8) = 0.003**0.9 = 0.005363 + a2=a1*0.005363 + ! Beljaars H_efold + H_efold = 1500. + DO k=kts,km + wsp=SQRT(uwnd1(i,k)**2 + vwnd1(i,k)**2) + ! alpha*beta*Cmd*Ccorr*2.109 = 12.*1.*0.005*0.6*2.109 = 0.0759 + var_temp = 0.0759*EXP(-(zl(i,k)/H_efold)**1.5)*a2* & + zl(i,k)**(-1.2)*ss_taper(i) ! this is greater than zero + ! Note: This is a semi-implicit treatment of the time differencing + ! per Beljaars et al. (2004, QJRMS) + utendform(i,k) = - var_temp*wsp*uwnd1(i,k)/(1. + var_temp*deltim*wsp) + vtendform(i,k) = - var_temp*wsp*vwnd1(i,k)/(1. + var_temp*deltim*wsp) + !IF(zl(i,k) > 4000.) exit + ENDDO + ENDIF + + do k = kts,km + dudt(i,k) = dudt(i,k) + utendform(i,k) + dvdt(i,k) = dvdt(i,k) + vtendform(i,k) + dusfc(i) = dusfc(i) - onebgrcs * utendform(i,k) * del(i,k) + dvsfc(i) = dvsfc(i) - onebgrcs * vtendform(i,k) * del(i,k) + enddo + if(udtend>0) then + dtend(i,kts:km,udtend) = dtend(i,kts:km,udtend) + utendform(i,kts:km)*deltim + endif + if(vdtend>0) then + dtend(i,kts:km,vdtend) = dtend(i,kts:km,vdtend) + vtendform(i,kts:km)*deltim + endif + if ( ldiag_ugwp ) then + do k = kts,km + dtaux2d_fd(i,k) = utendform(i,k) + dtauy2d_fd(i,k) = vtendform(i,k) + dusfc_fd(i) = dusfc_fd(i) + utendform(i,k) * del(i,k) + dvsfc_fd(i) = dvsfc_fd(i) + vtendform(i,k) * del(i,k) + enddo + endif + + endif ! if (ss_taper(i).GT.1.E-02) + + enddo ! i=its,im + +ENDIF ! if (do_gsl_drag_tofd) + + + +if ( ldiag_ugwp ) then + ! Finalize dusfc and dvsfc diagnostics for gsl small-scale drag components + dusfc_ss(:) = -onebgrcs * dusfc_ss(:) + dvsfc_ss(:) = -onebgrcs * dvsfc_ss(:) + dusfc_fd(:) = -onebgrcs * dusfc_fd(:) + dvsfc_fd(:) = -onebgrcs * dvsfc_fd(:) endif ! return diff --git a/physics/drag_suite.meta b/physics/drag_suite.meta index 8de3610f5..ff60290ae 100644 --- a/physics/drag_suite.meta +++ b/physics/drag_suite.meta @@ -270,70 +270,70 @@ type = real kind = kind_phys intent = in -[dtaux2d_ls] +[dtaux2d_ms] standard_name = tendency_of_x_wind_due_to_mesoscale_orographic_gravity_wave_drag - long_name = x momentum tendency from large scale gwd + long_name = x wind tendency from mesoscale gwd units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out -[dtauy2d_ls] + intent = inout +[dtauy2d_ms] standard_name = tendency_of_y_wind_due_to_mesoscale_orographic_gravity_wave_drag - long_name = y momentum tendency from large scale gwd + long_name = y wind tendency from mesoscale gwd units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtaux2d_bl] - standard_name = tendency_of_x_momentum_due_to_blocking_drag - long_name = x momentum tendency from blocking drag + standard_name = tendency_of_x_wind_due_to_blocking_drag + long_name = x wind tendency from blocking drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtauy2d_bl] - standard_name = tendency_of_y_momentum_due_to_blocking_drag - long_name = y momentum tendency from blocking drag + standard_name = tendency_of_y_wind_due_to_blocking_drag + long_name = y wind tendency from blocking drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtaux2d_ss] - standard_name = tendency_of_x_momentum_due_to_small_scale_gravity_wave_drag - long_name = x momentum tendency from small scale gwd + standard_name = tendency_of_x_wind_due_to_small_scale_gravity_wave_drag + long_name = x wind tendency from small scale gwd units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtauy2d_ss] - standard_name = tendency_of_y_momentum_due_to_small_scale_gravity_wave_drag - long_name = y momentum tendency from small scale gwd + standard_name = tendency_of_y_wind_due_to_small_scale_gravity_wave_drag + long_name = y wind tendency from small scale gwd units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtaux2d_fd] - standard_name = tendency_of_x_momentum_due_to_form_drag - long_name = x momentum tendency from form drag + standard_name = tendency_of_x_wind_due_to_form_drag + long_name = x wind tendency from form drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dtauy2d_fd] - standard_name = tendency_of_y_momentum_due_to_form_drag - long_name = y momentum tendency from form drag + standard_name = tendency_of_y_wind_due_to_form_drag + long_name = y wind tendency from form drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys - intent = out + intent = inout [dusfc] standard_name = instantaneous_x_stress_due_to_gravity_wave_drag long_name = zonal surface stress due to orographic gravity wave drag @@ -341,7 +341,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dvsfc] standard_name = instantaneous_y_stress_due_to_gravity_wave_drag long_name = meridional surface stress due to orographic gravity wave drag @@ -349,23 +349,23 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out -[dusfc_ls] + intent = inout +[dusfc_ms] standard_name = vertically_integrated_x_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag - long_name = integrated x momentum flux from large scale gwd + long_name = integrated x momentum flux from mesoscale gwd units = Pa dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out -[dvsfc_ls] + intent = inout +[dvsfc_ms] standard_name = vertically_integrated_y_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag - long_name = integrated y momentum flux from large scale gwd + long_name = integrated y momentum flux from mesoscale gwd units = Pa dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dusfc_bl] standard_name = vertically_integrated_x_momentum_flux_due_to_blocking_drag long_name = integrated x momentum flux from blocking drag @@ -373,7 +373,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dvsfc_bl] standard_name = vertically_integrated_y_momentum_flux_due_to_blocking_drag long_name = integrated y momentum flux from blocking drag @@ -381,7 +381,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dusfc_ss] standard_name = vertically_integrated_x_momentum_flux_due_to_small_scale_gravity_wave_drag long_name = integrated x momentum flux from small scale gwd @@ -389,7 +389,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dvsfc_ss] standard_name = vertically_integrated_y_momentum_flux_due_to_small_scale_gravity_wave_drag long_name = integrated y momentum flux from small scale gwd @@ -397,7 +397,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dusfc_fd] standard_name = vertically_integrated_x_momentum_flux_due_to_form_drag long_name = integrated x momentum flux from form drag @@ -405,7 +405,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dvsfc_fd] standard_name = vertically_integrated_y_momentum_flux_due_to_form_drag long_name = integrated y momentum flux from form drag @@ -413,7 +413,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [slmsk] standard_name = area_type long_name = landmask: sea/land/ice=0/1/2 @@ -553,21 +553,21 @@ type = integer intent = in [do_gsl_drag_ls_bl] - standard_name = flag_for_gsl_drag_suite_large_scale_orographic_and_blocking_drag - long_name = flag to activate GSL drag suite - large-scale GWD and blocking + standard_name = do_gsl_drag_suite_mesoscale_orographic_and_blocking_drag + long_name = flag to activate GSL drag suite - mesoscale GWD and blocking units = flag dimensions = () type = logical intent = in [do_gsl_drag_ss] - standard_name = flag_for_gsl_drag_suite_small_scale_orographic_drag + standard_name = do_gsl_drag_suite_small_scale_orographic_drag long_name = flag to activate GSL drag suite - small-scale GWD units = flag dimensions = () type = logical intent = in [do_gsl_drag_tofd] - standard_name = flag_for_gsl_drag_suite_turbulent_orographic_form_drag + standard_name = do_gsl_drag_suite_turbulent_orographic_form_drag long_name = flag to activate GSL drag suite - turb orog form drag units = flag dimensions = () @@ -624,6 +624,20 @@ dimensions = () type = logical intent = in +[ldiag_ugwp] + standard_name = flag_for_unified_gravity_wave_physics_diagnostics + long_name = flag for CIRES UGWP Diagnostics + units = flag + dimensions = () + type = logical + intent = in +[ugwp_seq_update] + standard_name = do_ugwp_sequential_update + long_name = flag for ugwp sequential update + units = flag + dimensions = () + type = logical + intent = in [spp_wts_gwd] standard_name = spp_weights_for_gravity_wave_drag_scheme long_name = spp weights for gravity wave drag scheme diff --git a/physics/gcycle.F90 b/physics/gcycle.F90 index 5f4f959c6..16e446b27 100644 --- a/physics/gcycle.F90 +++ b/physics/gcycle.F90 @@ -15,14 +15,14 @@ module gcycle_mod !>\ingroup mod_GFS_phys_time_vary !! This subroutine repopulates specific time-varying surface properties for !! atmospheric forecast runs. - subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, & + subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml, & input_nml_file, lsoil, lsoil_lsm, kice, idate, ialb, isot, ivegsrc, & use_ufo, nst_anl, fhcyc, phour, landfrac, lakefrac, min_seaice, min_lakeice, & frac_grid, smc, slc, stc, smois, sh2o, tslb, tiice, tg3, tref, tsfc, & tsfco, tisfc, hice, fice, facsf, facwf, alvsf, alvwf, alnsf, alnwf, & zorli, zorll, zorlo, weasd, slope, snoalb, canopy, vfrac, vtype, & stype, shdmin, shdmax, snowd, cv, cvb, cvt, oro, oro_uf, & - xlat_d, xlon_d, slmsk, imap, jmap) + xlat_d, xlon_d, slmsk, imap, jmap, errmsg, errflg) ! ! use machine, only: kind_phys, kind_io8 @@ -31,6 +31,7 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, integer, intent(in) :: me, nthrds, nx, ny, isc, jsc, nsst, & tile_num, nlunit, lsoil, lsoil_lsm, kice integer, intent(in) :: idate(:), ialb, isot, ivegsrc + character(len = 64), intent(in) :: fn_nml character(len=*), intent(in) :: input_nml_file(:) logical, intent(in) :: use_ufo, nst_anl, frac_grid real(kind=kind_phys), intent(in) :: fhcyc, phour, landfrac(:), lakefrac(:), & @@ -77,6 +78,9 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, slope(:) integer, intent(in) :: imap(:), jmap(:) + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg + ! ! Local variables ! --------------- @@ -103,6 +107,11 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, real(kind=kind_phys) :: sig1t integer :: npts, nb, ix, jx, ls, ios, ll logical :: exists + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ! @@ -210,13 +219,15 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, enddo ! #ifndef INTERNAL_FILE_NML - inquire (file=trim(Model%fn_nml),exist=exists) + inquire (file=trim(fn_nml),exist=exists) if (.not. exists) then - write(6,*) 'gcycle:: namelist file: ',trim(Model%fn_nml),' does not exist' - stop + write(6,*) 'gcycle:: namelist file: ',trim(fn_nml),' does not exist' + errflg = 1 + errmsg = 'ERROR(gcycle): namelist file: ',trim(fn_nml),' does not exist.' + return else - open (unit=Model%nlunit, file=trim(Model%fn_nml), action='READ', status='OLD', iostat=ios) - rewind (Model%nlunit) + open (unit=nlunit, file=trim(fn_nml), action='READ', status='OLD', iostat=ios) + rewind (nlunit) endif #endif CALL SFCCYCLE (9998, npts, max(lsoil,lsoil_lsm), sig1t, fhcyc, & @@ -233,7 +244,7 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, min_ice, ialb, isot, ivegsrc, & trim(tile_num_ch), i_indx, j_indx) #ifndef INTERNAL_FILE_NML - close (Model%nlunit) + close (nlunit) #endif ! if ( nsst > 0 ) then diff --git a/physics/gfdl_cloud_microphys.F90 b/physics/gfdl_cloud_microphys.F90 index 4e8b3d586..0fd84c7ea 100644 --- a/physics/gfdl_cloud_microphys.F90 +++ b/physics/gfdl_cloud_microphys.F90 @@ -63,7 +63,7 @@ subroutine gfdl_cloud_microphys_init (me, master, nlunit, input_nml_file, loguni return endif - call gfdl_cloud_microphys_mod_init(me, master, nlunit, input_nml_file, logunit, fn_nml) + call gfdl_cloud_microphys_mod_init(me, master, nlunit, input_nml_file, logunit, fn_nml, errmsg, errflg) is_initialized = .true. diff --git a/physics/gfdl_sfc_layer.F90 b/physics/gfdl_sfc_layer.F90 index cf97fc1b6..e235acc52 100644 --- a/physics/gfdl_sfc_layer.F90 +++ b/physics/gfdl_sfc_layer.F90 @@ -1137,7 +1137,7 @@ SUBROUTINE MFLUX2( fxh,fxe,fxmx,fxmy,cdm,rib,xxfh,zoc,mzoc,tstrc, & !m land(i) = 0.0 windmks=wind10p(i)*.01 if ( iwavecpl .eq. 1 ) then - call znot_wind10m(windmks,znott,znotm,icoef_sf) + call znot_wind10m(windmks,znott,znotm,icoef_sf,errmsg,errflg) !Check if Charnock parameter ratio is received in a proper range. if ( alpha(i) .ge. 0.2 .and. alpha(i) .le. 5. ) then znotm = znotm*alpha(i) @@ -1145,7 +1145,7 @@ SUBROUTINE MFLUX2( fxh,fxe,fxmx,fxmy,cdm,rib,xxfh,zoc,mzoc,tstrc, & !m zoc(i) = -100.*znotm zot(i) = -100* znott else - call znot_wind10m(windmks,znott,znotm,icoef_sf) + call znot_wind10m(windmks,znott,znotm,icoef_sf,errmsg,errflg) zoc(i) = -100.*znotm zot(i) = -100* znott endif @@ -1782,7 +1782,7 @@ SUBROUTINE MFLUX2( fxh,fxe,fxmx,fxmy,cdm,rib,xxfh,zoc,mzoc,tstrc, & !m !!! if ( iwavecpl .eq. 1 .and. zoc(i) .le. 0.0 ) then windmks = wind10(i) * 0.01 - call znot_wind10m(windmks,znott,znotm,icoef_sf) + call znot_wind10m(windmks,znott,znotm,icoef_sf,errmsg,errflg) !Check if Charnock parameter ratio is received in a proper range. if ( alpha(i) .ge. 0.2 .and. alpha(i) .le. 5. ) then znotm = znotm*alpha(i) diff --git a/physics/gwdps.f b/physics/gwdps.f index e894104a0..273c2d5dc 100644 --- a/physics/gwdps.f +++ b/physics/gwdps.f @@ -3,6 +3,7 @@ !! drag and mountain blocking. !> This module contains the CCPP-compliant orographic gravity wave dray scheme. +!> This version of gwdps is called from the unified_ugwp CCPP scheme module gwdps contains @@ -194,8 +195,12 @@ subroutine gwdps_run( & & IM,KM,A,B,C,U1,V1,T1,Q1,KPBL, & & PRSI,DEL,PRSL,PRSLK,PHII, PHIL,DELTIM,KDT, & & HPRIME,OC,OA4,CLX4,THETA,SIGMA,GAMMA,ELVMAX, & - & DUSFC,DVSFC,G, CP, RD, RV, IMX, & - & nmtvr, cdmbgwd, me, lprnt, ipr, rdxzb, errmsg, errflg) + & DUSFC,DVSFC,dtaux2d_ms,dtauy2d_ms,dtaux2d_bl, & + & dtauy2d_bl,dusfc_ms,dvsfc_ms,dusfc_bl,dvsfc_bl, & + & G, CP, RD, RV, IMX, & + & nmtvr, cdmbgwd, me, lprnt, ipr, rdxzb, ldiag_ugwp, & + & errmsg, errflg) + ! ! ******************************************************************** ! -----> I M P L E M E N T A T I O N V E R S I O N <---------- @@ -308,10 +313,16 @@ subroutine gwdps_run( & real(kind=kind_phys), intent(inout) :: ELVMAX(:) real(kind=kind_phys), intent(in) :: & & THETA(:), SIGMA(:), GAMMA(:) - real(kind=kind_phys), intent(out) :: DUSFC(:), DVSFC(:), & + real(kind=kind_phys), intent(inout) :: DUSFC(:), DVSFC(:), & & RDXZB(:) + real(kind=kind_phys), intent(inout) :: dtaux2d_ms(:,:), & + & dtauy2d_ms(:,:), dtaux2d_bl(:,:), & + & dtauy2d_bl(:,:) + real(kind=kind_phys), intent(inout) :: dusfc_ms(:), dvsfc_ms(:), & + & dusfc_bl(:), dvsfc_bl(:) integer, intent(in) :: nmtvr logical, intent(in) :: lprnt + logical, intent(in) :: ldiag_ugwp character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg ! @@ -413,10 +424,6 @@ subroutine gwdps_run( & cdmbo4 = 0.25 * cdmb ! npr = 0 - DO I = 1, IM - DUSFC(I) = 0. - DVSFC(I) = 0. - ENDDO ! DO K = 1, KM DO I = 1, IM @@ -1237,8 +1244,15 @@ subroutine gwdps_run( & ! & dbim,idxzb(I),U1(J,K),V1(J,K),me tem1 = DBIM * DEL(J,K) - DUSFC(J) = DUSFC(J) - tem1 * U1(J,K) - DVSFC(J) = DVSFC(J) - tem1 * V1(J,K) + DUSFC(J) = DUSFC(J) + onebg * tem1 * U1(J,K) + DVSFC(J) = DVSFC(J) + onebg * tem1 * V1(J,K) + ! Output blocking tendencies if ldiag_ugwp=.true. + if (ldiag_ugwp) then + dtaux2d_bl(j,k) = - DBIM * U1(J,K) + dtauy2d_bl(j,k) = - DBIM * V1(J,K) + dusfc_bl(j) = dusfc_bl(j) + dtaux2d_bl(j,k) * del(j,k) + dvsfc_bl(j) = dvsfc_bl(j) + dtauy2d_bl(j,k) * del(j,k) + end if else ! orographic GWD applied ! ---------------------- A(J,K) = DTAUY + A(J,K) @@ -1246,8 +1260,15 @@ subroutine gwdps_run( & tem1 = U1(J,K) + DTAUX*DELTIM tem2 = V1(J,K) + DTAUY*DELTIM ENG1 = 0.5 * (tem1*tem1+tem2*tem2) - DUSFC(J) = DUSFC(J) + DTAUX * DEL(J,K) - DVSFC(J) = DVSFC(J) + DTAUY * DEL(J,K) + DUSFC(J) = DUSFC(J) - onebg * DTAUX * DEL(J,K) + DVSFC(J) = DVSFC(J) - onebg * DTAUY * DEL(J,K) + ! Output mesoscale GWD tendencies if ldiag_ugwp=.ture. + if (ldiag_ugwp) then + dtaux2d_ms(j,k) = DTAUX + dtauy2d_ms(j,k) = DTAUY + dusfc_ms(j) = dusfc_ms(j) + DTAUX * del(j,k) + dvsfc_ms(j) = dvsfc_ms(j) + DTAUY * del(j,k) + end if endif C(J,K) = C(J,K) + max(ENG0-ENG1,0.) * oneocpdt ENDDO @@ -1259,12 +1280,16 @@ subroutine gwdps_run( & ! print *,' DB=',DB(ipr,:) ! endif - DO I = 1,npt - J = ipt(i) -! TEM = (-1.E3/G) - DUSFC(J) = - onebg * DUSFC(J) - DVSFC(J) = - onebg * DVSFC(J) - ENDDO + if (ldiag_ugwp) then + ! Finalize dusfc and dvsfc diagnostics + DO i = 1,npt + j = ipt(i) + dusfc_ms(j) = - onebg * dusfc_ms(j) + dvsfc_ms(j) = - onebg * dvsfc_ms(j) + dusfc_bl(j) = - onebg * dusfc_bl(j) + dvsfc_bl(j) = - onebg * dvsfc_bl(j) + ENDDO + end if ! ! MONITOR FOR EXCESSIVE GRAVITY WAVE DRAG TENDENCIES IF NCNT>0 ! diff --git a/physics/gwdps.meta b/physics/gwdps.meta index 3ce1c5b74..af60886ab 100644 --- a/physics/gwdps.meta +++ b/physics/gwdps.meta @@ -218,7 +218,7 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout [dvsfc] standard_name = instantaneous_y_stress_due_to_gravity_wave_drag long_name = meridional surface stress due to orographic gravity wave drag @@ -226,7 +226,71 @@ dimensions = (horizontal_loop_extent) type = real kind = kind_phys - intent = out + intent = inout +[dtaux2d_ms] + standard_name = tendency_of_x_wind_due_to_mesoscale_orographic_gravity_wave_drag + long_name = instantaneous change in x wind due to orographic gw drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dtauy2d_ms] + standard_name = tendency_of_y_wind_due_to_mesoscale_orographic_gravity_wave_drag + long_name = instantaneous change in y wind due to orographic gw drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dtaux2d_bl] + standard_name = tendency_of_x_wind_due_to_blocking_drag + long_name = x wind tendency from blocking drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dtauy2d_bl] + standard_name = tendency_of_y_wind_due_to_blocking_drag + long_name = y wind tendency from blocking drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dusfc_ms] + standard_name = vertically_integrated_x_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = integrated x momentum flux from mesoscale gwd + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dvsfc_ms] + standard_name = vertically_integrated_y_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = integrated y momentum flux from mesoscale gwd + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dusfc_bl] + standard_name = vertically_integrated_x_momentum_flux_due_to_blocking_drag + long_name = integrated x momentum flux from blocking drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dvsfc_bl] + standard_name = vertically_integrated_y_momentum_flux_due_to_blocking_drag + long_name = integrated y momentum flux from blocking drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout [g] standard_name = gravitational_acceleration long_name = gravitational acceleration @@ -310,6 +374,13 @@ type = real kind = kind_phys intent = out +[ldiag_ugwp] + standard_name = flag_for_unified_gravity_wave_physics_diagnostics + long_name = flag for CIRES UGWP Diagnostics + units = flag + dimensions = () + type = logical + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/lsm_noah.f b/physics/lsm_noah.f index 246f81654..836fc3b72 100644 --- a/physics/lsm_noah.f +++ b/physics/lsm_noah.f @@ -61,7 +61,7 @@ subroutine lsm_noah_init(lsm, lsm_noah, me, isot, ivegsrc, nlunit, end if !--- initialize soil vegetation - call set_soilveg(me, isot, ivegsrc, nlunit) + call set_soilveg(me, isot, ivegsrc, nlunit, errmsg, errflg) pores (:) = maxsmc (:) resid (:) = drysmc (:) @@ -220,7 +220,8 @@ subroutine lsm_noah_run & & lheatstrg, isot, ivegsrc, & & bexppert, xlaipert, vegfpert,pertvegf, & ! sfc perts, mgehne & albdvis_lnd, albdnir_lnd, albivis_lnd, albinir_lnd, & - & adjvisbmd, adjnirbmd, adjvisdfd, adjnirdfd, & + & adjvisbmd, adjnirbmd, adjvisdfd, adjnirdfd, rhonewsn1, & + & exticeden, & ! --- in/outs: & weasd, snwdph, tskin, tprcp, srflag, smc, stc, slc, & & canopy, trans, tsurf, zorl, & @@ -252,7 +253,7 @@ subroutine lsm_noah_run & & -1.0_kind_phys, -2.0_kind_phys / ! --- input: - integer, intent(in) :: im, km, isot, ivegsrc + integer, intent(in) :: im, km, isot, ivegsrc real (kind=kind_phys), intent(in) :: grav, cp, hvap, rd, eps, & & epsm1, rvrdm1 real (kind=kind_phys), intent(in) :: pertvegf @@ -265,13 +266,13 @@ subroutine lsm_noah_run & & snoalb, sfalb, zf, & & bexppert, xlaipert, vegfpert, & & albdvis_lnd, albdnir_lnd, albivis_lnd, albinir_lnd, & - & adjvisbmd, adjnirbmd, adjvisdfd, adjnirdfd + & adjvisbmd, adjnirbmd, adjvisdfd, adjnirdfd, rhonewsn1 real (kind=kind_phys), intent(in) :: delt logical, dimension(:), intent(in) :: flag_iter, flag_guess, land - logical, intent(in) :: lheatstrg + logical, intent(in) :: lheatstrg, exticeden ! --- in/out: real (kind=kind_phys), dimension(:), intent(inout) :: weasd, & @@ -292,7 +293,7 @@ subroutine lsm_noah_run & ! --- locals: real (kind=kind_phys), dimension(im) :: rch, rho, & & q0, qs1, theta1, weasd_old, snwdph_old, & - & tprcp_old, srflag_old, tskin_old, canopy_old + & tprcp_old, srflag_old, tskin_old, canopy_old real (kind=kind_phys), dimension(km) :: et, sldpth, stsoil, & & smsoil, slsoil @@ -309,8 +310,8 @@ subroutine lsm_noah_run & & smcdry, smcref, smcmax, sneqv, snoalb1d, snowh, & & snomlt, sncovr, soilw, soilm, ssoil, tsea, th2, tbot, & & xlai, zlvl, swdn, tem, z0, bexpp, xlaip, vegfp, & - & mv, sv, alphav, betav, vegftmp, cpinv, hvapi, elocp - + & mv, sv, alphav, betav, vegftmp, cpinv, hvapi, elocp, & + & rhonewsn integer :: couple, ice, nsoil, nroot, slope, stype, vtype integer :: i, k, iflag ! @@ -326,7 +327,6 @@ subroutine lsm_noah_run & errflg = 0 !> - Save land-related prognostic fields for guess run. - do i = 1, im if (land(i) .and. flag_guess(i)) then weasd_old(i) = weasd(i) @@ -335,7 +335,6 @@ subroutine lsm_noah_run & canopy_old(i) = canopy(i) tprcp_old(i) = tprcp(i) srflag_old(i) = srflag(i) - do k = 1, km smc_old(i,k) = smc(i,k) stc_old(i,k) = stc(i,k) @@ -361,7 +360,6 @@ subroutine lsm_noah_run & sbsno(i) = zero snowc(i) = zero snohf(i) = zero - !> - Initialize variables wind, q, and rh at level 1. q0(i) = max(q1(i), qmin) !* q1=specific humidity at level 1 (kg/kg) @@ -371,7 +369,6 @@ subroutine lsm_noah_run & qs1(i) = fpvs( t1(i) ) !* qs1=sat. humidity at level 1 (kg/kg) qs1(i) = max(eps*qs1(i) / (prsl1(i)+epsm1*qs1(i)), qmin) q0 (i) = min(qs1(i), q0(i)) - do k = 1, km zsoil(i,k) = zsoil_noah(k) enddo @@ -524,7 +521,8 @@ subroutine lsm_noah_run & !> - Apply perturbation of soil type b parameter and leave area index. bexpp = bexppert(i) ! sfc perts, mgehne xlaip = xlaipert(i) ! sfc perts, mgehne - +!> - New snow depth variables + rhonewsn = rhonewsn1(i) !> - Call Noah LSM gfssflx(). call gfssflx & ! ccppdox: these is sflx in mpbl @@ -533,6 +531,7 @@ subroutine lsm_noah_run & & swdn, solnet, lwdn, sfcems, sfcprs, sfctmp, & & sfcspd, prcp, q2, q2sat, dqsdt2, th2, ivegsrc, & & vtype, stype, slope, shdmin1d, alb, snoalb1d, & + & rhonewsn, exticeden, & & bexpp, xlaip, & ! sfc-perts, mgehne & lheatstrg, & ! --- input/outputs: @@ -543,7 +542,8 @@ subroutine lsm_noah_run & & edir, et, ett, esnow, drip, dew, beta, etp, ssoil, & & flx1, flx2, flx3, runoff1, runoff2, runoff3, & & snomlt, sncovr, rc, pc, rsmin, xlai, rcs, rct, rcq, & - & rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax) + & rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax, & + & errmsg, errflg ) !> - Noah LSM: prepare variables for return to parent model and unit conversion. ! - 6. output (o): diff --git a/physics/lsm_noah.meta b/physics/lsm_noah.meta index 2ce7c3e6c..e059a22c6 100644 --- a/physics/lsm_noah.meta +++ b/physics/lsm_noah.meta @@ -486,6 +486,21 @@ type = real kind = kind_phys intent = in +[rhonewsn1] + standard_name = surface_frozen_precipitation_density + long_name = density of precipitation ice + units = kg m-3 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[exticeden] + standard_name = do_external_surface_frozen_precipitation_density + long_name = flag for calculating frozen precip ice density outside of the LSM + units = flag + dimensions = () + type = logical + intent = in [weasd] standard_name = water_equivalent_accumulated_snow_depth_over_land long_name = water equiv of acc snow depth over land diff --git a/physics/lsm_ruc.F90 b/physics/lsm_ruc.F90 index 99b6c2b41..9a1f2ca21 100644 --- a/physics/lsm_ruc.F90 +++ b/physics/lsm_ruc.F90 @@ -159,7 +159,7 @@ subroutine lsm_ruc_init (me, master, isot, ivegsrc, nlunit, & endif !--- initialize soil vegetation - call set_soilveg_ruc(me, isot, ivegsrc, nlunit) + call set_soilveg_ruc(me, isot, ivegsrc, nlunit, errmsg, errflg) pores (:) = maxsmc (:) resid (:) = drysmc (:) @@ -323,15 +323,15 @@ end subroutine lsm_ruc_finalize subroutine lsm_ruc_run & ! inputs & ( iter, me, master, delt, kdt, im, nlev, lsm_ruc, lsm, & & imp_physics, imp_physics_gfdl, imp_physics_thompson, & - & imp_physics_nssl, & - & do_mynnsfclay, lsoil_ruc, lsoil, rdlai, xlat_d, xlon_d, zs,& + & imp_physics_nssl, do_mynnsfclay, exticeden, & + & lsoil_ruc, lsoil, rdlai, xlat_d, xlon_d, zs, & & t1, q1, qc, stype, vtype, sigmaf, laixy, & & dlwflx, dswsfc, tg3, coszen, land, icy, use_lake, & & rainnc, rainc, ice, snow, graupel, & & prsl1, zf, wind, shdmin, shdmax, & & srflag, sfalb_lnd_bck, snoalb, & & isot, ivegsrc, fice, smcwlt2, smcref2, & - & min_lakeice, min_seaice, oceanfrac, & + & min_lakeice, min_seaice, oceanfrac, rhonewsn1, & ! --- constants & con_cp, con_rd, con_rv, con_g, con_pi, con_hvap, & & con_fvirt, & @@ -397,6 +397,7 @@ subroutine lsm_ruc_run & ! inputs logical, dimension(:), intent(in) :: flag_cice logical, intent(in) :: frac_grid logical, intent(in) :: do_mynnsfclay + logical, intent(in) :: exticeden logical, intent(in) :: rdlai @@ -418,7 +419,7 @@ subroutine lsm_ruc_run & ! inputs ! --- in real (kind=kind_phys), dimension(:), intent(in) :: & - & rainnc, rainc, ice, snow, graupel + & rainnc, rainc, ice, snow, graupel, rhonewsn1 ! --- in/out: ! --- on RUC levels real (kind=kind_phys), dimension(:,:), intent(inout) :: & @@ -494,7 +495,8 @@ subroutine lsm_ruc_run & ! inputs & soilt_lnd, tbot, & & xlai, swdn, z0_lnd, znt_lnd, rhosnfr, infiltr, & & precipfr, snfallac_lnd, acsn, & - & qsfc_lnd, qsg_lnd, qvg_lnd, qcg_lnd, soilt1_lnd, chklowq + & qsfc_lnd, qsg_lnd, qvg_lnd, qcg_lnd, soilt1_lnd, chklowq, & + & rhonewsn ! ice real (kind=kind_phys),dimension (im,1) :: & & albbck_ice, alb_ice, chs_ice, flhc_ice, flqc_ice, & @@ -746,7 +748,7 @@ subroutine lsm_ruc_run & ! inputs acrunoff(i,j) = 0.0 snfallac_lnd(i,j) = 0.0 snfallac_ice(i,j) = 0.0 - rhosnfr(i,j) = 0.0 + rhosnfr(i,j) = -1.e3 precipfr(i,j) = 0.0 endif @@ -845,6 +847,7 @@ subroutine lsm_ruc_run & ! inputs rainncv(i,j) = rhoh2o * rainnc(i) ! total time-step explicit precip graupelncv(i,j) = rhoh2o * graupel(i) snowncv(i,j) = rhoh2o * snow(i) + rhonewsn(i,j) = rhonewsn1(i) if (debug_print) then !-- diagnostics for a test point with known lat/lon if (abs(xlat_d(i)-testptlat).lt.2.5 .and. & @@ -1120,12 +1123,12 @@ subroutine lsm_ruc_run & ! inputs & zs, prcp(i,j), sneqv_lnd(i,j), snowh_lnd(i,j), & & sncovr_lnd(i,j), & & ffrozp(i,j), frpcpn, & - & rhosnfr(i,j), precipfr(i,j), & + & rhosnfr(i,j), precipfr(i,j), exticeden, & ! --- inputs: & conflx2(i,1,j), sfcprs(i,1,j), sfctmp(i,1,j), q2(i,1,j), & & qcatm(i,1,j), rho2(i,1,j), semis_bck(i,j), lwdn(i,j), & & swdn(i,j), solnet_lnd(i,j), sfcems_lnd(i,j), chklowq(i,j), & - & chs_lnd(i,j), flqc_lnd(i,j), flhc_lnd(i,j), & + & chs_lnd(i,j), flqc_lnd(i,j), flhc_lnd(i,j), rhonewsn(i,j), & ! --- input/outputs: & wet(i,j), cmc(i,j), shdfac(i,j), alb_lnd(i,j), znt_lnd(i,j), & & z0_lnd(i,j), snoalb1d_lnd(i,j), albbck_lnd(i,j), & @@ -1149,7 +1152,8 @@ subroutine lsm_ruc_run & ! inputs & smfrsoil(i,:,j),keepfrsoil(i,:,j), .false., & & shdmin1d(i,j), shdmax1d(i,j), rdlai2d, & & ims,ime, jms,jme, kms,kme, & - & its,ite, jts,jte, kts,kte ) + & its,ite, jts,jte, kts,kte, & + & errmsg, errflg) if(debug_print) then write (0,*)'after LSMRUC for land' write (0,*)'after sneqv(i,j) =',i,j,sneqv_lnd(i,j) @@ -1394,12 +1398,12 @@ subroutine lsm_ruc_run & ! inputs & zs, prcp(i,j), sneqv_ice(i,j), snowh_ice(i,j), & & sncovr_ice(i,j), & & ffrozp(i,j), frpcpn, & - & rhosnfr(i,j), precipfr(i,j), & + & rhosnfr(i,j), precipfr(i,j), exticeden, & ! --- inputs: & conflx2(i,1,j), sfcprs(i,1,j), sfctmp(i,1,j), q2(i,1,j), & & qcatm(i,1,j), rho2(i,1,j), semis_bck(i,j), lwdn(i,j), & & swdn(i,j), solnet_ice(i,j), sfcems_ice(i,j), chklowq(i,j), & - & chs_ice(i,j), flqc_ice(i,j), flhc_ice(i,j), & + & chs_ice(i,j), flqc_ice(i,j), flhc_ice(i,j), rhonewsn(i,j), & ! --- input/outputs: & wet_ice(i,j), cmc(i,j), shdfac(i,j), alb_ice(i,j), & & znt_ice(i,j), z0_ice(i,j), snoalb1d_ice(i,j), & @@ -1423,7 +1427,8 @@ subroutine lsm_ruc_run & ! inputs & smfrice(i,:,j),keepfrice(i,:,j), .false., & & shdmin1d(i,j), shdmax1d(i,j), rdlai2d, & & ims,ime, jms,jme, kms,kme, & - & its,ite, jts,jte, kts,kte ) + & its,ite, jts,jte, kts,kte, & + & errmsg, errflg) ! Interstitial evap_ice(i) = qfx_ice(i,j) / rho(i) ! kinematic diff --git a/physics/lsm_ruc.meta b/physics/lsm_ruc.meta index 587fda681..0d22f8d4a 100644 --- a/physics/lsm_ruc.meta +++ b/physics/lsm_ruc.meta @@ -634,6 +634,13 @@ dimensions = () type = logical intent = in +[exticeden] + standard_name = do_external_surface_frozen_precipitation_density + long_name = flag for calculating frozen precip ice density outside of the LSM + units = flag + dimensions = () + type = logical + intent = in [lsoil_ruc] standard_name = vertical_dimension_of_soil_internal_to_land_surface_scheme long_name = number of soil layers internal to land surface model @@ -952,6 +959,14 @@ type = real kind = kind_phys intent = in +[rhonewsn1] + standard_name = surface_frozen_precipitation_density + long_name = density of precipitation ice + units = kg m-3 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in [con_cp] standard_name = specific_heat_of_dry_air_at_constant_pressure long_name = specific heat !of dry air at constant pressure @@ -1505,7 +1520,7 @@ kind = kind_phys intent = out [rhosnf] - standard_name = frozen_precipitation_density + standard_name = lsm_internal_surface_frozen_precipitation_density long_name = density of frozen precipitation units = kg m-3 dimensions = (horizontal_loop_extent) diff --git a/physics/m_micro.F90 b/physics/m_micro.F90 index 091ed2020..714372d53 100644 --- a/physics/m_micro.F90 +++ b/physics/m_micro.F90 @@ -123,7 +123,9 @@ subroutine m_micro_init(imp_physics, imp_physics_mg, fprcp, gravit, rair, rh2o, mg_ngcons, mg_ngnst) else write(0,*)' fprcp = ',fprcp,' is not a valid option - aborting' - stop + errflg = 1 + errmsg = 'ERROR(m_micro_init): fprcp is not a valid option' + return endif call aer_cloud_init () diff --git a/physics/maximum_hourly_diagnostics.F90 b/physics/maximum_hourly_diagnostics.F90 index fb3a400e6..cd1016053 100644 --- a/physics/maximum_hourly_diagnostics.F90 +++ b/physics/maximum_hourly_diagnostics.F90 @@ -29,14 +29,17 @@ subroutine maximum_hourly_diagnostics_run(im, levs, reset, lradar, imp_physics, gt0, refl_10cm, refdmax, refdmax263k, u10m, v10m, & u10max, v10max, spd10max, pgr, t2m, q2m, t02max, & t02min, rh02max, rh02min, dtp, rain, pratemax, & - errmsg, errflg) + lightning_threat, ltg1_max,ltg2_max,ltg3_max, & + wgrs, prsi, qgraupel, qsnowwat, qicewat, tgrs, con_rd,& + prsl, kdt, errmsg, errflg) ! Interface variables - integer, intent(in) :: im, levs - logical, intent(in) :: reset, lradar + integer, intent(in) :: im, levs, kdt + logical, intent(in) :: reset, lradar, lightning_threat integer, intent(in) :: imp_physics, imp_physics_gfdl, imp_physics_thompson, imp_physics_fer_hires, & imp_physics_nssl real(kind_phys), intent(in ) :: con_g + real(kind_phys), intent(in ) :: con_rd real(kind_phys), intent(in ) :: phil(:,:) real(kind_phys), intent(in ) :: gt0(:,:) real(kind_phys), intent(in ) :: refl_10cm(:,:) @@ -55,20 +58,30 @@ subroutine maximum_hourly_diagnostics_run(im, levs, reset, lradar, imp_physics, real(kind_phys), intent(inout) :: rh02max(:) real(kind_phys), intent(inout) :: rh02min(:) real(kind_phys), intent(in ) :: dtp - real(kind_phys), intent(in ) :: rain(im) - real(kind_phys), intent(inout) :: pratemax(im) + real(kind_phys), intent(in ) :: rain(:) + real(kind_phys), intent(in ) :: tgrs(:,:) + real(kind_phys), intent(in ) :: prsl(:,:) + real(kind_phys), intent(inout) :: pratemax(:) + + real(kind_phys), intent(in), dimension(:,:) :: prsi, qgraupel, qsnowwat, qicewat, wgrs + real(kind_phys), intent(inout), dimension(:) :: ltg1_max, ltg2_max, ltg3_max character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg ! Local variables real(kind_phys), dimension(:), allocatable :: refd, refd263k - real(kind_phys) :: tem, pshltr, QCQ, rh02 + real(kind_phys) :: tem, pshltr, QCQ, rh02, dP, Q integer :: i ! Initialize CCPP error handling variables errmsg = '' errflg = 0 +!Lightning threat indices + if (lightning_threat) then + call lightning_threat_indices + endif + !Calculate hourly max 1-km agl and -10C reflectivity if (lradar .and. (imp_physics == imp_physics_gfdl .or. & imp_physics == imp_physics_thompson .or. & @@ -134,6 +147,79 @@ subroutine maximum_hourly_diagnostics_run(im, levs, reset, lradar, imp_physics, pratemax(i) = max(pratemax(i),(3.6E6/dtp)*rain(i)) enddo + contains + + subroutine lightning_threat_indices + implicit none + REAL(kind_phys), PARAMETER :: clim1=1.50 + REAL(kind_phys), PARAMETER :: clim2=0.40*1.22 + REAL(kind_phys), PARAMETER :: clim3=0.02*1.22 + ! coef1 and coef2 are modified from the values given + ! in McCaul et al. + ! coef1 is x 1000 x 1.22 + ! coef2 is x 1.22 + ! are these tuning factors, scale factors?? + ! McCaul et al. used a 2-km WRF simulation + REAL(kind_phys), PARAMETER :: coef1=0.042*1000.*1.22 + REAL(kind_phys), PARAMETER :: coef2=0.20*1.22 + + REAL(kind_phys) :: totice_colint(im), ltg1, ltg2, high_ltg1, high_wgrs, high_graupel, rho + LOGICAL :: ltg1_calc(im) + integer :: k, i, count + + count = 0 + high_ltg1 = 0 + high_wgrs = 0 + high_graupel = 0 + + totice_colint = 0 + ltg1_calc = .false. + do k=1,levs-1 + do i=1,im + dP = prsi(i,k) - prsi(i,k+1) + Q = qgraupel(i,k) + qsnowwat(i,k) + qicewat(i,k) + rho = prsl(i,k) / (con_rd * tgrs(i,k)) + totice_colint(i) = totice_colint(i) + Q * rho * dP / con_g + + IF ( .not.ltg1_calc(i) ) THEN + IF ( 0.5*(tgrs(i,k+1) + tgrs(i,k)) < 258.15 ) THEN + count = count + 1 + ltg1_calc(i) = .true. + + ltg1 = coef1*wgrs(i,k)* & + (( qgraupel(i,k+1) + qgraupel(i,k) )*0.5 ) + if(ltg1 > high_ltg1) then + high_ltg1 = ltg1 + high_graupel = qgraupel(i,k) + high_wgrs = wgrs(i,k) + endif + + IF ( ltg1 .LT. clim1 ) ltg1 = 0. + + IF ( ltg1 .GT. ltg1_max(i) ) THEN + ltg1_max(i) = ltg1 + ENDIF + ENDIF + ENDIF + enddo + enddo + + do i=1,im + ltg2 = coef2 * totice_colint(i) + + IF ( ltg2 .LT. clim2 ) ltg2 = 0. + + IF ( ltg2 .GT. ltg2_max(i) ) THEN + ltg2_max(i) = ltg2 + ENDIF + + ltg3_max(i) = 0.95 * ltg1_max(i) + 0.05 * ltg2_max(i) + + IF ( ltg3_max(i) .LT. clim3 ) ltg3_max(i) = 0. + enddo + + end subroutine lightning_threat_indices + end subroutine maximum_hourly_diagnostics_run subroutine max_fields(phil,ref3D,grav,im,levs,refd,tk,refd263k) diff --git a/physics/maximum_hourly_diagnostics.meta b/physics/maximum_hourly_diagnostics.meta index 391dbde52..e9d0876d2 100644 --- a/physics/maximum_hourly_diagnostics.meta +++ b/physics/maximum_hourly_diagnostics.meta @@ -238,6 +238,108 @@ type = real kind = kind_phys intent = inout +[wgrs] + standard_name = unsmoothed_nonhydrostatic_upward_air_velocity + long_name = unsmoothed non-hydrostatic upward air velocity + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[qgraupel] + standard_name = graupel_mixing_ratio + long_name = ratio of mass of graupel to mass of dry air plus vapor (without condensates) + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[qsnowwat] + standard_name = snow_mixing_ratio + long_name = ratio of mass of snow water to mass of dry air plus vapor (without condensates) + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[qicewat] + standard_name = cloud_ice_mixing_ratio + long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[con_rd] + standard_name = gas_constant_of_dry_air + long_name = ideal gas constant for dry air + units = J kg-1 K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[tgrs] + standard_name = air_temperature + long_name = model layer mean temperature + units = K + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[lightning_threat] + standard_name = do_lightning_threat_index_calculations + long_name = enables the lightning threat index calculations + units = flag + dimensions = () + type = logical + intent = in +[ltg1_max] + standard_name = lightning_threat_index_1 + long_name = lightning threat index 1 + units = flashes 5 min-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[ltg2_max] + standard_name = lightning_threat_index_2 + long_name = lightning threat index 2 + units = flashes 5 min-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[ltg3_max] + standard_name = lightning_threat_index_3 + long_name = lightning threat index 3 + units = flashes 5 min-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[prsi] + standard_name = air_pressure_at_interface + long_name = air pressure at model layer interfaces + units = Pa + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[prsl] + standard_name = air_pressure + long_name = mean layer pressure + units = Pa + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[kdt] + standard_name = index_of_timestep + long_name = current forecast iteration + units = index + dimensions = () + type = integer + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/module_SF_JSFC.F90 b/physics/module_SF_JSFC.F90 index 8d67a81cd..fdf188b96 100644 --- a/physics/module_SF_JSFC.F90 +++ b/physics/module_SF_JSFC.F90 @@ -122,7 +122,7 @@ SUBROUTINE JSFC(FLAG_ITER,ITER,ME & & ,A1U,A1T,A1Q & & ,IDS,IDE,JDS,JDE,KDS,KDE & & ,IMS,IME,JMS,JME,KMS,KME & - & ,ITS,ITE,JTS,JTE,KTS,LM) + & ,ITS,ITE,JTS,JTE,KTS,LM,errmsg,errflg) ! !----------------------------------------------------------------------- ! SUBROUTINE JSFC(NTSD,EPSQ2,HT,DZ & @@ -182,6 +182,8 @@ SUBROUTINE JSFC(FLAG_ITER,ITER,ME & REAL(kind=kfpt),DIMENSION(IMS:IME,JMS:JME),INTENT(OUT) :: CM,CH,STRESS,FFM & & ,FFH,WIND,FM10,FH2 & & ,A1U,A1T,A1Q + character(len=*),intent(out) :: errmsg + integer, intent(out) :: errflg ! ! REAL(kind=kfpt),DIMENSION(IMS:IME,JMS:JME),INTENT(OUT) :: CHS,CHS2,CQS2 & ! & ,CPM,CT,FLHC,FLQC & @@ -215,6 +217,9 @@ SUBROUTINE JSFC(FLAG_ITER,ITER,ME & ! !---------------------------------------------------------------------- !********************************************************************** + ! Initialize error-handling + errflg = 0 + errmsg = '' !---------------------------------------------------------------------- ! !*** MAKE PREPARATIONS @@ -390,7 +395,8 @@ SUBROUTINE JSFC(FLAG_ITER,ITER,ME & & ,A1U(I,J),A1T(I,J),A1Q(I,J) & & ,IDS,IDE,JDS,JDE,KDS,KDE & & ,IMS,IME,JMS,JME,KMS,KME & - & ,ITS,ITE,JTS,JTE,KTS,LM,I,J,ZHK(LMH+1),RIB(I,J)) ! Added Bulk Richardson No. + & ,ITS,ITE,JTS,JTE,KTS,LM,I,J,ZHK(LMH+1),RIB(I,J) & ! Added Bulk Richardson No. + & ,errmsg, errflg) ! !*** REMOVE SUPERATURATION AT 2M AND 10M ! @@ -454,7 +460,8 @@ SUBROUTINE SFCDIF(NTSD,SEAMASK,THS,QS,PSFC & & ,FFM,FFH,FM10,FH2,A1U,A1T,A1Q & & ,IDS,IDE,JDS,JDE,KDS,KDE & & ,IMS,IME,JMS,JME,KMS,KME & - & ,ITS,ITE,JTS,JTE,KTS,LM,I,J,ZSFC,RIB) ! Added Bulk Richardson No. + & ,ITS,ITE,JTS,JTE,KTS,LM,I,J,ZSFC,RIB & ! Added Bulk Richardson No. + & ,errmsg, errflg) ! **************************************************************** ! * * ! * SURFACE LAYER * @@ -481,6 +488,8 @@ SUBROUTINE SFCDIF(NTSD,SEAMASK,THS,QS,PSFC & REAL(kind=kfpt),INTENT(OUT) :: FFM,FFH,FM10,FH2,A1U,A1T,A1Q ! REAL(kind=kfpt),INTENT(INOUT) :: AKHS,AKMS,QZ0,THZ0,USTAR,UZ0,VZ0,Z0,QS + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg !---------------------------------------------------------------------- !*** !*** LOCAL VARIABLES @@ -507,6 +516,10 @@ SUBROUTINE SFCDIF(NTSD,SEAMASK,THS,QS,PSFC & !---------------------------------------------------------------------- !********************************************************************** !---------------------------------------------------------------------- + ! Initialize error-handling + errflg = 0 + errmsg = '' + RDZ=1./ZSL CXCHL=EXCML*RDZ CXCHS=EXCMS*RDZ @@ -701,7 +714,9 @@ SUBROUTINE SFCDIF(NTSD,SEAMASK,THS,QS,PSFC & print*,'PSIH1(1,2),RDZT=',PSIH1(K+1),PSIH1(K+2),RDZT print*,'ZSLU,ZSLT,RLMO,ZU,ZT=',ZSLU,ZSLT,RLMO,ZU,ZT print*,'A,B,DTHV,DU2,RIB=',A,B,DTHV,DU2,RIB - stop + errflg = 1 + errmsg = 'ERROR(SFCDIF): ' + return end if diff --git a/physics/module_bl_mynn.F90 b/physics/module_bl_mynn.F90 index ffb4b5696..51a906faf 100644 --- a/physics/module_bl_mynn.F90 +++ b/physics/module_bl_mynn.F90 @@ -121,7 +121,7 @@ ! Hybrid PBL height diagnostic, which blends a theta-v-based ! definition in neutral/convective BL and a TKE-based definition ! in stable conditions. -! TKE budget output option (bl_mynn_tkebudget) +! TKE budget output option ! v3.5.0: TKE advection option (bl_mynn_tkeadvect) ! v3.5.1: Fog deposition related changes. ! v3.6.0: Removed fog deposition from the calculation of tendencies @@ -216,14 +216,14 @@ ! Misc small-impact bugfixes: ! 1) dz was incorrectly indexed in mym_condensation ! 2) configurations with icloud_bl = 0 were using uninitialized arrays -! v4.4 / CCPP +! v4.5 / CCPP ! This version includes many modifications that proved valuable in the global ! framework and removes some key lingering bugs in the mixing of chemical species. ! TKE Budget output fixed (Puhales, 2020-12) ! New option for stability function: (Puhales, 2020-12) ! bl_mynn_stfunc = 0 (original, Kansas-type function, Paulson, 1970 ) ! bl_mynn_stfunc = 1 (expanded range, same as used for Jimenez et al (MWR) -! see the Technical Note for this implementation. +! see the Technical Note for this implementation (small impact). ! Improved conservation of momentum and higher-order moments. ! Important bug fixes for mixing of chemical species. ! Addition of pressure-gradient effects on updraft momentum transport. @@ -248,62 +248,53 @@ MODULE module_bl_mynn xlvcp , tv0 , tv1 , tref , & zero , half , one , two , & onethird , twothirds , tkmin , t0c , & - tice + tice , kind_phys IMPLICIT NONE -!get rid - INTEGER , PARAMETER :: param_first_scalar = 1, & - & p_qc = 2, & - & p_qr = 0, & - & p_qi = 2, & - & p_qs = 0, & - & p_qg = 0, & - & p_qnc= 0, & - & p_qni= 0 - !=================================================================== ! From here on, these are MYNN-specific parameters: ! The parameters below depend on stability functions of module_sf_mynn. - REAL, PARAMETER :: cphm_st=5.0, cphm_unst=16.0, & - cphh_st=5.0, cphh_unst=16.0 + real(kind_phys), PARAMETER :: cphm_st=5.0, cphm_unst=16.0, & + cphh_st=5.0, cphh_unst=16.0 ! Closure constants - REAL, PARAMETER :: & - &pr = 0.74, & - &g1 = 0.235, & ! NN2009 = 0.235 - &b1 = 24.0, & - &b2 = 15.0, & ! CKmod NN2009 - &c2 = 0.729, & ! 0.729, & !0.75, & - &c3 = 0.340, & ! 0.340, & !0.352, & - &c4 = 0.0, & - &c5 = 0.2, & + real(kind_phys), PARAMETER :: & + &pr = 0.74, & + &g1 = 0.235, & ! NN2009 = 0.235 + &b1 = 24.0, & + &b2 = 15.0, & ! CKmod NN2009 + &c2 = 0.729, & ! 0.729, & !0.75, & + &c3 = 0.340, & ! 0.340, & !0.352, & + &c4 = 0.0, & + &c5 = 0.2, & &a1 = b1*( 1.0-3.0*g1 )/6.0, & ! &c1 = g1 -1.0/( 3.0*a1*b1**(1.0/3.0) ), & &c1 = g1 -1.0/( 3.0*a1*2.88449914061481660), & &a2 = a1*( g1-c1 )/( g1*pr ), & &g2 = b2/b1*( 1.0-c3 ) +2.0*a1/b1*( 3.0-2.0*c2 ) - REAL, PARAMETER :: & - &cc2 = 1.0-c2, & - &cc3 = 1.0-c3, & - &e1c = 3.0*a2*b2*cc3, & - &e2c = 9.0*a1*a2*cc2, & + real(kind_phys), PARAMETER :: & + &cc2 = 1.0-c2, & + &cc3 = 1.0-c3, & + &e1c = 3.0*a2*b2*cc3, & + &e2c = 9.0*a1*a2*cc2, & &e3c = 9.0*a2*a2*cc2*( 1.0-c5 ), & - &e4c = 12.0*a1*a2*cc2, & + &e4c = 12.0*a1*a2*cc2, & &e5c = 6.0*a1*a1 ! Constants for min tke in elt integration (qmin), max z/L in els (zmax), ! and factor for eddy viscosity for TKE (Kq = Sqfac*Km): - REAL, PARAMETER :: qmin=0.0, zmax=1.0, Sqfac=3.0 + real(kind_phys), PARAMETER :: qmin=0.0, zmax=1.0, Sqfac=3.0 ! Note that the following mixing-length constants are now specified in mym_length ! &cns=3.5, alp1=0.23, alp2=0.3, alp3=3.0, alp4=10.0, alp5=0.2 - REAL, PARAMETER :: gpw=5./3., qcgmin=1.e-8, qkemin=1.e-12 + real(kind_phys), PARAMETER :: gpw=5./3., qcgmin=1.e-8, qkemin=1.e-12 + real(kind_phys), PARAMETER :: tliq = 269. !all hydrometeors are liquid when T > tliq ! Constants for cloud PDF (mym_condensation) - REAL, PARAMETER :: rr2=0.7071068, rrp=0.3989423 + real(kind_phys), PARAMETER :: rr2=0.7071068, rrp=0.3989423 !>Use Canuto/Kitamura mod (remove Ric and negative TKE) (1:yes, 0:no) !!For more info, see Canuto et al. (2008 JAS) and Kitamura (Journal of the @@ -313,12 +304,12 @@ MODULE module_bl_mynn !!(above) back to NN2009 values (see commented out lines next to the !!parameters above). This only removes the negative TKE problem !!but does not necessarily improve performance - neutral impact. - REAL, PARAMETER :: CKmod=1. + real(kind_phys), PARAMETER :: CKmod=1. !>Use Ito et al. (2015, BLM) scale-aware (0: no, 1: yes). Note that this also has impacts !!on the cloud PDF and mass-flux scheme, using Honnert et al. (2011) similarity function !!for TKE in the upper PBL/cloud layer. - REAL, PARAMETER :: scaleaware=1. + real(kind_phys), PARAMETER :: scaleaware=1. !>Of the following the options, use one OR the other, not both. !>Adding top-down diffusion driven by cloud-top radiative cooling @@ -340,32 +331,6 @@ MODULE module_bl_mynn LOGICAL, PARAMETER :: debug_code = .false. INTEGER, PARAMETER :: idbg = 23 !specific i-point to write out -! JAYMES- -!> Constants used for empirical calculations of saturation -!! vapor pressures (in function "esat") and saturation mixing ratios -!! (in function "qsat"), reproduced from module_mp_thompson.F, -!! v3.6 - REAL, PARAMETER:: J0= .611583699E03 - REAL, PARAMETER:: J1= .444606896E02 - REAL, PARAMETER:: J2= .143177157E01 - REAL, PARAMETER:: J3= .264224321E-1 - REAL, PARAMETER:: J4= .299291081E-3 - REAL, PARAMETER:: J5= .203154182E-5 - REAL, PARAMETER:: J6= .702620698E-8 - REAL, PARAMETER:: J7= .379534310E-11 - REAL, PARAMETER:: J8=-.321582393E-13 - - REAL, PARAMETER:: K0= .609868993E03 - REAL, PARAMETER:: K1= .499320233E02 - REAL, PARAMETER:: K2= .184672631E01 - REAL, PARAMETER:: K3= .402737184E-1 - REAL, PARAMETER:: K4= .565392987E-3 - REAL, PARAMETER:: K5= .521693933E-5 - REAL, PARAMETER:: K6= .307839583E-7 - REAL, PARAMETER:: K7= .105785160E-9 - REAL, PARAMETER:: K8= .161444444E-12 -! end- - ! Used in WRF-ARW module_physics_init.F INTEGER :: mynn_level @@ -373,7 +338,7 @@ MODULE module_bl_mynn CONTAINS ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine is the GSD MYNN-EDNF PBL driver routine,which !! encompassed the majority of the subroutines that comprise the !! procedures that ultimately solve for tendencies of @@ -383,35 +348,32 @@ MODULE module_bl_mynn SUBROUTINE mynn_bl_driver( & &initflag,restart,cycling, & &delt,dz,dx,znt, & - &u,v,w,th,sqv3D,sqc3D,sqi3D, & - &qnc,qni, & - &qnwfa,qnifa,ozone, & - &p,exner,rho,T3D, & + &u,v,w,th,sqv3d,sqc3d,sqi3d, & + &sqs3d,qnc,qni, & + &qnwfa,qnifa,qnbca,ozone, & + &p,exner,rho,t3d, & &xland,ts,qsfc,ps, & &ust,ch,hfx,qfx,rmol,wspd, & &uoce,voce, & !ocean current - &vdfg, & !Katata-added for fog dep - &Qke,qke_adv, & + &qke,qke_adv, & &sh3d,sm3d, & - &nchem,kdvel,ndvel, & !Smoke/Chem variables - &chem3d, vdep, & - &frp,EMIS_ANT_NO, & ! JLS/RAR to adjust exchange coeffs - &mix_chem,fire_turb,rrfs_smoke, & ! end smoke/chem variables - - &Tsq,Qsq,Cov, & - &RUBLTEN,RVBLTEN,RTHBLTEN, & - &RQVBLTEN,RQCBLTEN,RQIBLTEN, & - &RQNCBLTEN,RQNIBLTEN, & - &RQNWFABLTEN,RQNIFABLTEN, & - &DOZONE, & + &chem3d,vdep,smoke_dbg, & + &frp,emis_ant_no, & ! JLS/RAR to adjust exchange coeffs + &mix_chem,enh_mix,rrfs_sd, & ! end smoke/chem variables + &tsq,qsq,cov, & + &rublten,rvblten,rthblten, & + &rqvblten,rqcblten,rqiblten, & + &rqncblten,rqniblten,rqsblten, & + &rqnwfablten,rqnifablten, & + &rqnbcablten,dozone, & &exch_h,exch_m, & - &Pblh,kpbl, & + &pblh,kpbl, & &el_pbl, & - &dqke,qWT,qSHEAR,qBUOY,qDISS, & + &dqke,qwt,qshear,qbuoy,qdiss, & &qc_bl,qi_bl,cldfra_bl, & &bl_mynn_tkeadvect, & - &bl_mynn_tkebudget, & + &tke_budget, & &bl_mynn_cloudpdf, & &bl_mynn_mixlength, & &icloud_bl, & @@ -428,20 +390,21 @@ SUBROUTINE mynn_bl_driver( & &det_thl3D,det_sqv3D, & &nupdraft,maxMF,ktop_plume, & &spp_pbl,pattern_spp_pbl, & - &RTHRATEN, & + &rthraten, & &FLAG_QC,FLAG_QI,FLAG_QNC, & - &FLAG_QNI,FLAG_QNWFA,FLAG_QNIFA, & - &FLAG_OZONE & - &,IDS,IDE,JDS,JDE,KDS,KDE & - &,IMS,IME,JMS,JME,KMS,KME & - &,ITS,ITE,JTS,JTE,KTS,KTE) + &FLAG_QNI,FLAG_QS, & + &FLAG_QNWFA,FLAG_QNIFA, & + &FLAG_QNBCA,FLAG_OZONE, & + &IDS,IDE,JDS,JDE,KDS,KDE, & + &IMS,IME,JMS,JME,KMS,KME, & + &ITS,ITE,JTS,JTE,KTS,KTE ) !------------------------------------------------------------------- INTEGER, INTENT(in) :: initflag !INPUT NAMELIST OPTIONS: - LOGICAL, INTENT(IN) :: restart,cycling - LOGICAL, INTENT(in) :: bl_mynn_tkebudget + LOGICAL, INTENT(in) :: restart,cycling + INTEGER, INTENT(in) :: tke_budget INTEGER, INTENT(in) :: bl_mynn_cloudpdf INTEGER, INTENT(in) :: bl_mynn_mixlength INTEGER, INTENT(in) :: bl_mynn_edmf @@ -453,17 +416,18 @@ SUBROUTINE mynn_bl_driver( & INTEGER, INTENT(in) :: bl_mynn_cloudmix INTEGER, INTENT(in) :: bl_mynn_mixqt INTEGER, INTENT(in) :: icloud_bl - REAL, INTENT(in) :: closure + real(kind_phys), INTENT(in) :: closure LOGICAL, INTENT(in) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QNC,& - FLAG_QNWFA,FLAG_QNIFA,FLAG_OZONE + FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA, & + FLAG_OZONE,FLAG_QS - LOGICAL, INTENT(IN) :: mix_chem,fire_turb,rrfs_smoke + LOGICAL, INTENT(IN) :: mix_chem,enh_mix,rrfs_sd,smoke_dbg - INTEGER, INTENT(in) :: & - & IDS,IDE,JDS,JDE,KDS,KDE & - &,IMS,IME,JMS,JME,KMS,KME & - &,ITS,ITE,JTS,JTE,KTS,KTE + INTEGER, INTENT(in) :: & + & IDS,IDE,JDS,JDE,KDS,KDE & + &,IMS,IME,JMS,JME,KMS,KME & + &,ITS,ITE,JTS,JTE,KTS,KTE #ifdef HARDCODE_VERTICAL # define kts 1 @@ -480,146 +444,166 @@ SUBROUTINE mynn_bl_driver( & ! to prevent a crash on Cheyenne. Do not change it back without testing if the code runs ! on Cheyenne with the GNU compiler. - REAL, INTENT(in) :: delt - REAL, DIMENSION(:), INTENT(in) :: dx - REAL, DIMENSION(:,:), INTENT(in) :: dz, & + real(kind_phys), INTENT(in) :: delt + real(kind_phys), DIMENSION(:), INTENT(in) :: dx + real(kind_phys), DIMENSION(:,:), INTENT(in) :: dz, & &u,v,w,th,sqv3D,p,exner,rho,T3D - REAL, DIMENSION(:,:), INTENT(in):: & - &sqc3D,sqi3D,qni,qnc,qnwfa,qnifa - REAL, DIMENSION(:,:), INTENT(in):: ozone - REAL, DIMENSION(:), INTENT(in) :: xland,ust, & - &ch,ts,qsfc,ps,hfx,qfx,wspd,uoce,voce,vdfg,znt - - REAL, DIMENSION(:,:), INTENT(inout) :: & + real(kind_phys), DIMENSION(:,:), INTENT(in) :: & + &sqc3D,sqi3D,sqs3D,qni,qnc,qnwfa,qnifa,qnbca + real(kind_phys), DIMENSION(:,:), INTENT(in):: ozone + real(kind_phys), DIMENSION(:), INTENT(in):: ust, & + &ch,qsfc,ps,wspd + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & &Qke,Tsq,Qsq,Cov,qke_adv + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & + &rublten,rvblten,rthblten,rqvblten,rqcblten, & + &rqiblten,rqsblten,rqniblten,rqncblten, & + &rqnwfablten,rqnifablten,rqnbcablten + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: dozone + real(kind_phys), DIMENSION(:,:), INTENT(in) :: rthraten - REAL, DIMENSION(:,:), INTENT(inout) :: & - &RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN,RQCBLTEN, & - &RQIBLTEN,RQNIBLTEN,RQNCBLTEN, & - &RQNWFABLTEN,RQNIFABLTEN - REAL, DIMENSION(:,:), INTENT(inout) :: DOZONE - - REAL, DIMENSION(:,:), INTENT(in) :: RTHRATEN - - REAL, DIMENSION(:,:), INTENT(out) :: & - &exch_h,exch_m + real(kind_phys), DIMENSION(:,:), INTENT(out) :: exch_h,exch_m + real(kind_phys), DIMENSION(:), INTENT(in) :: xland, & + &ts,znt,hfx,qfx,uoce,voce !These 10 arrays are only allocated when bl_mynn_output > 0 - REAL, DIMENSION(:,:), INTENT(inout) :: & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & & edmf_a,edmf_w,edmf_qt,edmf_thl,edmf_ent,edmf_qc, & & sub_thl3D,sub_sqv3D,det_thl3D,det_sqv3D -! REAL, DIMENSION(IMS:IME,KMS:KME) :: & +! real, DIMENSION(IMS:IME,KMS:KME) :: & ! & edmf_a_dd,edmf_w_dd,edmf_qt_dd,edmf_thl_dd,edmf_ent_dd,edmf_qc_dd - REAL, DIMENSION(:), INTENT(inout) :: Pblh,rmol + real(kind_phys), DIMENSION(:), INTENT(inout) :: Pblh + real(kind_phys), DIMENSION(:), INTENT(inout) :: rmol - REAL, DIMENSION(IMS:IME) :: Psig_bl,Psig_shcu + real(kind_phys), DIMENSION(IMS:IME) :: psig_bl,psig_shcu - INTEGER,DIMENSION(:),INTENT(INOUT) :: & + INTEGER,DIMENSION(:),INTENT(INOUT) :: & &KPBL,nupdraft,ktop_plume - REAL, DIMENSION(:), INTENT(OUT) :: & - &maxmf + real(kind_phys), DIMENSION(:), INTENT(out) :: maxmf - REAL, DIMENSION(:,:), INTENT(inout) :: & - &el_pbl + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: el_pbl - REAL, DIMENSION(:,:), INTENT(out) :: & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & &qWT,qSHEAR,qBUOY,qDISS,dqke - ! 3D budget arrays are not allocated when bl_mynn_tkebudget == .false. + ! 3D budget arrays are not allocated when tke_budget == 0 ! 1D (local) budget arrays are used for passing between subroutines. - REAL, DIMENSION(kts:kte) :: qWT1,qSHEAR1,qBUOY1,qDISS1,dqke1,diss_heat + real(kind_phys), DIMENSION(kts:kte) :: & + &qwt1,qshear1,qbuoy1,qdiss1,dqke1,diss_heat - REAL, DIMENSION(:,:), intent(out) :: Sh3D,Sm3D + real(kind_phys), DIMENSION(:,:), intent(out) :: Sh3D,Sm3D - REAL, DIMENSION(:,:), INTENT(inout) :: & + real(kind_phys), DIMENSION(:,:), INTENT(inout) :: & &qc_bl,qi_bl,cldfra_bl - REAL, DIMENSION(KTS:KTE) :: qc_bl1D,qi_bl1D,cldfra_bl1D,& - qc_bl1D_old,qi_bl1D_old,cldfra_bl1D_old + real(kind_phys), DIMENSION(KTS:KTE) :: qc_bl1D,qi_bl1D, & + &cldfra_bl1D,qc_bl1D_old,qi_bl1D_old,cldfra_bl1D_old ! smoke/chemical arrays INTEGER, INTENT(IN ) :: nchem, kdvel, ndvel -! REAL, DIMENSION( ims:ime, kms:kme, nchem ), INTENT(INOUT), optional :: chem3d -! REAL, DIMENSION( ims:ime, kdvel, ndvel ), INTENT(IN), optional :: vdep - REAL, DIMENSION(:, :, :), INTENT(INOUT) :: chem3d - REAL, DIMENSION(:, :), INTENT(IN) :: vdep - REAL, DIMENSION(:), INTENT(IN) :: frp,EMIS_ANT_NO + real(kind_phys), DIMENSION(:,:,:), INTENT(INOUT) :: chem3d + real(kind_phys), DIMENSION(:,:), INTENT(IN) :: vdep + real(kind_phys), DIMENSION(:), INTENT(IN) :: frp,EMIS_ANT_NO !local - REAL, DIMENSION(kts:kte ,nchem) :: chem1 - REAL, DIMENSION(kts:kte+1,nchem) :: s_awchem1 - REAL, DIMENSION(ndvel) :: vd1 + real(kind_phys), DIMENSION(kts:kte ,nchem) :: chem1 + real(kind_phys), DIMENSION(kts:kte+1,nchem) :: s_awchem1 + real(kind_phys), DIMENSION(ndvel) :: vd1 INTEGER :: ic !local vars INTEGER :: ITF,JTF,KTF, IMD,JMD - INTEGER :: i,j,k - REAL, DIMENSION(KTS:KTE) :: thl,thvl,tl,qv1,qc1,qi1,sqw,& - &El, Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, & - &Vt, Vq, sgm, thlsg, sqwsg - REAL, DIMENSION(KTS:KTE) :: thetav,sh,sm,u1,v1,w1,p1, & + INTEGER :: i,j,k,kproblem + real(kind_phys), DIMENSION(KTS:KTE) :: & + &thl,tl,qv1,qc1,qi1,qs1,sqw, & + &el, dfm, dfh, dfq, tcd, qcd, pdk, pdt, pdq, pdc, & + &vt, vq, sgm + real(kind_phys), DIMENSION(KTS:KTE) :: & + &thetav,sh,sm,u1,v1,w1,p1, & &ex1,dz1,th1,tk1,rho1,qke1,tsq1,qsq1,cov1, & - &sqv,sqi,sqc,du1,dv1,dth1,dqv1,dqc1,dqi1,ozone1, & + &sqv,sqi,sqc,sqs, & + &du1,dv1,dth1,dqv1,dqc1,dqi1,dqs1,ozone1, & &k_m1,k_h1,qni1,dqni1,qnc1,dqnc1,qnwfa1,qnifa1, & - &dqnwfa1,dqnifa1,dozone1 + &qnbca1,dqnwfa1,dqnifa1,dqnbca1,dozone1 !mass-flux variables - REAL, DIMENSION(KTS:KTE) :: dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf - REAL, DIMENSION(KTS:KTE) :: edmf_a1,edmf_w1,edmf_qt1, & - &edmf_thl1,edmf_ent1,edmf_qc1 - REAL, DIMENSION(KTS:KTE) :: edmf_a_dd1,edmf_w_dd1, & - &edmf_qt_dd1,edmf_thl_dd1, & + real(kind_phys), DIMENSION(KTS:KTE) :: & + &dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf + real(kind_phys), DIMENSION(KTS:KTE) :: & + &edmf_a1,edmf_w1,edmf_qt1,edmf_thl1, & + &edmf_ent1,edmf_qc1 + real(kind_phys), DIMENSION(KTS:KTE) :: & + &edmf_a_dd1,edmf_w_dd1,edmf_qt_dd1,edmf_thl_dd1, & &edmf_ent_dd1,edmf_qc_dd1 - REAL, DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v,& - det_thl,det_sqv,det_sqc,det_u,det_v - REAL,DIMENSION(KTS:KTE+1) :: s_aw1,s_awthl1,s_awqt1, & - s_awqv1,s_awqc1,s_awu1,s_awv1,s_awqke1, & - s_awqnc1,s_awqni1,s_awqnwfa1,s_awqnifa1 - REAL,DIMENSION(KTS:KTE+1) :: sd_aw1,sd_awthl1,sd_awqt1, & - sd_awqv1,sd_awqc1,sd_awu1,sd_awv1,sd_awqke1 - - REAL, DIMENSION(KTS:KTE+1) :: zw - REAL :: cpm,sqcg,flt,fltv,flq,flqv,flqc,pmz,phh,exnerg,zet,phi_m,& - & afk,abk,ts_decay, qc_bl2, qi_bl2, & - & th_sfc,ztop_plume,sqc9,sqi9 + real(kind_phys), DIMENSION(KTS:KTE) :: & + &sub_thl,sub_sqv,sub_u,sub_v, & + &det_thl,det_sqv,det_sqc,det_u,det_v + real(kind_phys), DIMENSION(KTS:KTE+1) :: & + &s_aw1,s_awthl1,s_awqt1, & + &s_awqv1,s_awqc1,s_awu1,s_awv1,s_awqke1, & + &s_awqnc1,s_awqni1,s_awqnwfa1,s_awqnifa1, & + &s_awqnbca1 + real(kind_phys), DIMENSION(KTS:KTE+1) :: & + &sd_aw1,sd_awthl1,sd_awqt1, & + &sd_awqv1,sd_awqc1,sd_awu1,sd_awv1,sd_awqke1 + + real(kind_phys), DIMENSION(KTS:KTE+1) :: zw + real(kind_phys) :: cpm,sqcg,flt,fltv,flq,flqv,flqc, & + &pmz,phh,exnerg,zet,phi_m, & + &afk,abk,ts_decay, qc_bl2, qi_bl2, & + &th_sfc,ztop_plume,wsp !top-down diffusion - REAL, DIMENSION(ITS:ITE) :: maxKHtopdown - REAL,DIMENSION(KTS:KTE) :: KHtopdown,TKEprodTD + real(kind_phys), DIMENSION(ITS:ITE) :: maxKHtopdown + real(kind_phys), DIMENSION(KTS:KTE) :: KHtopdown,TKEprodTD - LOGICAL :: INITIALIZE_QKE + LOGICAL :: INITIALIZE_QKE,problem ! Stochastic fields - INTEGER, INTENT(IN) ::spp_pbl - REAL, DIMENSION( :, :), INTENT(IN) ::pattern_spp_pbl - REAL, DIMENSION(KTS:KTE) ::rstoch_col + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(:,:), INTENT(IN) :: pattern_spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col ! Substepping TKE INTEGER :: nsub - real :: delt2 - - IF ( debug_code ) THEN - if (idbg .lt. ime) then - print*,'in MYNN driver; at beginning' - print*," th(1:5)=",th(idbg,1:5) - print*," u(1:5)=",u(idbg,1:5) - print*," v(1:5)=",v(idbg,1:5) - print*," w(1:5)=",w(idbg,1:5) - print*," sqv(1:5)=",sqv3D(idbg,1:5) - print*," p(1:5)=",p(idbg,1:5) - print*," rho(1:5)=",rho(idbg,1:5) - print*," xland=",xland(idbg)," u*=",ust(idbg), & - &" ts=",ts(idbg)," qsfc=",qsfc(idbg), & - &" z/L=",0.5*dz(idbg,1)*rmol(idbg)," ps=",ps(idbg),& - &" hfx=",hfx(idbg)," qfx=",qfx(idbg), & - &" wspd=",wspd(idbg)," znt=",znt(idbg) - endif - ENDIF + real(kind_phys) :: delt2 + + + if (debug_code) then !check incoming values + do i=its,ite + problem = .false. + do k=kts,kte + wsp = sqrt(u(i,k)**2 + v(i,k)**2) + if (abs(hfx(i)) > 1200. .or. abs(qfx(i)) > 0.001 .or. & + wsp > 200. .or. t3d(i,k) > 360. .or. t3d(i,k) < 160. .or. & + sqv3d(i,k)< 0.0 .or. sqc3d(i,k)< 0.0 ) then + kproblem = k + problem = .true. + print*,"Incoming problem at: i=",i," k=1" + print*," QFX=",qfx(i)," HFX=",hfx(i) + print*," wsp=",wsp," T=",t3d(i,k) + print*," qv=",sqv3d(i,k)," qc=",sqc3d(i,k) + print*," u*=",ust(i)," wspd=",wspd(i) + print*," xland=",xland(i)," ts=",ts(i) + print*," z/L=",0.5*dz(i,1)*rmol(i)," ps=",ps(i) + print*," znt=",znt(i)," dx=",dx(i) + endif + enddo + if (problem) then + print*,"===tk:",t3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qv:",sqv3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qc:",sqc3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qi:",sqi3d(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====u:",u(i,max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====v:",v(i,max(kproblem-3,1):min(kproblem+3,kte)) + endif + enddo + endif !*** Begin debugging IMD=(IMS+IME)/2 JMD=(JMS+JME)/2 -!*** End debugging +!*** End debugging JTF=JTE ITF=ITE @@ -691,6 +675,7 @@ SUBROUTINE mynn_bl_driver( & dqnc1(kts:kte)=0.0 dqnwfa1(kts:kte)=0.0 dqnifa1(kts:kte)=0.0 + dqnbca1(kts:kte)=0.0 dozone1(kts:kte)=0.0 qc_bl1D_old(kts:kte)=0.0 cldfra_bl1D_old(kts:kte)=0.0 @@ -711,7 +696,7 @@ SUBROUTINE mynn_bl_driver( & ENDDO ENDDO - IF ( bl_mynn_tkebudget ) THEN + IF (tke_budget .eq. 1) THEN DO k=KTS,KTE DO i=ITS,ITF qWT(i,k)=0. @@ -724,7 +709,23 @@ SUBROUTINE mynn_bl_driver( & ENDIF DO i=ITS,ITF - DO k=KTS,KTE !KTF + if (FLAG_QI ) then + sqi(:)=sqi3D(i,:) + else + sqi = 0.0 + endif + if (FLAG_QS ) then + sqs(:)=sqs3D(i,:) + else + sqs = 0.0 + endif + if (icloud_bl > 0) then + cldfra_bl1d(:)=cldfra_bl(i,:) + qc_bl1d(:)=qc_bl(i,:) + qi_bl1d(:)=qi_bl(i,:) + endif + + do k=KTS,KTE !KTF dz1(k)=dz(i,k) u1(k) = u(i,k) v1(k) = v(i,k) @@ -735,52 +736,15 @@ SUBROUTINE mynn_bl_driver( & rho1(k)=rho(i,k) sqc(k)=sqc3D(i,k) !/(1.+qv(i,k)) sqv(k)=sqv3D(i,k) !/(1.+qv(i,k)) - thetav(k)=th(i,k)*(1.+0.608*sqv(k)) - IF (icloud_bl > 0) THEN - CLDFRA_BL1D(k)=CLDFRA_BL(i,k) - QC_BL1D(k)=QC_BL(i,k) - QI_BL1D(k)=QI_BL(i,k) - ENDIF - IF (FLAG_QI ) THEN - sqi(k)=sqi3D(i,k) !/(1.+qv(i,k)) - sqw(k)=sqv(k)+sqc(k)+sqi(k) - thl(k)=th1(k) - xlvcp/ex1(k)*sqc(k) & - & - xlscp/ex1(k)*sqi(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & - ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. sqi(k)<1e-8 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=QI_BL1D(k)*CLDFRA_BL1D(k) - ELSE - sqc9=sqc(k) - sqi9=sqi(k) - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - sqwsg(k)=sqv(k)+sqc9+sqi9 - ELSE - sqi(k)=0.0 - sqw(k)=sqv(k)+sqc(k) - thl(k)=th1(k)-xlvcp/ex1(k)*sqc(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=0.0 - ELSE - sqc9=sqc(k) - sqi9=0.0 - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - sqwsg(k)=sqv(k)+sqc9+sqi9 - ENDIF - thvl(k)=thlsg(k)*(1.+0.61*sqv(k)) + thetav(k)=th(i,k)*(1.+p608*sqv(k)) + !keep snow out for now - increases ceiling bias + sqw(k)=sqv(k)+sqc(k)+sqi(k)!+sqs(k) + thl(k)=th1(k) - xlvcp/ex1(k)*sqc(k) & + & - xlscp/ex1(k)*(sqi(k)+sqs(k)) + !Use form from Tripoli and Cotton (1981) with their + !suggested min temperature to improve accuracy. + !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & + ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) IF (k==kts) THEN zw(k)=0. @@ -811,9 +775,8 @@ SUBROUTINE mynn_bl_driver( & zw(kte+1)=zw(kte)+dz(i,kte) -!> - Call get_pblh() to calculate hybrid (\f$\theta_{vli}-TKE\f$) PBL height. -! CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& - CALL GET_PBLH(KTS,KTE,PBLH(i),thvl, & +!> - Call get_pblh() to calculate hybrid (\f$\theta_{v}-TKE\f$) PBL height. + CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& & Qke1,zw,dz1,xland(i),KPBL(i)) !> - Call scale_aware() to calculate similarity functions for scale-adaptive control @@ -831,18 +794,17 @@ SUBROUTINE mynn_bl_driver( & !! obtaining prerequisite variables by calling the following subroutines from !! within mym_initialize(): mym_level2() and mym_length(). CALL mym_initialize ( & - &kts,kte, & + &kts,kte,xland(i), & &dz1, dx(i), zw, & &u1, v1, thl, sqv, & - &thlsg, sqwsg, & &PBLH(i), th1, thetav, sh, sm, & &ust(i), rmol(i), & &el, Qke1, Tsq1, Qsq1, Cov1, & &Psig_bl(i), cldfra_bl1D, & &bl_mynn_mixlength, & - &edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf,& + &edmf_w1,edmf_a1, & &INITIALIZE_QKE, & - &spp_pbl,rstoch_col ) + &spp_pbl,rstoch_col ) IF (.not.restart) THEN !UPDATE 3D VARIABLES @@ -885,654 +847,582 @@ SUBROUTINE mynn_bl_driver( & ENDIF DO i=ITS,ITF - DO k=KTS,KTE !KTF - !JOE-TKE BUDGET - IF ( bl_mynn_tkebudget ) THEN - dqke(i,k)=qke(i,k) - END IF - IF (icloud_bl > 0) THEN - CLDFRA_BL1D(k)=CLDFRA_BL(i,k) - QC_BL1D(k)=QC_BL(i,k) - QI_BL1D(k)=QI_BL(i,k) - cldfra_bl1D_old(k)=cldfra_bl(i,k) - qc_bl1D_old(k)=qc_bl(i,k) - qi_bl1D_old(k)=qi_bl(i,k) - else - CLDFRA_BL1D(k)=0.0 - QC_BL1D(k)=0.0 - QI_BL1D(k)=0.0 - cldfra_bl1D_old(k)=0.0 - qc_bl1D_old(k)=0.0 - qi_bl1D_old(k)=0.0 - ENDIF - dz1(k)= dz(i,k) - u1(k) = u(i,k) - v1(k) = v(i,k) - w1(k) = w(i,k) - th1(k)= th(i,k) - tk1(k)=T3D(i,k) - p1(k) = p(i,k) - ex1(k)= exner(i,k) - rho1(k)=rho(i,k) - sqv(k)= sqv3D(i,k) !/(1.+qv(i,k)) - sqc(k)= sqc3D(i,k) !/(1.+qv(i,k)) - qv1(k)= sqv(k)/(1.-sqv(k)) - qc1(k)= sqc(k)/(1.-sqv(k)) - dqc1(k)=0.0 - dqi1(k)=0.0 - dqni1(k)=0.0 - dqnc1(k)=0.0 - dqnwfa1(k)=0.0 - dqnifa1(k)=0.0 - dozone1(k)=0.0 - IF(FLAG_QI)THEN - sqi(k)= sqi3D(i,k) !/(1.+qv(i,k)) - qi1(k)= sqi(k)/(1.-sqv(k)) - sqw(k)= sqv(k)+sqc(k)+sqi(k) - thl(k)= th1(k) - xlvcp/ex1(k)*sqc(k) & - & - xlscp/ex1(k)*sqi(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & - ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. sqi(k)<1e-8 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=QI_BL1D(k)*CLDFRA_BL1D(k) - ELSE - sqc9=sqc(k) - sqi9=sqi(k) - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - sqwsg(k)=sqv(k)+sqc9+sqi9 - ELSE - qi1(k)=0.0 - sqi(k)=0.0 - sqw(k)= sqv(k)+sqc(k) - thl(k)= th1(k)-xlvcp/ex1(k)*sqc(k) - !Use form from Tripoli and Cotton (1981) with their - !suggested min temperature to improve accuracy. - !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k)) - !COMPUTE THL USING SGS CLOUDS FOR PBLH DIAG - IF(sqc(k)<1e-6 .and. CLDFRA_BL1D(k)>0.001)THEN - sqc9=QC_BL1D(k)*CLDFRA_BL1D(k) - sqi9=QI_BL1D(k)*CLDFRA_BL1D(k) - ELSE - sqc9=sqc(k) - sqi9=0.0 - ENDIF - thlsg(k)=th1(k) - xlvcp/ex1(k)*sqc9 & - & - xlscp/ex1(k)*sqi9 - ENDIF - thetav(k)=th1(k)*(1.+0.608*sqv(k)) - thvl(k) =thlsg(k) *(1.+0.608*sqv(k)) - - IF (FLAG_QNI ) THEN - qni1(k)=qni(i,k) - ELSE - qni1(k)=0.0 - ENDIF - IF (FLAG_QNC ) THEN - qnc1(k)=qnc(i,k) - ELSE - qnc1(k)=0.0 - ENDIF - IF (FLAG_QNWFA ) THEN - qnwfa1(k)=qnwfa(i,k) - ELSE - qnwfa1(k)=0.0 - ENDIF - IF (FLAG_QNIFA ) THEN - qnifa1(k)=qnifa(i,k) - ELSE - qnifa1(k)=0.0 - ENDIF - IF (FLAG_OZONE) THEN - ozone1(k)=ozone(i,k) - ELSE - ozone1(k)=0.0 - ENDIF - el(k) = el_pbl(i,k) - qke1(k)=qke(i,k) - sh(k) =sh3d(i,k) - sm(k) =sm3d(i,k) - tsq1(k)=tsq(i,k) - qsq1(k)=qsq(i,k) - cov1(k)=cov(i,k) - if (spp_pbl==1) then - rstoch_col(k)=pattern_spp_pbl(i,k) - else - rstoch_col(k)=0.0 - endif - - !edmf - edmf_a1(k)=0.0 - edmf_w1(k)=0.0 - edmf_qc1(k)=0.0 - s_aw1(k)=0. - s_awthl1(k)=0. - s_awqt1(k)=0. - s_awqv1(k)=0. - s_awqc1(k)=0. - s_awu1(k)=0. - s_awv1(k)=0. - s_awqke1(k)=0. - s_awqnc1(k)=0. - s_awqni1(k)=0. - s_awqnwfa1(k)=0. - s_awqnifa1(k)=0. - ![EWDD] - edmf_a_dd1(k)=0.0 - edmf_w_dd1(k)=0.0 - edmf_qc_dd1(k)=0.0 - sd_aw1(k)=0. - sd_awthl1(k)=0. - sd_awqt1(k)=0. - sd_awqv1(k)=0. - sd_awqc1(k)=0. - sd_awu1(k)=0. - sd_awv1(k)=0. - sd_awqke1(k)=0. - sub_thl(k)=0. - sub_sqv(k)=0. - sub_u(k)=0. - sub_v(k)=0. - det_thl(k)=0. - det_sqv(k)=0. - det_sqc(k)=0. - det_u(k)=0. - det_v(k)=0. - - IF (k==kts) THEN - zw(k)=0. - ELSE - zw(k)=zw(k-1)+dz(i,k-1) - ENDIF - ENDDO ! end k - - !initialize smoke/chem arrays (if used): - IF ( rrfs_smoke .and. mix_chem ) then - do ic = 1,ndvel - vd1(ic) = vdep(i,ic) !is this correct???? - chem1(kts,ic) = chem3d(i,kts,ic) - s_awchem1(kts,ic)=0. - enddo - do k = kts+1,kte - DO ic = 1,nchem - chem1(k,ic) = chem3d(i,k,ic) - s_awchem1(k,ic)=0. - ENDDO - enddo - ELSE - do ic = 1,ndvel - vd1(ic) = 0. !is this correct??? (ite) or (ndvel) - chem1(kts,ic) = 0. - s_awchem1(kts,ic)=0. - enddo - do k = kts+1,kte - do ic = 1,nchem - chem1(k,ic) = 0. - s_awchem1(k,ic)=0. - enddo - enddo - ENDIF - - zw(kte+1)=zw(kte)+dz(i,kte) - !EDMF - s_aw1(kte+1)=0. - s_awthl1(kte+1)=0. - s_awqt1(kte+1)=0. - s_awqv1(kte+1)=0. - s_awqc1(kte+1)=0. - s_awu1(kte+1)=0. - s_awv1(kte+1)=0. - s_awqke1(kte+1)=0. - s_awqnc1(kte+1)=0. - s_awqni1(kte+1)=0. - s_awqnwfa1(kte+1)=0. - s_awqnifa1(kte+1)=0. - sd_aw1(kte+1)=0. - sd_awthl1(kte+1)=0. - sd_awqt1(kte+1)=0. - sd_awqv1(kte+1)=0. - sd_awqc1(kte+1)=0. - sd_awu1(kte+1)=0. - sd_awv1(kte+1)=0. - sd_awqke1(kte+1)=0. - IF ( mix_chem ) THEN - DO ic = 1,nchem - s_awchem1(kte+1,ic)=0. - ENDDO - ENDIF + !Initialize some arrays + if (tke_budget .eq. 1) then + dqke(i,:)=qke(i,:) + endif + if (FLAG_QI ) then + sqi(:)=sqi3D(i,:) + else + sqi = 0.0 + endif + if (FLAG_QS ) then + sqs(:)=sqs3D(i,:) + else + sqs = 0.0 + endif + if (icloud_bl > 0) then + CLDFRA_BL1D(:)=CLDFRA_BL(i,:) + QC_BL1D(:) =QC_BL(i,:) + QI_BL1D(:) =QI_BL(i,:) + cldfra_bl1D_old(:)=cldfra_bl(i,:) + qc_bl1D_old(:)=qc_bl(i,:) + qi_bl1D_old(:)=qi_bl(i,:) + else + CLDFRA_BL1D =0.0 + QC_BL1D =0.0 + QI_BL1D =0.0 + cldfra_bl1D_old=0.0 + qc_bl1D_old =0.0 + qi_bl1D_old =0.0 + endif + dz1(kts:kte) =dz(i,kts:kte) + u1(kts:kte) =u(i,kts:kte) + v1(kts:kte) =v(i,kts:kte) + w1(kts:kte) =w(i,kts:kte) + th1(kts:kte) =th(i,kts:kte) + tk1(kts:kte) =T3D(i,kts:kte) + p1(kts:kte) =p(i,kts:kte) + ex1(kts:kte) =exner(i,kts:kte) + rho1(kts:kte) =rho(i,kts:kte) + sqv(kts:kte) =sqv3D(i,kts:kte) !/(1.+qv(i,kts:kte)) + sqc(kts:kte) =sqc3D(i,kts:kte) !/(1.+qv(i,kts:kte)) + qv1(kts:kte) =sqv(kts:kte)/(1.-sqv(kts:kte)) + qc1(kts:kte) =sqc(kts:kte)/(1.-sqv(kts:kte)) + qi1(kts:kte) =sqi(kts:kte)/(1.-sqv(kts:kte)) + qs1(kts:kte) =sqs(kts:kte)/(1.-sqv(kts:kte)) + dqc1(kts:kte) =0.0 + dqi1(kts:kte) =0.0 + dqs1(kts:kte) =0.0 + dqni1(kts:kte) =0.0 + dqnc1(kts:kte) =0.0 + dqnwfa1(kts:kte)=0.0 + dqnifa1(kts:kte)=0.0 + dqnbca1(kts:kte)=0.0 + dozone1(kts:kte)=0.0 + IF (FLAG_QNI ) THEN + qni1(kts:kte)=qni(i,kts:kte) + ELSE + qni1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNC ) THEN + qnc1(kts:kte)=qnc(i,kts:kte) + ELSE + qnc1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNWFA ) THEN + qnwfa1(kts:kte)=qnwfa(i,kts:kte) + ELSE + qnwfa1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNIFA ) THEN + qnifa1(kts:kte)=qnifa(i,kts:kte) + ELSE + qnifa1(kts:kte)=0.0 + ENDIF + IF (FLAG_QNBCA ) THEN + qnbca1(kts:kte)=qnbca(i,kts:kte) + ELSE + qnbca1(kts:kte)=0.0 + ENDIF + IF (FLAG_OZONE ) THEN + ozone1(kts:kte)=ozone(i,kts:kte) + ELSE + ozone1(kts:kte)=0.0 + ENDIF + el(kts:kte) =el_pbl(i,kts:kte) + qke1(kts:kte)=qke(i,kts:kte) + sh(kts:kte) =sh3d(i,kts:kte) + sm(kts:kte) =sm3d(i,kts:kte) + tsq1(kts:kte)=tsq(i,kts:kte) + qsq1(kts:kte)=qsq(i,kts:kte) + cov1(kts:kte)=cov(i,kts:kte) + if (spp_pbl==1) then + rstoch_col(kts:kte)=pattern_spp_pbl(i,kts:kte) + else + rstoch_col(kts:kte)=0.0 + endif + !edmf + edmf_a1 =0.0 + edmf_w1 =0.0 + edmf_qc1 =0.0 + s_aw1 =0.0 + s_awthl1 =0.0 + s_awqt1 =0.0 + s_awqv1 =0.0 + s_awqc1 =0.0 + s_awu1 =0.0 + s_awv1 =0.0 + s_awqke1 =0.0 + s_awqnc1 =0.0 + s_awqni1 =0.0 + s_awqnwfa1 =0.0 + s_awqnifa1 =0.0 + s_awqnbca1 =0.0 + ![EWDD] + edmf_a_dd1 =0.0 + edmf_w_dd1 =0.0 + edmf_qc_dd1=0.0 + sd_aw1 =0.0 + sd_awthl1 =0.0 + sd_awqt1 =0.0 + sd_awqv1 =0.0 + sd_awqc1 =0.0 + sd_awu1 =0.0 + sd_awv1 =0.0 + sd_awqke1 =0.0 + sub_thl =0.0 + sub_sqv =0.0 + sub_u =0.0 + sub_v =0.0 + det_thl =0.0 + det_sqv =0.0 + det_sqc =0.0 + det_u =0.0 + det_v =0.0 + + do k = kts,kte + if (k==kts) then + zw(k)=0. + else + zw(k)=zw(k-1)+dz(i,k-1) + endif + !keep snow out for now - increases ceiling bias + sqw(k)= sqv(k)+sqc(k)+sqi(k)!+sqs(k) + thl(k)= th1(k) - xlvcp/ex1(k)*sqc(k) & + & - xlscp/ex1(k)*(sqi(k)+sqs(k)) + !Use form from Tripoli and Cotton (1981) with their + !suggested min temperature to improve accuracy. + !thl(k)=th(i,k)*(1.- xlvcp/MAX(tk1(k),TKmin)*sqc(k) & + ! & - xlscp/MAX(tk1(k),TKmin)*sqi(k)) + thetav(k)=th1(k)*(1.+p608*sqv(k)) + enddo ! end k + zw(kte+1)=zw(kte)+dz(i,kte) + + !initialize smoke/chem arrays (if used): + if ( mix_chem ) then + do ic = 1,ndvel + vd1(ic) = vdep(i,ic) ! dry deposition velocity + chem1(kts,ic) = chem3d(i,kts,ic) + enddo + do k = kts+1,kte + do ic = 1,nchem + chem1(k,ic) = chem3d(i,k,ic) + enddo + enddo + else + do ic = 1,ndvel + vd1(ic) = 0. ! dry deposition velocity + chem1(kts,ic) = 0. + enddo + do k = kts+1,kte + do ic = 1,nchem + chem1(k,ic) = 0. + enddo + enddo + endif + s_awchem1 = 0.0 !> - Call get_pblh() to calculate the hybrid \f$\theta_{vli}-TKE\f$ !! PBL height diagnostic. -! CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& - CALL GET_PBLH(KTS,KTE,PBLH(i),thvl,& - & Qke1,zw,dz1,xland(i),KPBL(i)) + CALL GET_PBLH(KTS,KTE,PBLH(i),thetav,& + & Qke1,zw,dz1,xland(i),KPBL(i)) !> - Call scale_aware() to calculate the similarity functions, !! \f$P_{\sigma-PBL}\f$ and \f$P_{\sigma-shcu}\f$, to control !! the scale-adaptive behaviour for the local and nonlocal !! components, respectively. - IF (scaleaware > 0.) THEN - CALL SCALE_AWARE(dx(i),PBLH(i),Psig_bl(i),Psig_shcu(i)) - ELSE - Psig_bl(i)=1.0 - Psig_shcu(i)=1.0 - ENDIF + if (scaleaware > 0.) then + call SCALE_AWARE(dx(i),PBLH(i),Psig_bl(i),Psig_shcu(i)) + else + Psig_bl(i)=1.0 + Psig_shcu(i)=1.0 + endif - sqcg= 0.0 !ill-defined variable; qcg has been removed - cpm=cp*(1.+0.84*qv1(kts)) - exnerg=(ps(i)/p1000mb)**rcp - - !----------------------------------------------------- - !ORIGINAL CODE - !flt = hfx(i)/( rho(i,kts)*cpm ) & - ! +xlvcp*ch(i)*(sqc(kts)/exner(i,kts) -sqcg/exnerg) - !flq = qfx(i)/ rho(i,kts) & - ! -ch(i)*(sqc(kts) -sqcg ) - !----------------------------------------------------- - ! Katata-added - The deposition velocity of cloud (fog) - ! water is used instead of CH. - !flt = hfx(i)/( rho(i,kts)*cpm ) & - ! & +xlvcp*vdfg(i)*(sqc(kts)/exner(i,kts)- sqcg/exnerg) - !flq = qfx(i)/ rho(i,kts) & - ! & -vdfg(i)*(sqc(kts) - sqcg ) - !----------------------------------------------------- - flqv = qfx(i)/rho1(kts) - flqc = -vdfg(i)*(sqc(kts) - sqcg ) - th_sfc = ts(i)/ex1(kts) - - ! TURBULENT FLUX FOR TKE BOUNDARY CONDITIONS - flq =flqv+flqc !! LATENT - flt =hfx(i)/(rho1(kts)*cpm )-xlvcp*flqc/ex1(kts) !! Temperature flux - fltv=flt + flqv*p608*th_sfc !! Virtual temperature flux - - ! Update 1/L using updated sfc heat flux and friction velocity - rmol(i) = -karman*gtr*fltv/max(ust(i)**3,1.0e-6) - zet = 0.5*dz(i,kts)*rmol(i) - zet = MAX(zet, -20.) - zet = MIN(zet, 20.) - !if(i.eq.idbg)print*,"updated z/L=",zet - if (bl_mynn_stfunc == 0) then - !Original Kansas-type stability functions - if ( zet >= 0.0 ) then - pmz = 1.0 + (cphm_st-1.0) * zet - phh = 1.0 + cphh_st * zet - else - pmz = 1.0/ (1.0-cphm_unst*zet)**0.25 - zet - phh = 1.0/SQRT(1.0-cphh_unst*zet) - end if + sqcg= 0.0 !ill-defined variable; qcg has been removed + cpm=cp*(1.+0.84*qv1(kts)) + exnerg=(ps(i)/p1000mb)**rcp + + !----------------------------------------------------- + !ORIGINAL CODE + !flt = hfx(i)/( rho(i,kts)*cpm ) & + ! +xlvcp*ch(i)*(sqc(kts)/exner(i,kts) -sqcg/exnerg) + !flq = qfx(i)/ rho(i,kts) & + ! -ch(i)*(sqc(kts) -sqcg ) + !----------------------------------------------------- + flqv = qfx(i)/rho1(kts) + flqc = 0.0 !currently no sea-spray fluxes, fog settling handled elsewhere + th_sfc = ts(i)/ex1(kts) + + ! TURBULENT FLUX FOR TKE BOUNDARY CONDITIONS + flq =flqv+flqc !! LATENT + flt =hfx(i)/(rho1(kts)*cpm )-xlvcp*flqc/ex1(kts) !! Temperature flux + fltv=flt + flqv*p608*th_sfc !! Virtual temperature flux + + ! Update 1/L using updated sfc heat flux and friction velocity + rmol(i) = -karman*gtr*fltv/max(ust(i)**3,1.0e-6) + zet = 0.5*dz(i,kts)*rmol(i) + zet = MAX(zet, -20.) + zet = MIN(zet, 20.) + !if(i.eq.idbg)print*,"updated z/L=",zet + if (bl_mynn_stfunc == 0) then + !Original Kansas-type stability functions + if ( zet >= 0.0 ) then + pmz = 1.0 + (cphm_st-1.0) * zet + phh = 1.0 + cphh_st * zet else - !Updated stability functions (Puhales, 2020) - phi_m = phim(zet) - pmz = phi_m - zet - phh = phih(zet) + pmz = 1.0/ (1.0-cphm_unst*zet)**0.25 - zet + phh = 1.0/SQRT(1.0-cphh_unst*zet) end if + else + !Updated stability functions (Puhales, 2020) + phi_m = phim(zet) + pmz = phi_m - zet + phh = phih(zet) + end if !> - Call mym_condensation() to calculate the nonconvective component !! of the subgrid cloud fraction and mixing ratio as well as the functions !! used to calculate the buoyancy flux. Different cloud PDFs can be !! selected by use of the namelist parameter \p bl_mynn_cloudpdf. - CALL mym_condensation ( kts,kte, & - &dx(i),dz1,zw,thl,sqw,sqv,sqc,sqi,& - &p1,ex1,tsq1,qsq1,cov1, & - &Sh,el,bl_mynn_cloudpdf, & - &qc_bl1D,qi_bl1D,cldfra_bl1D, & - &PBLH(i),HFX(i), & - &Vt, Vq, th1, sgm, rmol(i), & - &spp_pbl, rstoch_col ) + call mym_condensation (kts,kte, & + &dx(i),dz1,zw,xland(i), & + &thl,sqw,sqv,sqc,sqi,sqs, & + &p1,ex1,tsq1,qsq1,cov1, & + &Sh,el,bl_mynn_cloudpdf, & + &qc_bl1D,qi_bl1D,cldfra_bl1D, & + &PBLH(i),HFX(i), & + &Vt, Vq, th1, sgm, rmol(i), & + &spp_pbl, rstoch_col ) !> - Add TKE source driven by cloud top cooling !! Calculate the buoyancy production of TKE from cloud-top cooling when !! \p bl_mynn_topdown =1. - IF (bl_mynn_topdown.eq.1)then - CALL topdown_cloudrad(kts,kte,dz1,zw, & - &xland(i),kpbl(i),PBLH(i), & - &sqc,sqi,sqw,thl,th1,ex1,p1,rho1,thetav, & - &cldfra_bl1D,rthraten, & - &maxKHtopdown(i),KHtopdown,TKEprodTD ) - ELSE - maxKHtopdown(i) = 0.0 - KHtopdown(kts:kte) = 0.0 - TKEprodTD(kts:kte) = 0.0 - ENDIF + if (bl_mynn_topdown.eq.1) then + call topdown_cloudrad(kts,kte,dz1,zw, & + &xland(i),kpbl(i),PBLH(i), & + &sqc,sqi,sqw,thl,th1,ex1,p1,rho1,thetav, & + &cldfra_bl1D,rthraten(i,:), & + &maxKHtopdown(i),KHtopdown,TKEprodTD ) + else + maxKHtopdown(i) = 0.0 + KHtopdown(kts:kte) = 0.0 + TKEprodTD(kts:kte) = 0.0 + endif - IF (bl_mynn_edmf > 0) THEN - !PRINT*,"Calling DMP Mass-Flux: i= ",i - CALL DMP_mf( & - &kts,kte,delt,zw,dz1,p1,rho1, & - &bl_mynn_edmf_mom, & - &bl_mynn_edmf_tke, & - &bl_mynn_mixscalars, & - &u1,v1,w1,th1,thl,thetav,tk1, & - &sqw,sqv,sqc,qke1, & - &qnc1,qni1,qnwfa1,qnifa1, & - &ex1,Vt,Vq,sgm, & - &ust(i),flt,fltv,flq,flqv, & - &PBLH(i),KPBL(i),DX(i), & - &xland(i),th_sfc, & + if (bl_mynn_edmf > 0) then + !PRINT*,"Calling DMP Mass-Flux: i= ",i + call DMP_mf( & + &kts,kte,delt,zw,dz1,p1,rho1, & + &bl_mynn_edmf_mom, & + &bl_mynn_edmf_tke, & + &bl_mynn_mixscalars, & + &u1,v1,w1,th1,thl,thetav,tk1, & + &sqw,sqv,sqc,qke1, & + &qnc1,qni1,qnwfa1,qnifa1,qnbca1, & + &ex1,Vt,Vq,sgm, & + &ust(i),flt,fltv,flq,flqv, & + &PBLH(i),KPBL(i),DX(i), & + &xland(i),th_sfc, & ! now outputs - tendencies - ! &,dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf & + ! &,dth1mf,dqv1mf,dqc1mf,du1mf,dv1mf & ! outputs - updraft properties - & edmf_a1,edmf_w1,edmf_qt1, & - & edmf_thl1,edmf_ent1,edmf_qc1, & + &edmf_a1,edmf_w1,edmf_qt1, & + &edmf_thl1,edmf_ent1,edmf_qc1, & ! for the solver - & s_aw1,s_awthl1,s_awqt1, & - & s_awqv1,s_awqc1, & - & s_awu1,s_awv1,s_awqke1, & - & s_awqnc1,s_awqni1, & - & s_awqnwfa1,s_awqnifa1, & - & sub_thl,sub_sqv, & - & sub_u,sub_v, & - & det_thl,det_sqv,det_sqc, & - & det_u,det_v, & + &s_aw1,s_awthl1,s_awqt1, & + &s_awqv1,s_awqc1, & + &s_awu1,s_awv1,s_awqke1, & + &s_awqnc1,s_awqni1, & + &s_awqnwfa1,s_awqnifa1,s_awqnbca1, & + &sub_thl,sub_sqv, & + &sub_u,sub_v, & + &det_thl,det_sqv,det_sqc, & + &det_u,det_v, & ! chem/smoke mixing - & nchem,chem1,s_awchem1, & - & mix_chem, & - & qc_bl1D,cldfra_bl1D, & - & qc_bl1D_old,cldfra_bl1D_old, & - & FLAG_QC,FLAG_QI, & - & FLAG_QNC,FLAG_QNI, & - & FLAG_QNWFA,FLAG_QNIFA, & - & Psig_shcu(i), & - & nupdraft(i),ktop_plume(i), & - & maxmf(i),ztop_plume, & - & spp_pbl,rstoch_col ) - ENDIF + &nchem,chem1,s_awchem1, & + &mix_chem, & + &qc_bl1D,cldfra_bl1D, & + &qc_bl1D_old,cldfra_bl1D_old, & + &FLAG_QC,FLAG_QI, & + &FLAG_QNC,FLAG_QNI, & + &FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA, & + &Psig_shcu(i), & + &nupdraft(i),ktop_plume(i), & + &maxmf(i),ztop_plume, & + &spp_pbl,rstoch_col ) + endif - IF (bl_mynn_edmf_dd == 1) THEN - CALL DDMF_JPL(kts,kte,delt,zw,dz1,p1, & - &u1,v1,th1,thl,thetav,tk1, & - sqw,sqv,sqc,rho1,ex1, & - &ust(i),flt,flq, & - &PBLH(i),KPBL(i), & - &edmf_a_dd1,edmf_w_dd1,edmf_qt_dd1, & - &edmf_thl_dd1,edmf_ent_dd1, & - &edmf_qc_dd1, & - &sd_aw1,sd_awthl1,sd_awqt1, & - &sd_awqv1,sd_awqc1,sd_awu1,sd_awv1, & - &sd_awqke1, & - &qc_bl1d,cldfra_bl1d, & - &rthraten(i,:) ) - ENDIF + if (bl_mynn_edmf_dd == 1) then + call DDMF_JPL(kts,kte,delt,zw,dz1,p1, & + &u1,v1,th1,thl,thetav,tk1, & + &sqw,sqv,sqc,rho1,ex1, & + &ust(i),flt,flq, & + &PBLH(i),KPBL(i), & + &edmf_a_dd1,edmf_w_dd1,edmf_qt_dd1, & + &edmf_thl_dd1,edmf_ent_dd1, & + &edmf_qc_dd1, & + &sd_aw1,sd_awthl1,sd_awqt1, & + &sd_awqv1,sd_awqc1,sd_awu1,sd_awv1, & + &sd_awqke1, & + &qc_bl1d,cldfra_bl1d, & + &rthraten(i,:) ) + endif - !Capability to substep the eddy-diffusivity portion - !do nsub = 1,2 - delt2 = delt !*0.5 !only works if topdown=0 - - CALL mym_turbulence ( & - &kts,kte,closure, & - &dz1, DX(i), zw, & - &u1, v1, thl, thetav, sqc, sqw, & - &thlsg, sqwsg, & - &qke1, tsq1, qsq1, cov1, & - &vt, vq, & - &rmol(i), flt, flq, & - &PBLH(i),th1, & - &Sh,Sm,el, & - &Dfm,Dfh,Dfq, & - &Tcd,Qcd,Pdk, & - &Pdt,Pdq,Pdc, & - &qWT1,qSHEAR1,qBUOY1,qDISS1, & - &bl_mynn_tkebudget, & - &Psig_bl(i),Psig_shcu(i), & - &cldfra_bl1D,bl_mynn_mixlength, & - &edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf, & - &TKEprodTD, & - &spp_pbl,rstoch_col) + !Capability to substep the eddy-diffusivity portion + !do nsub = 1,2 + delt2 = delt !*0.5 !only works if topdown=0 + + call mym_turbulence( & + &kts,kte,xland(i),closure, & + &dz1, DX(i), zw, & + &u1, v1, thl, thetav, sqc, sqw, & + &qke1, tsq1, qsq1, cov1, & + &vt, vq, & + &rmol(i), flt, fltv, flq, & + &PBLH(i),th1, & + &Sh,Sm,el, & + &Dfm,Dfh,Dfq, & + &Tcd,Qcd,Pdk, & + &Pdt,Pdq,Pdc, & + &qWT1,qSHEAR1,qBUOY1,qDISS1, & + &tke_budget, & + &Psig_bl(i),Psig_shcu(i), & + &cldfra_bl1D,bl_mynn_mixlength, & + &edmf_w1,edmf_a1, & + &TKEprodTD, & + &spp_pbl,rstoch_col ) !> - Call mym_predict() to solve TKE and !! \f$\theta^{'2}, q^{'2}, and \theta^{'}q^{'}\f$ !! for the following time step. - CALL mym_predict (kts,kte,closure, & - &delt2, dz1, & - &ust(i), flt, flq, pmz, phh, & - &el, dfq, rho1, pdk, pdt, pdq, pdc,& - &Qke1, Tsq1, Qsq1, Cov1, & - &s_aw1, s_awqke1, bl_mynn_edmf_tke,& - &qWT1, qDISS1,bl_mynn_tkebudget) !! TKE budget (Puhales, 2020) - - if (dheat_opt > 0) then - DO k=kts,kte-1 - ! Set max dissipative heating rate to 7.2 K per hour - diss_heat(k) = MIN(MAX(1.0*(qke1(k)**1.5)/(b1*MAX(0.5*(el(k)+el(k+1)),1.))/cp, 0.0),0.002) - ! Limit heating above 100 mb: - diss_heat(k) = diss_heat(k) * exp(-10000./MAX(p1(k),1.)) - ENDDO - diss_heat(kte) = 0. - else - diss_heat(1:kte) = 0. - endif + call mym_predict(kts,kte,closure, & + &delt2, dz1, & + &ust(i), flt, flq, pmz, phh, & + &el, dfq, rho1, pdk, pdt, pdq, pdc, & + &Qke1, Tsq1, Qsq1, Cov1, & + &s_aw1, s_awqke1, bl_mynn_edmf_tke, & + &qWT1, qDISS1, tke_budget ) + + if (dheat_opt > 0) then + do k=kts,kte-1 + ! Set max dissipative heating rate to 7.2 K per hour + diss_heat(k) = MIN(MAX(1.0*(qke1(k)**1.5)/(b1*MAX(0.5*(el(k)+el(k+1)),1.))/cp, 0.0),0.002) + ! Limit heating above 100 mb: + diss_heat(k) = diss_heat(k) * exp(-10000./MAX(p1(k),1.)) + enddo + diss_heat(kte) = 0. + else + diss_heat(1:kte) = 0. + endif !> - Call mynn_tendencies() to solve for tendencies of !! \f$U, V, \theta, q_{v}, q_{c}, and q_{i}\f$. - CALL mynn_tendencies(kts,kte,i, & - &closure, & - &delt, dz1, rho1, & - &u1, v1, th1, tk1, qv1, & - &qc1, qi1, qnc1, qni1, & - &ps(i), p1, ex1, thl, & - &sqv, sqc, sqi, sqw, & - &qnwfa1, qnifa1, ozone1, & - &ust(i),flt,flq,flqv,flqc, & - &wspd(i),uoce(i),voce(i), & - &tsq1, qsq1, cov1, & - &tcd, qcd, & - &dfm, dfh, dfq, & - &Du1, Dv1, Dth1, Dqv1, & - &Dqc1, Dqi1, Dqnc1, Dqni1, & - &Dqnwfa1, Dqnifa1, Dozone1, & - &vdfg(i), diss_heat, & + call mynn_tendencies(kts,kte,i, & + &delt, dz1, rho1, & + &u1, v1, th1, tk1, qv1, & + &qc1, qi1, qs1, qnc1, qni1, & + &ps(i), p1, ex1, thl, & + &sqv, sqc, sqi, sqs, sqw, & + &qnwfa1, qnifa1, qnbca1, ozone1, & + &ust(i),flt,flq,flqv,flqc, & + &wspd(i),uoce(i),voce(i), & + &tsq1, qsq1, cov1, & + &tcd, qcd, & + &dfm, dfh, dfq, & + &Du1, Dv1, Dth1, Dqv1, & + &Dqc1, Dqi1, Dqs1, Dqnc1, Dqni1, & + &Dqnwfa1, Dqnifa1, Dqnbca1, & + &Dozone1, & + &diss_heat, & ! mass flux components - &s_aw1,s_awthl1,s_awqt1, & - &s_awqv1,s_awqc1,s_awu1,s_awv1, & - &s_awqnc1,s_awqni1, & - &s_awqnwfa1,s_awqnifa1, & - &sd_aw1,sd_awthl1,sd_awqt1, & - &sd_awqv1,sd_awqc1, & - sd_awu1,sd_awv1, & - &sub_thl,sub_sqv, & - &sub_u,sub_v, & - &det_thl,det_sqv,det_sqc, & - &det_u,det_v, & - &FLAG_QC,FLAG_QI,FLAG_QNC, & - &FLAG_QNI,FLAG_QNWFA,FLAG_QNIFA, & - &cldfra_bl1d, & - &bl_mynn_cloudmix, & - &bl_mynn_mixqt, & - &bl_mynn_edmf, & - &bl_mynn_edmf_mom, & - &bl_mynn_mixscalars ) - - - IF ( rrfs_smoke .and. mix_chem ) THEN - CALL mynn_mix_chem(kts,kte,i, & - &delt, dz1, pblh(i), & - &nchem, kdvel, ndvel, & - &chem1, vd1, & - &rho1,flt, & - &tcd, qcd, & - &dfh, & - &s_aw1,s_awchem1, & - &emis_ant_no(i), & - &frp(i), & - &fire_turb ) - - DO ic = 1,nchem - DO k = kts,kte - chem3d(i,k,ic) = chem1(k,ic) - ENDDO - ENDDO - ENDIF + &s_aw1,s_awthl1,s_awqt1, & + &s_awqv1,s_awqc1,s_awu1,s_awv1, & + &s_awqnc1,s_awqni1, & + &s_awqnwfa1,s_awqnifa1,s_awqnbca1, & + &sd_aw1,sd_awthl1,sd_awqt1, & + &sd_awqv1,sd_awqc1, & + &sd_awu1,sd_awv1, & + &sub_thl,sub_sqv, & + &sub_u,sub_v, & + &det_thl,det_sqv,det_sqc, & + &det_u,det_v, & + &FLAG_QC,FLAG_QI,FLAG_QNC, & + &FLAG_QNI,FLAG_QS, & + &FLAG_QNWFA,FLAG_QNIFA, & + &FLAG_QNBCA, & + &cldfra_bl1d, & + &bl_mynn_cloudmix, & + &bl_mynn_mixqt, & + &bl_mynn_edmf, & + &bl_mynn_edmf_mom, & + &bl_mynn_mixscalars ) + + + if ( mix_chem ) then + if ( rrfs_sd ) then + call mynn_mix_chem(kts,kte,i, & + &delt, dz1, pblh(i), & + &nchem, kdvel, ndvel, & + &chem1, vd1, & + &rho1,flt, & + &tcd, qcd, & + &dfh, & + &s_aw1,s_awchem1, & + &emis_ant_no(i), & + &frp(i), rrfs_sd, & + &enh_mix, smoke_dbg ) + else + call mynn_mix_chem(kts,kte,i, & + &delt, dz1, pblh(i), & + &nchem, kdvel, ndvel, & + &chem1, vd1, & + &rho1,flt, & + &tcd, qcd, & + &dfh, & + &s_aw1,s_awchem1, & + &zero, & + &zero, rrfs_sd, & + &enh_mix, smoke_dbg ) + endif + do ic = 1,nchem + do k = kts,kte + chem3d(i,k,ic) = max(1.e-12, chem1(k,ic)) + enddo + enddo + endif - CALL retrieve_exchange_coeffs(kts,kte,& - &dfm, dfh, dz1, K_m1, K_h1) - - !UPDATE 3D ARRAYS - DO k=KTS,KTE !KTF - exch_m(i,k)=K_m1(k) - exch_h(i,k)=K_h1(k) - RUBLTEN(i,k)=du1(k) - RVBLTEN(i,k)=dv1(k) - RTHBLTEN(i,k)=dth1(k) - RQVBLTEN(i,k)=dqv1(k) - IF(bl_mynn_cloudmix > 0)THEN - IF (FLAG_QC) RQCBLTEN(i,k)=dqc1(k) - IF (FLAG_QI) RQIBLTEN(i,k)=dqi1(k) - ELSE - IF (FLAG_QC) RQCBLTEN(i,k)=0. - IF (FLAG_QI) RQIBLTEN(i,k)=0. - ENDIF - IF(bl_mynn_cloudmix > 0 .AND. bl_mynn_mixscalars > 0)THEN - IF (FLAG_QNC) RQNCBLTEN(i,k)=dqnc1(k) - IF (FLAG_QNI) RQNIBLTEN(i,k)=dqni1(k) - IF (FLAG_QNWFA) RQNWFABLTEN(i,k)=dqnwfa1(k) - IF (FLAG_QNIFA) RQNIFABLTEN(i,k)=dqnifa1(k) - ELSE - IF (FLAG_QNC) RQNCBLTEN(i,k)=0. - IF (FLAG_QNI) RQNIBLTEN(i,k)=0. - IF (FLAG_QNWFA) RQNWFABLTEN(i,k)=0. - IF (FLAG_QNIFA) RQNIFABLTEN(i,k)=0. - ENDIF - DOZONE(i,k)=DOZONE1(k) - - IF(icloud_bl > 0)THEN - !DIAGNOSTIC-DECAY FOR SUBGRID-SCALE CLOUDS - IF (CLDFRA_BL1D(k) < cldfra_bl1D_old(k)) THEN - !DECAY TIMESCALE FOR CALM CONDITION IS THE EDDY TURNOVER - !TIMESCALE, BUT FOR WINDY CONDITIONS, IT IS THE ADVECTIVE - !TIMESCALE. USE THE MINIMUM OF THE TWO. - ts_decay = MIN( 1800., 2.*dx(i)/MAX(SQRT(u1(k)**2 + v1(k)**2),1.0) ) - cldfra_bl(i,k)= MAX(cldfra_bl1D(k),cldfra_bl1D_old(k)-(0.25*delt/ts_decay)) - ! qc_bl2 and qi_bl2 are linked to decay rates - qc_bl2 = MAX(qc_bl1D(k),qc_bl1D_old(k)) - qi_bl2 = MAX(qi_bl1D(k),qi_bl1D_old(k)) - qc_bl(i,k) = MAX(qc_bl1D(k),qc_bl1D_old(k)-(MIN(qc_bl2,1.0E-5) * delt/ts_decay)) - qi_bl(i,k) = MAX(qi_bl1D(k),qi_bl1D_old(k)-(MIN(qi_bl2,1.0E-6) * delt/ts_decay)) - IF (cldfra_bl(i,k) < 0.005 .OR. & - (qc_bl(i,k) + qi_bl(i,k)) < 1E-9) THEN - CLDFRA_BL(i,k)= 0. - QC_BL(i,k) = 0. - QI_BL(i,k) = 0. - ENDIF - ELSE - qc_bl(i,k)=qc_bl1D(k) - qi_bl(i,k)=qi_bl1D(k) - cldfra_bl(i,k)=cldfra_bl1D(k) - ENDIF - ENDIF - - el_pbl(i,k)=el(k) - qke(i,k)=qke1(k) - tsq(i,k)=tsq1(k) - qsq(i,k)=qsq1(k) - cov(i,k)=cov1(k) - sh3d(i,k)=sh(k) - sm3d(i,k)=sm(k) - ENDDO !end-k - - IF ( bl_mynn_tkebudget ) THEN - !! TKE budget is now given in m**2/s**-3 (Puhales, 2020) - !! Lower boundary condtions (using similarity relationships such as the prognostic equation for Qke) - k=kts - qSHEAR1(k)=4.*(ust(i)**3*phi_m/(karman*dz(i,k)))-qSHEAR1(k+1) !! staggered - qBUOY1(k)=4.*(-ust(i)**3*zet/(karman*dz(i,k)))-qBUOY1(k+1) !! staggered - !! unstaggering SHEAR and BUOY and trasfering all TKE budget to 3D array - DO k = kts,kte-1 - qSHEAR(i,k)=0.5*(qSHEAR1(k)+qSHEAR1(k+1)) !!! unstaggering in z - qBUOY(i,k)=0.5*(qBUOY1(k)+qBUOY1(k+1)) !!! unstaggering in z - qWT(i,k)=qWT1(k) - qDISS(i,k)=qDISS1(k) - dqke(i,k)=(qke1(k)-dqke(i,k))*0.5/delt - ENDDO - !! Upper boundary conditions - k=kte - qSHEAR(i,k)=0. - qBUOY(i,k)=0. - qWT(i,k)=0. - qDISS(i,k)=0. - dqke(i,k)=0. - ENDIF + call retrieve_exchange_coeffs(kts,kte, & + &dfm, dfh, dz1, K_m1, K_h1 ) + + !UPDATE 3D ARRAYS + exch_m(i,:) =k_m1(:) + exch_h(i,:) =k_h1(:) + rublten(i,:) =du1(:) + rvblten(i,:) =dv1(:) + rthblten(i,:)=dth1(:) + rqvblten(i,:)=dqv1(:) + if (bl_mynn_cloudmix > 0) then + if (flag_qc) rqcblten(i,:)=dqc1(:) + if (flag_qi) rqiblten(i,:)=dqi1(:) + if (flag_qs) rqsblten(i,:)=dqs1(:) + else + if (flag_qc) rqcblten(i,:)=0. + if (flag_qi) rqiblten(i,:)=0. + if (flag_qs) rqsblten(i,:)=0. + endif + if (bl_mynn_cloudmix > 0 .and. bl_mynn_mixscalars > 0) then + if (flag_qnc) rqncblten(i,:) =dqnc1(:) + if (flag_qni) rqniblten(i,:) =dqni1(:) + if (flag_qnwfa) rqnwfablten(i,:)=dqnwfa1(:) + if (flag_qnifa) rqnifablten(i,:)=dqnifa1(:) + if (flag_qnbca) rqnbcablten(i,:)=dqnbca1(:) + else + if (flag_qnc) rqncblten(i,:) =0. + if (flag_qni) rqniblten(i,:) =0. + if (flag_qnwfa) rqnwfablten(i,:)=0. + if (flag_qnifa) rqnifablten(i,:)=0. + if (flag_qnbca) rqnbcablten(i,:)=0. + endif + dozone(i,:)=dozone1(:) + if (icloud_bl > 0) then + qc_bl(i,:) =qc_bl1D(:) + qi_bl(i,:) =qi_bl1D(:) + cldfra_bl(i,:)=cldfra_bl1D(:) + endif + el_pbl(i,:)=el(:) + qke(i,:) =qke1(:) + tsq(i,:) =tsq1(:) + qsq(i,:) =qsq1(:) + cov(i,:) =cov1(:) + sh3d(i,:) =sh(:) + sm3d(i,:) =sm(:) + + if (tke_budget .eq. 1) then + !! TKE budget is now given in m**2/s**-3 (Puhales, 2020) + !! Lower boundary condtions (using similarity relationships such as the prognostic equation for Qke) + k=kts + qSHEAR1(k) =4.*(ust(i)**3*phi_m/(karman*dz(i,k)))-qSHEAR1(k+1) !! staggered + qBUOY1(k) =4.*(-ust(i)**3*zet/(karman*dz(i,k)))-qBUOY1(k+1) !! staggered + !! unstaggering SHEAR and BUOY and trasfering all TKE budget to 3D array + do k = kts,kte-1 + qSHEAR(i,k)=0.5*(qSHEAR1(k)+qSHEAR1(k+1)) !!! unstaggering in z + qBUOY(i,k) =0.5*(qBUOY1(k)+qBUOY1(k+1)) !!! unstaggering in z + qWT(i,k) =qWT1(k) + qDISS(i,k) =qDISS1(k) + dqke(i,k) =(qke1(k)-dqke(i,k))*0.5/delt + enddo + !! Upper boundary conditions + k=kte + qSHEAR(i,k) =0. + qBUOY(i,k) =0. + qWT(i,k) =0. + qDISS(i,k) =0. + dqke(i,k) =0. + endif - !update updraft/downdraft properties - if (bl_mynn_output > 0) THEN !research mode == 1 - if (bl_mynn_edmf > 0) THEN - DO k = kts,kte - edmf_a(i,k)=edmf_a1(k) - edmf_w(i,k)=edmf_w1(k) - edmf_qt(i,k)=edmf_qt1(k) - edmf_thl(i,k)=edmf_thl1(k) - edmf_ent(i,k)=edmf_ent1(k) - edmf_qc(i,k)=edmf_qc1(k) - sub_thl3D(i,k)=sub_thl(k) - sub_sqv3D(i,k)=sub_sqv(k) - det_thl3D(i,k)=det_thl(k) - det_sqv3D(i,k)=det_sqv(k) - ENDDO - endif -! if (bl_mynn_edmf_dd > 0) THEN -! DO k = kts,kte -! edmf_a_dd(i,k)=edmf_a_dd1(k) -! edmf_w_dd(i,k)=edmf_w_dd1(k) -! edmf_qt_dd(i,k)=edmf_qt_dd1(k) -! edmf_thl_dd(i,k)=edmf_thl_dd1(k) -! edmf_ent_dd(i,k)=edmf_ent_dd1(k) -! edmf_qc_dd(i,k)=edmf_qc_dd1(k) -! ENDDO -! ENDIF - ENDIF + !update updraft/downdraft properties + if (bl_mynn_output > 0) then !research mode == 1 + if (bl_mynn_edmf > 0) then + edmf_a(i,:) =edmf_a1(:) + edmf_w(i,:) =edmf_w1(:) + edmf_qt(i,:) =edmf_qt1(:) + edmf_thl(i,:) =edmf_thl1(:) + edmf_ent(i,:) =edmf_ent1(:) + edmf_qc(i,:) =edmf_qc1(:) + sub_thl3D(i,:)=sub_thl(:) + sub_sqv3D(i,:)=sub_sqv(:) + det_thl3D(i,:)=det_thl(:) + det_sqv3D(i,:)=det_sqv(:) + endif + !if (bl_mynn_edmf_dd > 0) THEN + ! edmf_a_dd(i,:) =edmf_a_dd1(:) + ! edmf_w_dd(i,:) =edmf_w_dd1(:) + ! edmf_qt_dd(i,:) =edmf_qt_dd1(:) + ! edmf_thl_dd(i,:)=edmf_thl_dd1(:) + ! edmf_ent_dd(i,:)=edmf_ent_dd1(:) + ! edmf_qc_dd(i,:) =edmf_qc_dd1(:) + !endif + endif - !*** Begin debug prints - IF ( debug_code .and. (i .eq. idbg)) THEN - IF ( ABS(QFX(i))>.001)print*,& - "SUSPICIOUS VALUES AT: i=",i," QFX=",QFX(i) - IF ( ABS(HFX(i))>1100.)print*,& - "SUSPICIOUS VALUES AT: i=",i," HFX=",HFX(i) - DO k = kts,kte - IF ( sh(k) < 0. .OR. sh(k)> 200.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," sh=",sh(k) - IF ( ABS(vt(k)) > 0.9 )print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," vt=",vt(k) - IF ( ABS(vq(k)) > 6000.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," vq=",vq(k) - IF ( qke(i,k) < -1. .OR. qke(i,k)> 200.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," qke=",qke(i,k) - IF ( el_pbl(i,k) < 0. .OR. el_pbl(i,k)> 1500.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," el_pbl=",el_pbl(i,k) - IF ( exch_m(i,k) < 0. .OR. exch_m(i,k)> 2000.)print*,& - "SUSPICIOUS VALUES AT: i,k=",i,k," exxch_m=",exch_m(i,k) - IF (icloud_bl > 0) then - IF( cldfra_bl(i,k) < 0.0 .OR. cldfra_bl(i,k)> 1.)THEN - PRINT*,"SUSPICIOUS VALUES: CLDFRA_BL=",cldfra_bl(i,k)," qc_bl=",QC_BL(i,k) - ENDIF - ENDIF - - !IF (I==IMD .AND. J==JMD) THEN - ! PRINT*,"MYNN DRIVER END: k=",k," sh=",sh(k) - ! PRINT*," sqw=",sqw(k)," thl=",thl(k)," exch_m=",exch_m(i,k) - ! PRINT*," xland=",xland(i)," rmol=",rmol(i)," ust=",ust(i) - ! PRINT*," qke=",qke(i,k)," el=",el_pbl(i,k)," tsq=",tsq(i,k) - ! PRINT*," PBLH=",PBLH(i)," u=",u(i,k)," v=",v(i,k) - ! PRINT*," vq=",vq(k)," vt=",vt(k)," vdfg=",vdfg(i) - !ENDIF - ENDDO !end-k - ENDIF - !*** End debug prints + !*** Begin debug prints + if ( debug_code .and. (i .eq. idbg)) THEN + if ( ABS(QFX(i))>.001)print*,& + "SUSPICIOUS VALUES AT: i=",i," QFX=",QFX(i) + if ( ABS(HFX(i))>1100.)print*,& + "SUSPICIOUS VALUES AT: i=",i," HFX=",HFX(i) + do k = kts,kte + IF ( sh(k) < 0. .OR. sh(k)> 200.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," sh=",sh(k) + IF ( ABS(vt(k)) > 2.0 )print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," vt=",vt(k) + IF ( ABS(vq(k)) > 7000.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," vq=",vq(k) + IF ( qke(i,k) < -1. .OR. qke(i,k)> 200.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," qke=",qke(i,k) + IF ( el_pbl(i,k) < 0. .OR. el_pbl(i,k)> 1500.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," el_pbl=",el_pbl(i,k) + IF ( exch_m(i,k) < 0. .OR. exch_m(i,k)> 2000.)print*,& + "SUSPICIOUS VALUES AT: i,k=",i,k," exxch_m=",exch_m(i,k) + IF (icloud_bl > 0) then + IF ( cldfra_bl(i,k) < 0.0 .OR. cldfra_bl(i,k)> 1.)THEN + PRINT*,"SUSPICIOUS VALUES: CLDFRA_BL=",cldfra_bl(i,k)," qc_bl=",QC_BL(i,k) + ENDIF + ENDIF - !JOE-add tke_pbl for coupling w/shallow-cu schemes (TKE_PBL = QKE/2.) - ! TKE_PBL is defined on interfaces, while QKE is at middle of layer. - !tke_pbl(i,kts) = 0.5*MAX(qke(i,kts),1.0e-10) - !DO k = kts+1,kte - ! afk = dz1(k)/( dz1(k)+dz1(k-1) ) - ! abk = 1.0 -afk - ! tke_pbl(i,k) = 0.5*MAX(qke(i,k)*abk+qke(i,k-1)*afk,1.0e-3) - !ENDDO + !IF (I==IMD .AND. J==JMD) THEN + ! PRINT*,"MYNN DRIVER END: k=",k," sh=",sh(k) + ! PRINT*," sqw=",sqw(k)," thl=",thl(k)," exch_m=",exch_m(i,k) + ! PRINT*," xland=",xland(i)," rmol=",rmol(i)," ust=",ust(i) + ! PRINT*," qke=",qke(i,k)," el=",el_pbl(i,k)," tsq=",tsq(i,k) + ! PRINT*," PBLH=",PBLH(i)," u=",u(i,k)," v=",v(i,k) + ! PRINT*," vq=",vq(k)," vt=",vt(k) + !ENDIF + enddo !end-k + endif - ENDDO !end i-loop + enddo !end i-loop !ACF copy qke into qke_adv if using advection IF (bl_mynn_tkeadvect) THEN @@ -1549,13 +1439,7 @@ END SUBROUTINE mynn_bl_driver !> @} !======================================================================= -!> This subroutine gives the closure constants and initializes the -!! turbulent qantities. ! SUBROUTINE mym_initialize: -! ================================================================== -! This subroutine computes the length scales up and down -! and then computes the min, average of the up/down length scales, and also -! considers the distance to the surface. ! ! Input variables: ! iniflag : <>0; turbulent quantities will be initialized @@ -1607,48 +1491,46 @@ END SUBROUTINE mynn_bl_driver ! !------------------------------------------------------------------- -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine initializes the mixing length, TKE, \f$\theta^{'2}\f$, !! \f$q^{'2}\f$, and \f$\theta^{'}q^{'}\f$. !!\section gen_mym_ini GSD MYNN-EDMF mym_initialize General Algorithm !> @{ SUBROUTINE mym_initialize ( & - & kts,kte, & + & kts,kte,xland, & & dz, dx, zw, & & u, v, thl, qw, & - & thlsg, qwsg, & ! & ust, rmo, pmz, phh, flt, flq, & & zi, theta, thetav, sh, sm, & & ust, rmo, el, & & Qke, Tsq, Qsq, Cov, Psig_bl, cldfra_bl1D, & & bl_mynn_mixlength, & - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf, & + & edmf_w1,edmf_a1, & & INITIALIZE_QKE, & & spp_pbl,rstoch_col) ! !------------------------------------------------------------------- - - INTEGER, INTENT(IN) :: kts,kte - INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf - LOGICAL, INTENT(IN) :: INITIALIZE_QKE -! REAL, INTENT(IN) :: ust, rmo, pmz, phh, flt, flq - REAL, INTENT(IN) :: ust, rmo, Psig_bl, dx - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,cldfra_bl1D,& - edmf_w1,edmf_a1,edmf_qc1 - REAL, DIMENSION(kts:kte), INTENT(out) :: tsq,qsq,cov - REAL, DIMENSION(kts:kte), INTENT(inout) :: el,qke - - REAL, DIMENSION(kts:kte) :: & - &ql,pdk,pdt,pdq,pdc,dtl,dqw,dtv,& + + integer, INTENT(IN) :: kts,kte + integer, INTENT(IN) :: bl_mynn_mixlength + logical, INTENT(IN) :: INITIALIZE_QKE +! real(kind_phys), INTENT(IN) :: ust, rmo, pmz, phh, flt, flq + real(kind_phys), INTENT(IN) :: rmo, Psig_bl, xland + real(kind_phys), INTENT(IN) :: dx, ust, zi + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v,thl,& + &qw,cldfra_bl1D,edmf_w1,edmf_a1 + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: tsq,qsq,cov + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: el,qke + real(kind_phys), DIMENSION(kts:kte) :: & + &ql,pdk,pdt,pdq,pdc,dtl,dqw,dtv, & &gm,gh,sm,sh,qkw,vt,vq INTEGER :: k,l,lmax - REAL :: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1.,flt=0.,flq=0.,tmpq - REAL :: zi - REAL, DIMENSION(kts:kte) :: theta,thetav,thlsg,qwsg - - REAL, DIMENSION(kts:kte) :: rstoch_col + real(kind_phys):: phm,vkz,elq,elv,b1l,b2l,pmz=1.,phh=1., & + &flt=0.,fltv=0.,flq=0.,tmpq + real(kind_phys), DIMENSION(kts:kte) :: theta,thetav + real(kind_phys), DIMENSION(kts:kte) :: rstoch_col INTEGER ::spp_pbl !> - At first ql, vt and vq are set to zero. @@ -1662,7 +1544,6 @@ SUBROUTINE mym_initialize ( & CALL mym_level2 ( kts,kte, & & dz, & & u, v, thl, thetav, qw, & - & thlsg, qwsg, & & ql, vt, vq, & & dtl, dqw, dtv, gm, gh, sm, sh ) ! @@ -1701,17 +1582,18 @@ SUBROUTINE mym_initialize ( & DO l = 1,lmax ! !> - call mym_length() to calculate the master length scale. - CALL mym_length ( & - & kts,kte, & - & dz, dx, zw, & - & rmo, flt, flq, & - & vt, vq, & - & u, v, qke, & - & dtv, & - & el, & - & zi,theta, & - & qkw,Psig_bl,cldfra_bl1D,bl_mynn_mixlength,& - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf) + CALL mym_length ( & + & kts,kte,xland, & + & dz, dx, zw, & + & rmo, flt, fltv, flq, & + & vt, vq, & + & u, v, qke, & + & dtv, & + & el, & + & zi,theta, & + & qkw,Psig_bl,cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1 ) ! DO k = kts+1,kte elq = el(k)*qkw(k) @@ -1795,7 +1677,7 @@ END SUBROUTINE mym_initialize ! These are defined on the walls of the grid boxes. ! -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the level 2, non-dimensional wind shear !! \f$G_M\f$ and vertical temperature gradient \f$G_H\f$ as well as !! the level 2 stability funcitons \f$S_h\f$ and \f$S_m\f$. @@ -1821,7 +1703,6 @@ END SUBROUTINE mym_initialize SUBROUTINE mym_level2 (kts,kte, & & dz, & & u, v, thl, thetav, qw, & - & thlsg, qwsg, & & ql, vt, vq, & & dtl, dqw, dtv, gm, gh, sm, sh ) ! @@ -1834,18 +1715,19 @@ SUBROUTINE mym_level2 (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,qw,ql,vt,vq,& - thetav,thlsg,qwsg - REAL, DIMENSION(kts:kte), INTENT(out) :: & + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v, & + &thl,qw,ql,vt,vq,thetav + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: & &dtl,dqw,dtv,gm,gh,sm,sh - INTEGER :: k + integer :: k - REAL :: rfc,f1,f2,rf1,rf2,smc,shc,& - &ri1,ri2,ri3,ri4,duz,dtz,dqz,vtt,vqq,dtq,dzk,afk,abk,ri,rf + real(kind_phys):: rfc,f1,f2,rf1,rf2,smc,shc, & + &ri1,ri2,ri3,ri4,duz,dtz,dqz,vtt,vqq,dtq,dzk, & + &afk,abk,ri,rf - REAL :: a2fac + real(kind_phys):: a2fac ! ev = 2.5e6 ! tv0 = 0.61*tref @@ -1873,11 +1755,7 @@ SUBROUTINE mym_level2 (kts,kte, & duz = ( u(k)-u(k-1) )**2 +( v(k)-v(k-1) )**2 duz = duz /dzk**2 dtz = ( thl(k)-thl(k-1) )/( dzk ) - !Alternatively, use SGS clouds for thl - !dtz = ( thlsg(k)-thlsg(k-1) )/( dzk ) dqz = ( qw(k)-qw(k-1) )/( dzk ) - !Alternatively, use SGS clouds for qw - !dqz = ( qwsg(k)-qwsg(k-1) )/( dzk ) ! vtt = 1.0 +vt(k)*abk +vt(k-1)*afk ! Beta-theta in NN09, Eq. 39 vqq = tv0 +vq(k)*abk +vq(k-1)*afk ! Beta-q @@ -1951,19 +1829,21 @@ END SUBROUTINE mym_level2 ! NOTE: the mixing lengths are meant to be calculated at the full- ! sigmal levels (or interfaces beween the model layers). ! -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the mixing lengths. SUBROUTINE mym_length ( & - & kts,kte, & + & kts,kte,xland, & & dz, dx, zw, & - & rmo, flt, flq, & + & rmo, flt, fltv, flq, & & vt, vq, & & u1, v1, qke, & & dtv, & & el, & - & zi,theta, & - & qkw,Psig_bl,cldfra_bl1D,bl_mynn_mixlength,& - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf) + & zi, theta, qkw, & + & Psig_bl, cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1 ) + !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte @@ -1973,52 +1853,50 @@ SUBROUTINE mym_length ( & # define kte HARDCODE_VERTICAL #endif - INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, INTENT(in) :: rmo,flt,flq,Psig_bl,dx - REAL, DIMENSION(kts:kte), INTENT(IN) :: u1,v1,qke,vt,vq,cldfra_bl1D,& - edmf_w1,edmf_a1,edmf_qc1 - REAL, DIMENSION(kts:kte), INTENT(out) :: qkw, el - REAL, DIMENSION(kts:kte), INTENT(in) :: dtv - - REAL :: elt,vsc - - REAL, DIMENSION(kts:kte), INTENT(IN) :: theta - REAL, DIMENSION(kts:kte) :: qtke,elBLmin,elBLavg,thetaw - REAL :: wt,wt2,zi,zi2,h1,h2,hs,elBLmin0,elBLavg0,cldavg + INTEGER, INTENT(IN) :: bl_mynn_mixlength + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: zw + real(kind_phys), INTENT(in) :: rmo,flt,fltv,flq,Psig_bl,xland + real(kind_phys), INTENT(IN) :: dx,zi + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: u1,v1, & + &qke,vt,vq,cldfra_bl1D,edmf_w1,edmf_a1 + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: qkw, el + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dtv + real(kind_phys):: elt,vsc + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: theta + real(kind_phys), DIMENSION(kts:kte) :: qtke,elBLmin,elBLavg,thetaw + real(kind_phys):: wt,wt2,zi2,h1,h2,hs,elBLmin0,elBLavg0,cldavg ! THE FOLLOWING CONSTANTS ARE IMPORTANT FOR REGULATING THE ! MIXING LENGTHS: - REAL :: cns, & !< for surface layer (els) in stable conditions - alp1, & !< for turbulent length scale (elt) - alp2, & !< for buoyancy length scale (elb) - alp3, & !< for buoyancy enhancement factor of elb - alp4, & !< for surface layer (els) in unstable conditions - alp5, & !< for BouLac mixing length or above PBLH - alp6 !< for mass-flux/ + real(kind_phys):: cns, & !< for surface layer (els) in stable conditions + alp1, & !< for turbulent length scale (elt) + alp2, & !< for buoyancy length scale (elb) + alp3, & !< for buoyancy enhancement factor of elb + alp4, & !< for surface layer (els) in unstable conditions + alp5, & !< for BouLac mixing length or above PBLH + alp6 !< for mass-flux/ !THE FOLLOWING LIMITS DO NOT DIRECTLY AFFECT THE ACTUAL PBLH. !THEY ONLY IMPOSE LIMITS ON THE CALCULATION OF THE MIXING LENGTH !SCALES SO THAT THE BOULAC MIXING LENGTH (IN FREE ATMOS) DOES !NOT ENCROACH UPON THE BOUNDARY LAYER MIXING LENGTH (els, elb & elt). - REAL, PARAMETER :: minzi = 300. !< min mixed-layer height - REAL, PARAMETER :: maxdz = 750. !< max (half) transition layer depth + real(kind_phys), PARAMETER :: minzi = 300. !< min mixed-layer height + real(kind_phys), PARAMETER :: maxdz = 750. !< max (half) transition layer depth !! =0.3*2500 m PBLH, so the transition !! layer stops growing for PBLHs > 2.5 km. - REAL, PARAMETER :: mindz = 300. !< 300 !min (half) transition layer depth + real(kind_phys), PARAMETER :: mindz = 300. !< 300 !min (half) transition layer depth !SURFACE LAYER LENGTH SCALE MODS TO REDUCE IMPACT IN UPPER BOUNDARY LAYER - REAL, PARAMETER :: ZSLH = 100. !< Max height correlated to surface conditions (m) - REAL, PARAMETER :: CSL = 2. !< CSL = constant of proportionality to L O(1) - REAL :: z_m + real(kind_phys), PARAMETER :: ZSLH = 100. !< Max height correlated to surface conditions (m) + real(kind_phys), PARAMETER :: CSL = 2. !< CSL = constant of proportionality to L O(1) INTEGER :: i,j,k - REAL :: afk,abk,zwk,zwk1,dzk,qdz,vflx,bv,tau_cloud,wstar,elb,els, & - & els1,elf,el_stab,el_unstab,el_mf,el_stab_mf,elb_mf, & - & PBLH_PLUS_ENT,Uonset,Ugrid,el_les - REAL, PARAMETER :: ctau = 1000. !constant for tau_cloud + real(kind_phys):: afk,abk,zwk,zwk1,dzk,qdz,vflx,bv,tau_cloud, & + & wstar,elb,els,elf,el_stab,el_mf,el_stab_mf,elb_mf, & + & PBLH_PLUS_ENT,Uonset,Ugrid,wt_u,el_les + real(kind_phys), PARAMETER :: ctau = 1000. !constant for tau_cloud ! tv0 = 0.61*tref ! gtr = 9.81/tref @@ -2028,7 +1906,7 @@ SUBROUTINE mym_length ( & CASE (0) ! ORIGINAL MYNN MIXING LENGTH + BouLac cns = 2.7 - alp1 = 0.21 + alp1 = 0.23 alp2 = 1.0 alp3 = 5.0 alp4 = 100. @@ -2086,15 +1964,11 @@ SUBROUTINE mym_length ( & elf = elb ENDIF - z_m = MAX(0.,zwk - 4.) - ! ** Length scale in the surface layer ** IF ( rmo .GT. 0.0 ) THEN els = karman*zwk/(1.0+cns*MIN( zwk*rmo, zmax )) - els1 = karman*z_m/(1.0+cns*MIN( zwk*rmo, zmax )) ELSE els = karman*zwk*( 1.0 - alp4* zwk*rmo )**0.2 - els1 = karman*z_m*( 1.0 - alp4* zwk*rmo )**0.2 END IF ! ** HARMONC AVERGING OF MIXING LENGTH SCALES: @@ -2109,18 +1983,21 @@ SUBROUTINE mym_length ( & CASE (1) !NONLOCAL (using BouLac) FORM OF MIXING LENGTH - cns = 3.5 - alp1 = 0.21 + ugrid = sqrt(u1(kts)**2 + v1(kts)**2) + uonset= 15. + wt_u = (1.0 - min(max(ugrid - uonset, 0.0)/30.0, 0.5)) + cns = 2.7 !was 3.5 + alp1 = 0.22 alp2 = 0.3 - alp3 = 1.5 + alp3 = 2.0 * wt_u !taper off bouyancy enhancement in shear-driven pbls alp4 = 5.0 alp5 = 0.3 alp6 = 50. ! Impose limits on the height integration for elt and the transition layer depth - zi2=MAX(zi,200.) !minzi) - h1=MAX(0.3*zi2,200.) - h1=MIN(h1,500.) ! 1/2 transition layer depth + zi2=MAX(zi,300.) !minzi) + h1=MAX(0.3*zi2,300.) + h1=MIN(h1,600.) ! 1/2 transition layer depth h2=h1/2.0 ! 1/4 transition layer depth qtke(kts)=MAX(0.5*qke(kts), 0.01) !tke at full sigma levels @@ -2143,7 +2020,7 @@ SUBROUTINE mym_length ( & zwk = zw(k) DO WHILE (zwk .LE. zi2+h1) dzk = 0.5*( dz(k)+dz(k-1) ) - qdz = MAX( qkw(k)-qmin, 0.03 )*dzk + qdz = min(max( qkw(k)-qmin, 0.03 ), 30.0)*dzk elt = elt +qdz*zwk vsc = vsc +qdz k = k+1 @@ -2151,7 +2028,9 @@ SUBROUTINE mym_length ( & END DO elt = MIN( MAX( alp1*elt/vsc, 10.), 400.) - vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq + !avoid use of buoyancy flux functions which are ill-defined at the surface + !vflx = ( vt(kts)+1.0 )*flt + ( vq(kts)+tv0 )*flq + vflx = fltv vsc = ( gtr*elt*MAX( vflx, 0.0 ) )**onethird ! ** Strictly, el(i,j,1) is not zero. ** @@ -2166,31 +2045,23 @@ SUBROUTINE mym_length ( & ! ** Length scale limited by the buoyancy effect ** IF ( dtv(k) .GT. 0.0 ) THEN - alp2 = 0.3 + 0.15*0.5*(cldfra_bl1D(k)+cldfra_bl1D(k-1)) - bv = SQRT( gtr*dtv(k) ) - !elb = alp2*qkw(k) / bv & ! formulation, - ! & *( 1.0 + alp3/alp2*& ! except keep - ! &SQRT( vsc/( bv*elt ) ) ) ! elb bounded by zwk - elb = MAX(alp2*qkw(k), & - & alp6*edmf_a1(k)*edmf_w1(k)) / bv & + bv = max( sqrt( gtr*dtv(k) ), 0.001) + elb = MAX(alp2*qkw(k), & + & alp6*edmf_a1(k-1)*edmf_w1(k-1)) / bv & & *( 1.0 + alp3*SQRT( vsc/(bv*elt) ) ) elb = MIN(elb, zwk) - elf = 0.65 * qkw(k)/bv - !elBLavg(k) = MAX(elBLavg(k), alp6*edmf_a1(k)*edmf_w1(k)/bv) + elf = 0.80 * qkw(k)/bv + elBLavg(k) = MAX(elBLavg(k), alp6*edmf_a1(k-1)*edmf_w1(k-1)/bv) ELSE elb = 1.0e10 elf = elb ENDIF - z_m = MAX(0.,zwk - 4.) - ! ** Length scale in the surface layer ** IF ( rmo .GT. 0.0 ) THEN els = karman*zwk/(1.0+cns*MIN( zwk*rmo, zmax )) - els1 = karman*z_m/(1.0+cns*MIN( zwk*rmo, zmax )) ELSE els = karman*zwk*( 1.0 - alp4* zwk*rmo )**0.2 - els1 = karman*z_m*( 1.0 - alp4* zwk*rmo )**0.2 END IF ! ** NOW BLEND THE MIXING LENGTH SCALES: @@ -2200,8 +2071,7 @@ SUBROUTINE mym_length ( & !defined relative to the PBLH (zi) + transition layer (h1) !el(k) = MIN(elb/( elb/elt+elb/els+1.0 ),elf) !try squared-blending - !el_unstab = SQRT( els**2/(1. + (els1**2/elt**2) )) - el(k) = SQRT( els**2/(1. + (els1**2/elt**2) +(els1**2/elb**2))) + el(k) = SQRT( els**2/(1. + (els**2/elt**2) +(els**2/elb**2))) el(k) = MIN (el(k), elf) el(k) = el(k)*(1.-wt) + alp5*elBLavg(k)*wt @@ -2215,20 +2085,20 @@ SUBROUTINE mym_length ( & Uonset = 3.5 + dz(kts)*0.1 Ugrid = sqrt(u1(kts)**2 + v1(kts)**2) cns = 3.5 !JOE-test * (1.0 - MIN(MAX(Ugrid - Uonset, 0.0)/10.0, 1.0)) - alp1 = 0.21 + alp1 = 0.22 alp2 = 0.30 - alp3 = 1.5 + alp3 = 2.0 alp4 = 5.0 alp5 = alp2 !like alp2, but for free atmosphere alp6 = 50.0 !used for MF mixing length ! Impose limits on the height integration for elt and the transition layer depth !zi2=MAX(zi,minzi) - zi2=MAX(zi, 200.) + zi2=MAX(zi, 300.) !h1=MAX(0.3*zi2,mindz) !h1=MIN(h1,maxdz) ! 1/2 transition layer depth - h1=MAX(0.3*zi2,200.) - h1=MIN(h1,500.) + h1=MAX(0.3*zi2,300.) + h1=MIN(h1,600.) h2=h1*0.5 ! 1/4 transition layer depth qtke(kts)=MAX(0.5*qke(kts),0.01) !tke at full sigma levels @@ -2250,7 +2120,7 @@ SUBROUTINE mym_length ( & zwk = zw(k) DO WHILE (zwk .LE. PBLH_PLUS_ENT) dzk = 0.5*( dz(k)+dz(k-1) ) - qdz = MAX( qkw(k)-qmin, 0.03 )*dzk + qdz = min(max( qkw(k)-qmin, 0.03 ), 30.0)*dzk elt = elt +qdz*zwk vsc = vsc +qdz k = k+1 @@ -2258,7 +2128,9 @@ SUBROUTINE mym_length ( & END DO elt = MIN( MAX(alp1*elt/vsc, 10.), 400.) - vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq + !avoid use of buoyancy flux functions which are ill-defined at the surface + !vflx = ( vt(kts)+1.0 )*flt +( vq(kts)+tv0 )*flq + vflx = fltv vsc = ( gtr*elt*MAX( vflx, 0.0 ) )**onethird ! ** Strictly, el(i,j,1) is not zero. ** @@ -2276,7 +2148,7 @@ SUBROUTINE mym_length ( & bv = MAX( SQRT( gtr*dtv(k) ), 0.001) !elb_mf = alp2*qkw(k) / bv & elb_mf = MAX(alp2*qkw(k), & - & alp6*edmf_a1(k)*edmf_w1(k)) / bv & + & alp6*edmf_a1(k-1)*edmf_w1(k-1)) / bv & & *( 1.0 + alp3*SQRT( vsc/( bv*elt ) ) ) elb = MIN(MAX(alp5*qkw(k), alp6*edmf_a1(k)*edmf_w1(k))/bv, zwk) @@ -2321,33 +2193,24 @@ SUBROUTINE mym_length ( & elb_mf = elb END IF elf = elf/(1. + (elf/800.)) !bound free-atmos mixing length to < 800 m. -! elb_mf = elb_mf/(1. + (elb_mf/800.)) !bound buoyancy mixing length to < 800 m. elb_mf = MAX(elb_mf, 0.01) !to avoid divide-by-zero below - z_m = MAX(0.,zwk - 4.) - ! ** Length scale in the surface layer ** IF ( rmo .GT. 0.0 ) THEN els = karman*zwk/(1.0+cns*MIN( zwk*rmo, zmax )) - els1 = karman*z_m/(1.0+cns*MIN( zwk*rmo, zmax )) ELSE els = karman*zwk*( 1.0 - alp4* zwk*rmo )**0.2 - els1 = karman*z_m*( 1.0 - alp4* zwk*rmo )**0.2 END IF ! ** NOW BLEND THE MIXING LENGTH SCALES: wt=.5*TANH((zwk - (zi2+h1))/h2) + .5 - ! "el_unstab" = blended els-elt - !el_unstab = els/(1. + (els1/elt)) !try squared-blending - !el(k) = SQRT( els**2/(1. + (els1**2/elt**2) )) - el(k) = SQRT( els**2/(1. + (els1**2/elt**2) +(els1**2/elb_mf**2))) - !el(k) = MIN(el_unstab, elb_mf) + el(k) = SQRT( els**2/(1. + (els**2/elt**2) +(els**2/elb_mf**2))) el(k) = el(k)*(1.-wt) + elf*wt - ! include scale-awareness. For now, use simple asymptotic kz -> 12 m. - el_les= MIN(els/(1. + (els1/12.)), elb_mf) + ! include scale-awareness. For now, use simple asymptotic kz -> 12 m (should be ~dz). + el_les= MIN(els/(1. + (els/12.)), elb_mf) el(k) = el(k)*Psig_bl + (1.-Psig_bl)*el_les END DO @@ -2363,7 +2226,7 @@ SUBROUTINE mym_length ( & END SUBROUTINE mym_length ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine was taken from the BouLac scheme in WRF-ARW and modified for !! integration into the MYNN PBL scheme. WHILE loops were added to reduce the !! computational expense. This subroutine computes the length scales up and down @@ -2394,14 +2257,14 @@ SUBROUTINE boulac_length0(k,kts,kte,zw,dz,qtke,theta,lb1,lb2) !------------------------------------------------------------------- INTEGER, INTENT(IN) :: k,kts,kte - REAL, DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta - REAL, INTENT(OUT) :: lb1,lb2 - REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta + real(kind_phys), INTENT(OUT) :: lb1,lb2 + real(kind_phys), DIMENSION(kts:kte+1), INTENT(IN) :: zw !LOCAL VARS INTEGER :: izz, found - REAL :: dlu,dld - REAL :: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz + real(kind_phys):: dlu,dld + real(kind_phys):: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz !---------------------------------- @@ -2526,7 +2389,7 @@ SUBROUTINE boulac_length0(k,kts,kte,zw,dz,qtke,theta,lb1,lb2) END SUBROUTINE boulac_length0 ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine was taken from the BouLac scheme in WRF-ARW !! and modified for integration into the MYNN PBL scheme. !! WHILE loops were added to reduce the computational expense. @@ -2544,15 +2407,15 @@ SUBROUTINE boulac_length(kts,kte,zw,dz,qtke,theta,lb1,lb2) !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte - REAL, DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta - REAL, DIMENSION(kts:kte), INTENT(OUT) :: lb1,lb2 - REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: qtke,dz,theta + real(kind_phys), DIMENSION(kts:kte), INTENT(OUT):: lb1,lb2 + real(kind_phys), DIMENSION(kts:kte+1), INTENT(IN) :: zw !LOCAL VARS INTEGER :: iz, izz, found - REAL, DIMENSION(kts:kte) :: dlu,dld - REAL, PARAMETER :: Lmax=2000. !soft limit - REAL :: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz + real(kind_phys), DIMENSION(kts:kte) :: dlu,dld + real(kind_phys), PARAMETER :: Lmax=2000. !soft limit + real(kind_phys):: dzt, zup, beta, zup_inf, bbb, tl, zdo, zdo_sup, zzz !print*,"IN MYNN-BouLac",kts, kte @@ -2717,7 +2580,7 @@ END SUBROUTINE boulac_length ! # dtl, dqw, dtv, gm and gh are allowed to share storage units with ! dfm, dfh, dfq, tcd and qcd, respectively, for saving memory. ! -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the vertical diffusivity coefficients and the !! production terms for the turbulent quantities. !>\section gen_mym_turbulence GSD mym_turbulence General Algorithm @@ -2733,29 +2596,30 @@ END SUBROUTINE boulac_length !! - Production terms of TKE,\f$\theta^{'2}\f$,\f$q^{'2}\f$, and \f$\theta^{'}q^{'}\f$ !! are calculated. !! - Eddy diffusivity \f$K_h\f$ and eddy viscosity \f$K_m\f$ are calculated. -!! - TKE budget terms are calculated (if the namelist parameter \p bl_mynn_tkebudget +!! - TKE budget terms are calculated (if the namelist parameter \p tke_budget !! is set to True) SUBROUTINE mym_turbulence ( & & kts,kte, & - & closure, & + & xland,closure, & & dz, dx, zw, & & u, v, thl, thetav, ql, qw, & - & thlsg, qwsg, & & qke, tsq, qsq, cov, & & vt, vq, & - & rmo, flt, flq, & + & rmo, flt, fltv, flq, & & zi,theta, & & sh, sm, & & El, & & Dfm, Dfh, Dfq, Tcd, Qcd, Pdk, Pdt, Pdq, Pdc, & & qWT1D,qSHEAR1D,qBUOY1D,qDISS1D, & - & bl_mynn_tkebudget, & - & Psig_bl,Psig_shcu,cldfra_bl1D,bl_mynn_mixlength,& - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf, & + & tke_budget, & + & Psig_bl,Psig_shcu,cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1, & & TKEprodTD, & - & spp_pbl,rstoch_col) + & spp_pbl,rstoch_col ) + !------------------------------------------------------------------- -! + INTEGER, INTENT(IN) :: kts,kte #ifdef HARDCODE_VERTICAL @@ -2763,39 +2627,38 @@ SUBROUTINE mym_turbulence ( & # define kte HARDCODE_VERTICAL #endif - INTEGER, INTENT(IN) :: bl_mynn_mixlength,bl_mynn_edmf - REAL, INTENT(IN) :: closure - REAL, DIMENSION(kts:kte), INTENT(in) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(in) :: zw - REAL, INTENT(in) :: rmo,flt,flq,Psig_bl,Psig_shcu,dx - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,thl,thetav,qw,& - &ql,vt,vq,qke,tsq,qsq,cov,cldfra_bl1D,edmf_w1,edmf_a1,edmf_qc1,& - &TKEprodTD,thlsg,qwsg - - REAL, DIMENSION(kts:kte), INTENT(out) :: dfm,dfh,dfq,& + INTEGER, INTENT(IN) :: bl_mynn_mixlength,tke_budget + real(kind_phys), INTENT(IN) :: closure + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: zw + real(kind_phys), INTENT(in) :: rmo,flt,fltv,flq, & + &Psig_bl,Psig_shcu,xland,dx,zi + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v,thl,thetav,qw, & + &ql,vt,vq,qke,tsq,qsq,cov,cldfra_bl1D,edmf_w1,edmf_a1, & + &TKEprodTD + + real(kind_phys), DIMENSION(kts:kte), INTENT(out) :: dfm,dfh,dfq, & &pdk,pdt,pdq,pdc,tcd,qcd,el - REAL, DIMENSION(kts:kte), INTENT(inout) :: & + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: & qWT1D,qSHEAR1D,qBUOY1D,qDISS1D - REAL :: q3sq_old,dlsq1,qWTP_old,qWTP_new - REAL :: dudz,dvdz,dTdz,& - upwp,vpwp,Tpwp - LOGICAL, INTENT(in) :: bl_mynn_tkebudget + real(kind_phys):: q3sq_old,dlsq1,qWTP_old,qWTP_new + real(kind_phys):: dudz,dvdz,dTdz,upwp,vpwp,Tpwp - REAL, DIMENSION(kts:kte) :: qkw,dtl,dqw,dtv,gm,gh,sm,sh + real(kind_phys), DIMENSION(kts:kte) :: qkw,dtl,dqw,dtv,gm,gh,sm,sh INTEGER :: k -! REAL :: cc2,cc3,e1c,e2c,e3c,e4c,e5c - REAL :: e6c,dzk,afk,abk,vtt,vqq,& +! real(kind_phys):: cc2,cc3,e1c,e2c,e3c,e4c,e5c + real(kind_phys):: e6c,dzk,afk,abk,vtt,vqq, & &cw25,clow,cupp,gamt,gamq,smd,gamv,elq,elh - REAL :: zi, cldavg - REAL, DIMENSION(kts:kte), INTENT(in) :: theta + real(kind_phys):: cldavg + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: theta - REAL :: a2fac, duz, ri !JOE-Canuto/Kitamura mod + real(kind_phys):: a2fac, duz, ri !JOE-Canuto/Kitamura mod - REAL:: auh,aum,adh,adm,aeh,aem,Req,Rsl,Rsl2,& - gmelq,sm20,sh20,sm25max,sh25max,sm25min,sh25min,& + real:: auh,aum,adh,adm,aeh,aem,Req,Rsl,Rsl2, & + gmelq,sm20,sh20,sm25max,sh25max,sm25min,sh25min, & sm_pbl,sh_pbl,zi2,wt,slht,wtpr DOUBLE PRECISION q2sq, t2sq, r2sq, c2sq, elsq, gmel, ghel @@ -2803,11 +2666,10 @@ SUBROUTINE mym_turbulence ( & DOUBLE PRECISION e1, e2, e3, e4, enum, eden, wden ! Stochastic - INTEGER, INTENT(IN) :: spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col - REAL :: Prnum, Prlim - REAL, PARAMETER :: Prlimit = 5.0 - + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col + real(kind_phys):: Prnum, shb + real(kind_phys), PARAMETER :: Prlimit = 5.0 ! ! tv0 = 0.61*tref @@ -2825,21 +2687,21 @@ SUBROUTINE mym_turbulence ( & CALL mym_level2 (kts,kte, & & dz, & & u, v, thl, thetav, qw, & - & thlsg, qwsg, & & ql, vt, vq, & & dtl, dqw, dtv, gm, gh, sm, sh ) ! CALL mym_length ( & - & kts,kte, & + & kts,kte,xland, & & dz, dx, zw, & - & rmo, flt, flq, & + & rmo, flt, fltv, flq, & & vt, vq, & & u, v, qke, & & dtv, & & el, & & zi,theta, & - & qkw,Psig_bl,cldfra_bl1D,bl_mynn_mixlength, & - & edmf_w1,edmf_a1,edmf_qc1,bl_mynn_edmf ) + & qkw,Psig_bl,cldfra_bl1D, & + & bl_mynn_mixlength, & + & edmf_w1,edmf_a1 ) ! DO k = kts+1,kte @@ -3003,10 +2865,16 @@ SUBROUTINE mym_turbulence ( & !IF ( sm(k) > sm25max ) sm(k) = sm25max !IF ( sm(k) < sm25min ) sm(k) = sm25min !sm(k) = Prnum*sh(k) - slht = zi*0.1 - wtpr = min( max( (slht - zw(k))/slht, 0.0), 1.0) ! 1 at z=0, 0 above sfc layer - Prlim = 1.0*wtpr + (1.0 - wtpr)*Prlimit - sm(k) = MIN(sm(k), Prlimit*Sh(k)) + + !surface layer PR + !slht = zi*0.1 + !wtpr = min( max( (slht - zw(k))/slht, 0.0), 1.0) ! 1 at z=0, 0 above sfc layer + !Prlim = 1.0*wtpr + (1.0 - wtpr)*Prlimit + !Prlim = 2.0*wtpr + (1.0 - wtpr)*Prlimit + !sm(k) = MIN(sm(k), Prlim*Sh(k)) + !Pending more testing, keep same Pr limit in sfc layer + shb = max(sh(k), 0.002) + sm(k) = MIN(sm(k), Prlimit*shb) ! ** Level 3 : start ** IF ( closure .GE. 3.0 ) THEN @@ -3161,11 +3029,6 @@ SUBROUTINE mym_turbulence ( & ! with active plumes and clouds. cldavg = 0.5*(cldfra_bl1D(k-1) + cldfra_bl1D(k)) IF (edmf_a1(k) > 0.001 .OR. cldavg > 0.02) THEN - !sm(k) = MAX(sm(k), MAX(1.0 - 2.0*cldavg, 0.0)**0.33 * 0.03 * & - ! & MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) - !sh(k) = MAX(sh(k), MAX(1.0 - 2.0*cldavg, 0.0)**0.33 * 0.03 * & - ! & MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) - ! for mass-flux columns sm(k) = MAX(sm(k), 0.03*MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) sh(k) = MAX(sh(k), 0.03*MIN(10.*edmf_a1(k)*edmf_w1(k),1.0) ) @@ -3179,14 +3042,14 @@ SUBROUTINE mym_turbulence ( & ! Production of TKE (pdk), T-variance (pdt), ! q-variance (pdq), and covariance (pdc) - pdk(k) = elq*( sm(k)*gm(k) & - & +sh(k)*gh(k)+gamv ) + & + pdk(k) = elq*( sm(k)*gm(k) & + & +sh(k)*gh(k)+gamv ) + & & TKEprodTD(k) pdt(k) = elh*( sh(k)*dtl(k)+gamt )*dtl(k) pdq(k) = elh*( sh(k)*dqw(k)+gamq )*dqw(k) - pdc(k) = elh*( sh(k)*dtl(k)+gamt )& - &*dqw(k)*0.5 & - &+elh*( sh(k)*dqw(k)+gamq )*dtl(k)*0.5 + pdc(k) = elh*( sh(k)*dtl(k)+gamt ) & + & *dqw(k)*0.5 & + & + elh*( sh(k)*dqw(k)+gamq )*dtl(k)*0.5 ! Contergradient terms tcd(k) = elq*gamt @@ -3201,7 +3064,7 @@ SUBROUTINE mym_turbulence ( & dfq(k) = dfm(k) ! Modified: Dec/22/2005, up to here - IF ( bl_mynn_tkebudget ) THEN + IF (tke_budget .eq. 1) THEN !TKE BUDGET ! dudz = ( u(k)-u(k-1) )/dzk ! dvdz = ( v(k)-v(k-1) )/dzk @@ -3230,7 +3093,7 @@ SUBROUTINE mym_turbulence ( & !!!Dissipation Term (now it evaluated on mym_predict) !qDISS1D(k) = (q3sq**(3./2.))/(b1*MAX(el(k),1.)) !! ORIGINAL CODE - !! >> EOB + !! >> EOB ENDIF END DO @@ -3313,7 +3176,7 @@ END SUBROUTINE mym_turbulence ! scheme (program). ! !------------------------------------------------------------------- -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine predicts the turbulent quantities at the next step. SUBROUTINE mym_predict (kts,kte, & & closure, & @@ -3324,7 +3187,8 @@ SUBROUTINE mym_predict (kts,kte, & & pdk, pdt, pdq, pdc, & & qke, tsq, qsq, cov, & & s_aw,s_awqke,bl_mynn_edmf_tke, & - & qWT1D, qDISS1D,bl_mynn_tkebudget) !! TKE budget (Puhales, 2020) + & qWT1D, qDISS1D,tke_budget) !! TKE budget (Puhales, 2020) + !------------------------------------------------------------------- INTEGER, INTENT(IN) :: kts,kte @@ -3333,30 +3197,29 @@ SUBROUTINE mym_predict (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(IN) :: closure - INTEGER, INTENT(IN) :: bl_mynn_edmf_tke - REAL, INTENT(IN) :: delt - REAL, DIMENSION(kts:kte), INTENT(IN) :: dz, dfq, el, rho - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: pdk, pdt, pdq, pdc - REAL, INTENT(IN) :: flt, flq, ust, pmz, phh - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: qke,tsq, qsq, cov + real(kind_phys), INTENT(IN) :: closure + INTEGER, INTENT(IN) :: bl_mynn_edmf_tke,tke_budget + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: dz, dfq, el, rho + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: pdk, pdt, pdq, pdc + real(kind_phys), INTENT(IN) :: flt, flq, pmz, phh + real(kind_phys), INTENT(IN) :: ust, delt + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: qke,tsq, qsq, cov ! WA 8/3/15 - REAL, DIMENSION(kts:kte+1), INTENT(INOUT) :: s_awqke,s_aw + real(kind_phys), DIMENSION(kts:kte+1), INTENT(INOUT) :: s_awqke,s_aw !! TKE budget (Puhales, 2020, WRF 4.2.1) << EOB - REAL, DIMENSION(kts:kte), INTENT(OUT) :: qWT1D, qDISS1D - LOGICAL, INTENT(IN) :: bl_mynn_tkebudget - REAL, DIMENSION(kts:kte) :: tke_up,dzinv + real(kind_phys), DIMENSION(kts:kte), INTENT(OUT) :: qWT1D, qDISS1D + real(kind_phys), DIMENSION(kts:kte) :: tke_up,dzinv !! >> EOB INTEGER :: k - REAL, DIMENSION(kts:kte) :: qkw, bp, rp, df3q - REAL :: vkz,pdk1,phm,pdt1,pdq1,pdc1,b1l,b2l,onoff - REAL, DIMENSION(kts:kte) :: dtz - REAL, DIMENSION(kts:kte) :: a,b,c,d,x + real(kind_phys), DIMENSION(kts:kte) :: qkw, bp, rp, df3q + real(kind_phys):: vkz,pdk1,phm,pdt1,pdq1,pdc1,b1l,b2l,onoff + real(kind_phys), DIMENSION(kts:kte) :: dtz + real(kind_phys), DIMENSION(kts:kte) :: a,b,c,d,x - REAL, DIMENSION(kts:kte) :: rhoinv - REAL, DIMENSION(kts:kte+1) :: rhoz,kqdz,kmdz + real(kind_phys), DIMENSION(kts:kte) :: rhoinv + real(kind_phys), DIMENSION(kts:kte+1) :: rhoz,kqdz,kmdz ! REGULATE THE MOMENTUM MIXING FROM THE MASS-FLUX SCHEME (on or off) IF (bl_mynn_edmf_tke == 0) THEN @@ -3486,7 +3349,7 @@ SUBROUTINE mym_predict (kts,kte, & !! TKE budget (Puhales, 2020, WRF 4.2.1) << EOB - IF (bl_mynn_tkebudget) THEN + IF (tke_budget .eq. 1) THEN !! TKE Vertical transport << EOBvt tke_up=0.5*qke dzinv=1./dz @@ -3716,22 +3579,22 @@ END SUBROUTINE mym_predict ! Set these values to those adopted by you. ! !------------------------------------------------------------------- -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates the nonconvective component of the !! subgrid cloud fraction and mixing ratio as well as the functions used to !! calculate the buoyancy flux. Different cloud PDFs can be selected by !! use of the namelist parameter \p bl_mynn_cloudpdf . - SUBROUTINE mym_condensation (kts,kte, & - & dx, dz, zw, & - & thl, qw, qv, qc, qi, & - & p,exner, & - & tsq, qsq, cov, & - & Sh, el, bl_mynn_cloudpdf,& - & qc_bl1D, qi_bl1D, & - & cldfra_bl1D, & - & PBLH1,HFX1, & - & Vt, Vq, th, sgm, rmo, & - & spp_pbl,rstoch_col ) + SUBROUTINE mym_condensation (kts,kte, & + & dx, dz, zw, xland, & + & thl, qw, qv, qc, qi, qs, & + & p,exner, & + & tsq, qsq, cov, & + & Sh, el, bl_mynn_cloudpdf, & + & qc_bl1D, qi_bl1D, & + & cldfra_bl1D, & + & PBLH1,HFX1, & + & Vt, Vq, th, sgm, rmo, & + & spp_pbl,rstoch_col ) !------------------------------------------------------------------- @@ -3742,43 +3605,45 @@ SUBROUTINE mym_condensation (kts,kte, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(IN) :: dx,PBLH1,HFX1,rmo - REAL, DIMENSION(kts:kte), INTENT(IN) :: dz - REAL, DIMENSION(kts:kte+1), INTENT(IN) :: zw - REAL, DIMENSION(kts:kte), INTENT(IN) :: p,exner,thl,qw,qv,qc,qi, & - &tsq, qsq, cov, th + real(kind_phys), INTENT(IN) :: HFX1,rmo,xland + real(kind_phys), INTENT(IN) :: dx,pblh1 + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: dz + real(kind_phys), DIMENSION(kts:kte+1), INTENT(IN) :: zw + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: p,exner,thl,qw, & + &qv,qc,qi,qs,tsq,qsq,cov,th - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: vt,vq,sgm + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: vt,vq,sgm - REAL, DIMENSION(kts:kte) :: alp,a,bet,b,ql,q1,RH - REAL, DIMENSION(kts:kte), INTENT(OUT) :: qc_bl1D,qi_bl1D, & - cldfra_bl1D + real(kind_phys), DIMENSION(kts:kte) :: alp,a,bet,b,ql,q1,RH + real(kind_phys), DIMENSION(kts:kte), INTENT(OUT) :: qc_bl1D,qi_bl1D, & + &cldfra_bl1D DOUBLE PRECISION :: t3sq, r3sq, c3sq - REAL :: qsl,esat,qsat,dqsl,cld0,q1k,qlk,eq1,qll,& - &q2p,pt,rac,qt,t,xl,rsl,cpm,Fng,qww,alpha,beta,bb,& - &ls,wt,cld_factor,fac_damp,liq_frac,ql_ice,ql_water,& - &qmq,qsat_tk + real(kind_phys):: qsl,esat,qsat,dqsl,cld0,q1k,qlk,eq1,qll, & + &q2p,pt,rac,qt,t,xl,rsl,cpm,Fng,qww,alpha,beta,bb, & + &ls,wt,cld_factor,fac_damp,liq_frac,ql_ice,ql_water, & + &qmq,qsat_tk,q1_rh,rh_hack + real(kind_phys), PARAMETER :: rhcrit=0.83 !for hom pdf min sigma INTEGER :: i,j,k - REAL :: erf + real(kind_phys):: erf !VARIABLES FOR ALTERNATIVE SIGMA - REAL::dth,dtl,dqw,dzk,els - REAL, DIMENSION(kts:kte), INTENT(IN) :: Sh,el + real:: dth,dtl,dqw,dzk,els + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: Sh,el !variables for SGS BL clouds - REAL :: zagl,damp,PBLH2 - REAL :: lfac + real(kind_phys) :: zagl,damp,PBLH2 + real(kind_phys) :: cfmax !JAYMES: variables for tropopause-height estimation - REAL :: theta1, theta2, ht1, ht2 - INTEGER :: k_tropo + real(kind_phys) :: theta1, theta2, ht1, ht2 + INTEGER :: k_tropo ! Stochastic - INTEGER, INTENT(IN) :: spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col - REAL :: qw_pert + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col + real(kind_phys) :: qw_pert ! First, obtain an estimate for the tropopause height (k), using the method employed in the ! Thompson subgrid-cloud scheme. This height will be a consideration later when determining @@ -3854,9 +3719,6 @@ SUBROUTINE mym_condensation (kts,kte, & qc_bl1D(k) = liq_frac*ql(k) qi_bl1D(k) = (1.0 - liq_frac)*ql(k) - if(cldfra_bl1D(k)>0.01 .and. qc_bl1D(k)<1.E-6)qc_bl1D(k)=1.E-6 - if(cldfra_bl1D(k)>0.01 .and. qi_bl1D(k)<1.E-8)qi_bl1D(k)=1.E-8 - !Now estimate the buoyancy flux functions q2p = xlvcp/exner(k) pt = thl(k) +q2p*ql(k) ! potential temp @@ -3914,9 +3776,6 @@ SUBROUTINE mym_condensation (kts,kte, & qc_bl1D(k) = liq_frac*ql(k) qi_bl1D(k) = (1.0 - liq_frac)*ql(k) - if(cldfra_bl1D(k)>0.01 .and. qc_bl1D(k)<1.E-6)qc_bl1D(k)=1.E-6 - if(cldfra_bl1D(k)>0.01 .and. qi_bl1D(k)<1.E-8)qi_bl1D(k)=1.E-8 - !Now estimate the buoyancy flux functions q2p = xlvcp/exner(k) pt = thl(k) +q2p*ql(k) ! potential temp @@ -3945,7 +3804,7 @@ SUBROUTINE mym_condensation (kts,kte, & xl = xl_blend(t) ! obtain latent heat qsat_tk = qsat_blend(t, p(k)) ! saturation water vapor mixing ratio at tk and p - rh(k)=MAX(MIN(1.0,qw(k)/MAX(1.E-8,qsat_tk)),0.001) + rh(k)=MAX(MIN(1.00,qw(k)/MAX(1.E-10,qsat_tk)),0.001) !dqw/dT: Clausius-Clapeyron dqsl = qsat_tk*ep_2*xlv/( r_d*t**2 ) @@ -3966,101 +3825,93 @@ SUBROUTINE mym_condensation (kts,kte, & !Use the form of Eq. (6) in Chaboureau and Bechtold (2002) !except neglect all but the first term for sig_r - r3sq = MAX( qsq(k), 0.0 ) + r3sq = max( qsq(k), 0.0 ) !Calculate sigma using higher-order moments: sgm(k) = SQRT( r3sq ) !Set limits on sigma relative to saturation water vapor - sgm(k) = MIN( sgm(k), qsat_tk*0.666 ) !500 ) - sgm(k) = MAX( sgm(k), qsat_tk*0.040 ) !Note: 0.02 results in SWDOWN similar - !to the first-order version of sigma - q1(k) = qmq / sgm(k) ! Q1, the normalized saturation - - !Original C-B cloud fraction, allows cloud fractions out to q1 = -3.5 - cldfra_bl1D(K) = MAX(0., MIN(1., 0.5+0.36*ATAN(1.55*q1(k)))) ! Eq. 7 in CB02 - !This form only allows cloud fractions out to q1 = -1.8 - !cldfra_bl1D(K) = MAX(0., MIN(1., 0.5+0.41*ATAN(1.55*q1(k)))) - !This form only allows cloud fractions out to q1 = -1 - !cldfra_bl1D(K) = MAX(0., MIN(1., 0.5+0.50*ATAN(1.55*q1(k)))) + sgm(k) = min( sgm(k), qsat_tk*0.666 ) + sgm(k) = max( sgm(k), qsat_tk*0.035 ) + q1(k) = qmq / sgm(k) ! Q1, the normalized saturation + + !Add condition for falling/settling into low-RH layers, so at least + !some cloud fraction is applied for all qc and qi. + rh_hack = rh(k) + !ensure adequate RH & q1 when qi is at least 1e-9 + if (qi(k)>1.e-9) then + rh_hack =min(1.0, rhcrit + 0.06*(9.0 + log10(qi(k)))) + rh(k) =max(rh(k), rh_hack) + !add rh-based q1 + q1_rh =-3. + 3.*(rh_hack-rhcrit)/(1.-rhcrit) + q1(k) =max(q1_rh, q1(k) ) + endif + !ensure adequate RH & q1 when qc is at least 1e-6 + if (qc(k)>1.e-6) then + rh_hack =min(1.0, rhcrit + 0.09*(6.0 + log10(qc(k)))) + rh(k) =max(rh(k), rh_hack) + !add rh-based q1 + q1_rh =-3. + 3.*(rh_hack-rhcrit)/(1.-rhcrit) + q1(k) =max(q1_rh, q1(k) ) + endif - END DO + q1k = q1(k) ! backup Q1 for later modification - ! Specify hydrometeors - ! JAYMES- this option added 8 May 2015 - ! The cloud water formulations are taken from CB02, Eq. 8. - ! "fng" represents the non-Gaussian contribution to the liquid - ! water flux; these formulations are from Cuijpers and Bechtold - ! (1995), Eq. 7. CB95 also draws from Bechtold et al. 1995, - ! hereafter BCMT95 - zagl = 0. - DO k = kts,kte-1 - t = th(k)*exner(k) - q1k = q1(k) - zagl = zagl + dz(k) + ! Specify cloud fraction + !Original C-B cloud fraction, allows cloud fractions out to q1 = -3.5 + !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.55*q1(k)))) ! Eq. 7 in CB02 + !Waynes LES fit - over-diffuse, when limits removed from vt & vq & fng + !cldfra_bl1D(K) = max(0., min(1., 0.5+0.36*atan(1.2*(q1(k)+0.4)))) + !Best compromise: Improves marine stratus without adding much cold bias. + cldfra_bl1D(k) = max(0., min(1., 0.5+0.36*atan(1.8*(q1(k)+0.2)))) - !CLOUD WATER AND ICE + ! Specify hydrometeors + ! JAYMES- this option added 8 May 2015 + ! The cloud water formulations are taken from CB02, Eq. 8. IF (q1k < 0.) THEN !unsaturated #ifdef SINGLE_PREC ql_water = sgm(k)*EXP(1.2*q1k-1.) #else - ql_water = sgm(k)*EXP(1.2*q1k-1) + ql_water = sgm(k)*EXP(1.2*q1k-1.) #endif ql_ice = sgm(k)*EXP(1.2*q1k-1.) ELSE IF (q1k > 2.) THEN !supersaturated ql_water = sgm(k)*q1k ql_ice = sgm(k)*q1k - !ql_ice = MIN(80.*qv(k),0.1)*sgm(k)*q1k ELSE !slightly saturated (0 > q1 < 2) ql_water = sgm(k)*(EXP(-1.) + 0.66*q1k + 0.086*q1k**2) ql_ice = sgm(k)*(EXP(-1.) + 0.66*q1k + 0.086*q1k**2) - !ql_ice = MIN(80.*qv(k),0.1)*sgm(k)*(EXP(-1.) + 0.66*q1k + 0.086*q1k**2) ENDIF - !In saturated grid cells, use average of current estimate and prev time step - IF ( qc(k) > 1.e-7 ) ql_water = 0.5 * ( ql_water + qc(k) ) - IF ( qi(k) > 1.e-9 ) ql_ice = 0.5 * ( ql_ice + qi(k) ) + !In saturated grid cells, use average of SGS and resolved values + !if ( qc(k) > 1.e-6 ) ql_water = 0.5 * ( ql_water + qc(k) ) + !ql_ice is actually the total frozen condensate (snow+ice), + !if ( (qi(k)+qs(k)) > 1.e-9 ) ql_ice = 0.5 * ( ql_ice + (qi(k)+qs(k)) ) - IF (cldfra_bl1D(k) < 0.01) THEN + if (cldfra_bl1D(k) < 0.001) then ql_ice = 0.0 ql_water = 0.0 cldfra_bl1D(k) = 0.0 - ENDIF - - !PHASE PARTITIONING: Make some inferences about the relative amounts of - !subgrid cloud water vs. ice based on collocated explicit clouds. Otherise, - !use a simple temperature-dependent partitioning. -! IF ( qc(k) + qi(k) > 0.0 ) THEN ! explicit condensate exists, retain its phase partitioning -! IF ( qi(k) == 0.0 ) THEN ! explicit contains no ice; assume subgrid liquid -! liq_frac = 1.0 -! ELSE IF ( qc(k) == 0.0 ) THEN ! explicit contains no liquid; assume subgrid ice -! liq_frac = 0.0 -! ELSE IF ( (qc(k) >= 1.E-10) .AND. (qi(k) >= 1.E-10) ) THEN ! explicit contains mixed phase of workably -! ! large amounts; assume subgrid follows -! ! same partioning -! liq_frac = qc(k) / ( qc(k) + qi(k) ) -! ELSE -! liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(t0c-tice))) ! explicit contains mixed phase, but at least one -! ! species is very small, so make a temperature- -! ! depedent guess -! ENDIF -! ELSE ! no explicit condensate, so make a temperature-dependent guess - liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(t0c-tice))) -! ENDIF + endif + liq_frac = MIN(1.0, MAX(0.0, (t-tice)/(tliq-tice))) qc_bl1D(k) = liq_frac*ql_water ! apply liq_frac to ql_water and ql_ice qi_bl1D(k) = (1.0-liq_frac)*ql_ice - !Above tropopause: eliminate subgrid clouds from CB scheme - if (k .ge. k_tropo-1) then + !Above tropopause: eliminate subgrid clouds from CB scheme. Note that this was + !"k_tropo - 1" as of 20 Feb 2023. Changed to allow more high-level clouds. + if (k .ge. k_tropo) then cldfra_bl1D(K) = 0. - qc_bl1D(k) = 0. - qi_bl1D(k) = 0. + qc_bl1D(k) = 0. + qi_bl1D(k) = 0. endif - ENDDO - - !Buoyancy-flux-related calculations follow... - DO k = kts,kte-1 - t = th(k)*exner(k) + !Buoyancy-flux-related calculations follow... + !limiting Q1 to avoid too much diffusion in cloud layers + !q1k=max(Q1(k),-2.0) + if ((xland-1.5).GE.0) then ! water + q1k=max(Q1(k),-2.5) + else ! land + q1k=max(Q1(k),-2.0) + endif ! "Fng" represents the non-Gaussian transport factor ! (non-dimensional) from Bechtold et al. 1995 ! (hereafter BCMT95), section 3(c). Their suggested @@ -4072,8 +3923,7 @@ SUBROUTINE mym_condensation (kts,kte, & !ELSE ! Fng = 1.-1.5*q1k !ENDIF - !limiting to avoid mixing away stratus, was -5 - q1k=MAX(Q1(k),-1.0) + ! Use the form of "Fng" from Bechtold and Siebesma (1998, JAS) IF (q1k .GE. 1.0) THEN Fng = 1.0 ELSEIF (q1k .GE. -1.7 .AND. q1k .LT. 1.0) THEN @@ -4083,42 +3933,36 @@ SUBROUTINE mym_condensation (kts,kte, & ELSE Fng = MIN(23.9 + EXP(-1.6*(q1k+2.5)), 60.) ENDIF - Fng = MIN(Fng, 20.) - xl = xl_blend(t) - bb = b(k)*t/th(k) ! bb is "b" in BCMT95. Their "b" differs from - ! "b" in CB02 (i.e., b(k) above) by a factor + cfmax= min(cldfra_bl1D(k), 0.6) + bb = b(k)*t/th(k) ! bb is "b" in BCMT95. Their "b" differs from + ! "b" in CB02 (i.e., b(k) above) by a factor ! of T/theta. Strictly, b(k) above is formulated in ! terms of sat. mixing ratio, but bb in BCMT95 is ! cast in terms of sat. specific humidity. The - ! conversion is neglected here. + ! conversion is neglected here. qww = 1.+0.61*qw(k) alpha = 0.61*th(k) beta = (th(k)/t)*(xl/cp) - 1.61*th(k) - vt(k) = qww - MIN(cldfra_bl1D(K),0.5)*beta*bb*Fng - 1. - vq(k) = alpha + MIN(cldfra_bl1D(K),0.5)*beta*a(k)*Fng - tv0 + vt(k) = qww - cfmax*beta*bb*Fng - 1. + vq(k) = alpha + cfmax*beta*a(k)*Fng - tv0 ! vt and vq correspond to beta-theta and beta-q, respectively, ! in NN09, Eq. B8. They also correspond to the bracketed ! expressions in BCMT95, Eq. 15, since (s*ql/sigma^2) = cldfra*Fng ! The "-1" and "-tv0" terms are included for consistency with ! the legacy vt and vq formulations (above). - ! dampen the amplification factor (cld_factor) with height in order - ! to limit excessively large cloud fractions aloft - !fac_damp = 1.! -MIN(MAX( zagl-(PBLH2+1000.),0.0)/ & - ! MAX((zw(k_tropo)-(PBLH2+1000.)),500.), 1.) - fac_damp = min(zagl * 0.01, 1.0) - !cld_factor = 1.0 + fac_damp*MAX(0.0, ( RH(k) - 0.5 ) / 0.51 )**3.3 + ! dampen amplification factor where need be + fac_damp = min(zagl * 0.0025, 1.0) !cld_factor = 1.0 + fac_damp*MAX(0.0, ( RH(k) - 0.75 ) / 0.26 )**1.9 !HRRRv4 - !cld_factor = 1.0 + fac_damp*(MAX(0.0, ( RH(k) - 0.80 )) / 0.22 )**2 - cld_factor = 1.0 + fac_damp*(MAX(0.0, ( RH(k) - 0.90 )) / 0.11 )**2 - !cld_factor = 1.0 - cldfra_bl1D(K) = MIN( 1., cld_factor*cldfra_bl1D(K) ) - ENDDO + !cld_factor = 1.0 + fac_damp*min((max(0.0, ( RH(k) - 0.92 )) / 0.25 )**2, 0.3) + cld_factor = 1.0 + fac_damp*min((max(0.0, ( RH(k) - 0.92 )) / 0.145)**2, 0.35) + cldfra_bl1D(K) = min( 1., cld_factor*cldfra_bl1D(K) ) + enddo END SELECT !end cloudPDF option - !FOR TESTING PURPOSES ONLY, ISOLATE ON THE MASS-CLOUDS. + !For testing purposes only, option for isolating on the mass-flux clouds. IF (bl_mynn_cloudpdf .LT. 0) THEN DO k = kts,kte-1 cldfra_bl1D(k) = 0.0 @@ -4143,42 +3987,42 @@ SUBROUTINE mym_condensation (kts,kte, & END SUBROUTINE mym_condensation ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine solves for tendencies of U, V, \f$\theta\f$, qv, !! qc, and qi - SUBROUTINE mynn_tendencies(kts,kte,i, & - &closure, & - &delt,dz,rho, & - &u,v,th,tk,qv,qc,qi,qnc,qni, & - &psfc,p,exner, & - &thl,sqv,sqc,sqi,sqw, & - &qnwfa,qnifa,ozone, & - &ust,flt,flq,flqv,flqc,wspd, & - &uoce,voce, & - &tsq,qsq,cov, & - &tcd,qcd, & - &dfm,dfh,dfq, & - &Du,Dv,Dth,Dqv,Dqc,Dqi,Dqnc,Dqni, & - &Dqnwfa,Dqnifa,Dozone, & - &vdfg1,diss_heat, & - &s_aw,s_awthl,s_awqt,s_awqv,s_awqc, & - &s_awu,s_awv, & - &s_awqnc,s_awqni, & - &s_awqnwfa,s_awqnifa, & - &sd_aw,sd_awthl,sd_awqt,sd_awqv, & - &sd_awqc,sd_awu,sd_awv, & - &sub_thl,sub_sqv, & - &sub_u,sub_v, & - &det_thl,det_sqv,det_sqc, & - &det_u,det_v, & - &FLAG_QC,FLAG_QI,FLAG_QNC,FLAG_QNI, & - &FLAG_QNWFA,FLAG_QNIFA, & - &cldfra_bl1d, & - &bl_mynn_cloudmix, & - &bl_mynn_mixqt, & - &bl_mynn_edmf, & - &bl_mynn_edmf_mom, & - &bl_mynn_mixscalars ) + SUBROUTINE mynn_tendencies(kts,kte,i, & + &delt,dz,rho, & + &u,v,th,tk,qv,qc,qi,qs,qnc,qni, & + &psfc,p,exner, & + &thl,sqv,sqc,sqi,sqs,sqw, & + &qnwfa,qnifa,qnbca,ozone, & + &ust,flt,flq,flqv,flqc,wspd, & + &uoce,voce, & + &tsq,qsq,cov, & + &tcd,qcd, & + &dfm,dfh,dfq, & + &Du,Dv,Dth,Dqv,Dqc,Dqi,Dqs,Dqnc,Dqni, & + &Dqnwfa,Dqnifa,Dqnbca,Dozone, & + &diss_heat, & + &s_aw,s_awthl,s_awqt,s_awqv,s_awqc, & + &s_awu,s_awv, & + &s_awqnc,s_awqni, & + &s_awqnwfa,s_awqnifa,s_awqnbca, & + &sd_aw,sd_awthl,sd_awqt,sd_awqv, & + &sd_awqc,sd_awu,sd_awv, & + &sub_thl,sub_sqv, & + &sub_u,sub_v, & + &det_thl,det_sqv,det_sqc, & + &det_u,det_v, & + &FLAG_QC,FLAG_QI,FLAG_QNC,FLAG_QNI, & + &FLAG_QS, & + &FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA, & + &cldfra_bl1d, & + &bl_mynn_cloudmix, & + &bl_mynn_mixqt, & + &bl_mynn_edmf, & + &bl_mynn_edmf_mom, & + &bl_mynn_mixscalars ) !------------------------------------------------------------------- INTEGER, INTENT(in) :: kts,kte,i @@ -4188,12 +4032,11 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(in) :: closure - INTEGER, INTENT(in) :: bl_mynn_cloudmix,bl_mynn_mixqt,& - bl_mynn_edmf,bl_mynn_edmf_mom, & + INTEGER, INTENT(in) :: bl_mynn_cloudmix,bl_mynn_mixqt, & + bl_mynn_edmf,bl_mynn_edmf_mom, & bl_mynn_mixscalars - LOGICAL, INTENT(IN) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QNC,& - FLAG_QNWFA,FLAG_QNIFA + LOGICAL, INTENT(IN) :: FLAG_QI,FLAG_QNI,FLAG_QC,FLAG_QS, & + &FLAG_QNC,FLAG_QNWFA,FLAG_QNIFA,FLAG_QNBCA ! thl - liquid water potential temperature ! qw - total water @@ -4202,47 +4045,47 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ! flq - surface flux of qw ! mass-flux plumes - REAL, DIMENSION(kts:kte+1), INTENT(in) :: s_aw,s_awthl,s_awqt,& - &s_awqnc,s_awqni,s_awqv,s_awqc,s_awu,s_awv, & - &s_awqnwfa,s_awqnifa, & + real(kind_phys), DIMENSION(kts:kte+1), INTENT(in) :: s_aw, & + &s_awthl,s_awqt,s_awqnc,s_awqni,s_awqv,s_awqc,s_awu,s_awv, & + &s_awqnwfa,s_awqnifa,s_awqnbca, & &sd_aw,sd_awthl,sd_awqt,sd_awqv,sd_awqc,sd_awu,sd_awv ! tendencies from mass-flux environmental subsidence and detrainment - REAL, DIMENSION(kts:kte), INTENT(in) :: sub_thl,sub_sqv, & + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: sub_thl,sub_sqv, & &sub_u,sub_v,det_thl,det_sqv,det_sqc,det_u,det_v - REAL, DIMENSION(kts:kte), INTENT(in) :: u,v,th,tk,qv,qc,qi,qni,qnc,& - &rho,p,exner,dfq,dz,tsq,qsq,cov,tcd,qcd,cldfra_bl1d,diss_heat - REAL, DIMENSION(kts:kte), INTENT(inout) :: thl,sqw,sqv,sqc,sqi,& - &qnwfa,qnifa,ozone,dfm,dfh - REAL, DIMENSION(kts:kte), INTENT(inout) :: du,dv,dth,dqv,dqc,dqi,& - &dqni,dqnc,dqnwfa,dqnifa,dozone - REAL, INTENT(IN) :: delt,ust,flt,flq,flqv,flqc,wspd,uoce,voce,& - &psfc + real(kind_phys), DIMENSION(kts:kte), INTENT(in) :: u,v,th,tk,qv,qc,qi,& + &qs,qni,qnc,rho,p,exner,dfq,dz,tsq,qsq,cov,tcd,qcd, & + &cldfra_bl1d,diss_heat + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: thl,sqw,sqv,sqc,& + &sqi,sqs,qnwfa,qnifa,qnbca,ozone,dfm,dfh + real(kind_phys), DIMENSION(kts:kte), INTENT(inout) :: du,dv,dth,dqv, & + &dqc,dqi,dqs,dqni,dqnc,dqnwfa,dqnifa,dqnbca,dozone + real(kind_phys), INTENT(IN) :: flt,flq,flqv,flqc,uoce,voce + real(kind_phys), INTENT(IN) :: ust,delt,psfc,wspd !debugging - REAL ::wsp,wsp2 + real(kind_phys):: wsp,wsp2,tk2,th2 LOGICAL :: problem integer :: kproblem -! REAL, INTENT(IN) :: gradu_top,gradv_top,gradth_top,gradqv_top +! real(kind_phys), INTENT(IN) :: gradu_top,gradv_top,gradth_top,gradqv_top !local vars - REAL, DIMENSION(kts:kte) :: dtz,dfhc,dfmc,delp - REAL, DIMENSION(kts:kte) :: sqv2,sqc2,sqi2,sqw2,qni2,qnc2, & !AFTER MIXING - qnwfa2,qnifa2,ozone2 - REAL, DIMENSION(kts:kte) :: zfac,plumeKh,rhoinv - REAL, DIMENSION(kts:kte) :: a,b,c,d,x - REAL, DIMENSION(kts:kte+1) :: rhoz, & !rho on model interface - & khdz, kmdz - REAL :: rhs,gfluxm,gfluxp,dztop,maxdfh,mindfh,maxcf,maxKh,zw - REAL :: vdfg1 !Katata-fogdes - REAL :: t,esat,qsl,onoff,kh,km,dzk,rhosfc - REAL :: ustdrag,ustdiff,qvflux - REAL :: th_new,portion_qc,portion_qi,condensate,qsat + real(kind_phys), DIMENSION(kts:kte) :: dtz,dfhc,dfmc,delp + real(kind_phys), DIMENSION(kts:kte) :: sqv2,sqc2,sqi2,sqs2,sqw2, & + &qni2,qnc2,qnwfa2,qnifa2,qnbca2,ozone2 + real(kind_phys), DIMENSION(kts:kte) :: zfac,plumeKh,rhoinv + real(kind_phys), DIMENSION(kts:kte) :: a,b,c,d,x + real(kind_phys), DIMENSION(kts:kte+1) :: rhoz, & !rho on model interface + &khdz,kmdz + real(kind_phys):: rhs,gfluxm,gfluxp,dztop,maxdfh,mindfh,maxcf,maxKh,zw + real(kind_phys):: t,esat,qsl,onoff,kh,km,dzk,rhosfc + real(kind_phys):: ustdrag,ustdiff,qvflux + real(kind_phys):: th_new,portion_qc,portion_qi,condensate,qsat INTEGER :: k,kk !Activate nonlocal mixing from the mass-flux scheme for !number concentrations and aerosols (0.0 = no; 1.0 = yes) - REAL, PARAMETER :: nonloc = 1.0 + real(kind_phys), PARAMETER :: nonloc = 1.0 dztop=.5*(dz(kte)+dz(kte-1)) @@ -4352,7 +4195,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=u(kte) ! CALL tridiag(kte,a,b,c,d) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte ! du(k)=(d(k-kts+1)-u(k))/delt @@ -4416,7 +4260,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=v(kte) ! CALL tridiag(kte,a,b,c,d) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte ! dv(k)=(d(k-kts+1)-v(k))/delt @@ -4483,8 +4328,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=thl(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !thl(k)=d(k-kts+1) @@ -4546,8 +4391,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqw(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqw2) - CALL tridiag3(kte,a,b,c,d,sqw2) + CALL tridiag2(kte,a,b,c,d,sqw2) +! CALL tridiag3(kte,a,b,c,d,sqw2) ! DO k=kts,kte ! sqw2(k)=d(k-kts+1) @@ -4603,8 +4448,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqc(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqc2) - CALL tridiag3(kte,a,b,c,d,sqc2) + CALL tridiag2(kte,a,b,c,d,sqc2) +! CALL tridiag3(kte,a,b,c,d,sqc2) ! DO k=kts,kte ! sqc2(k)=d(k-kts+1) @@ -4681,8 +4526,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqv(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqv2) - CALL tridiag3(kte,a,b,c,d,sqv2) + CALL tridiag2(kte,a,b,c,d,sqv2) +! CALL tridiag3(kte,a,b,c,d,sqv2) ! DO k=kts,kte ! sqv2(k)=d(k-kts+1) @@ -4697,19 +4542,6 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & IF (bl_mynn_cloudmix > 0 .AND. FLAG_QI) THEN k=kts - -! a(k)=0. -! b(k)=1.+dtz(k)*dfh(k+1) -! c(k)= -dtz(k)*dfh(k+1) -! d(k)=sqi(k) !+ qcd(k)*delt !should we have qcd for ice? -! -! DO k=kts+1,kte-1 -! a(k)= -dtz(k)*dfh(k) -! b(k)=1.+dtz(k)*(dfh(k)+dfh(k+1)) -! c(k)= -dtz(k)*dfh(k+1) -! d(k)=sqi(k) !+ qcd(k)*delt -! ENDDO - !rho-weighted: a(k)= -dtz(k)*khdz(k)*rhoinv(k) b(k)=1.+dtz(k)*(khdz(k+1)+khdz(k))*rhoinv(k) @@ -4743,8 +4575,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=sqi(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,sqi2) - CALL tridiag3(kte,a,b,c,d,sqi2) + CALL tridiag2(kte,a,b,c,d,sqi2) +! CALL tridiag3(kte,a,b,c,d,sqi2) ! DO k=kts,kte ! sqi2(k)=d(k-kts+1) @@ -4753,6 +4585,42 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & sqi2=sqi ENDIF +!============================================ +! MIX SNOW ( sqs ) +!============================================ +IF (bl_mynn_cloudmix > 0 .AND. FLAG_QS) THEN + + k=kts +!rho-weighted: + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + b(k)=1.+dtz(k)*(khdz(k+1)+khdz(k))*rhoinv(k) + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) + d(k)=sqs(k) + + DO k=kts+1,kte-1 + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + b(k)=1.+dtz(k)*(khdz(k)+khdz(k+1))*rhoinv(k) + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) + d(k)=sqs(k) + ENDDO + +!! prescribed value + a(kte)=0. + b(kte)=1. + c(kte)=0. + d(kte)=sqs(kte) + +! CALL tridiag(kte,a,b,c,d) + CALL tridiag2(kte,a,b,c,d,sqs2) +! CALL tridiag3(kte,a,b,c,d,sqs2) + +! DO k=kts,kte +! sqs2(k)=d(k-kts+1) +! ENDDO +ELSE + sqs2=sqs +ENDIF + !!============================================ !! cloud ice number concentration (qni) !!============================================ @@ -4781,8 +4649,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qni(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qni2(k)=d(k-kts+1) @@ -4799,6 +4667,7 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & !!============================================ IF (bl_mynn_cloudmix > 0 .AND. FLAG_QNC .AND. & bl_mynn_mixscalars > 0) THEN + k=kts a(k)= -dtz(k)*khdz(k)*rhoinv(k) @@ -4821,8 +4690,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qnc(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qnc2(k)=d(k-kts+1) @@ -4862,8 +4731,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qnwfa(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qnwfa2(k)=d(k) @@ -4904,8 +4773,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=qnifa(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !qnifa2(k)=d(k-kts+1) @@ -4917,6 +4786,48 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & qnifa2=qnifa ENDIF +!============================================ +! Black-carbon aerosols ( qnbca ). +!============================================ +IF (bl_mynn_cloudmix > 0 .AND. FLAG_QNBCA .AND. & + bl_mynn_mixscalars > 0) THEN + + k=kts + + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + b(k)=1.+dtz(k)*(khdz(k) + khdz(k+1))*rhoinv(k) - & + & 0.5*dtz(k)*rhoinv(k)*s_aw(k+1)*nonloc + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1)*nonloc + d(k)=qnbca(k) - dtz(k)*rhoinv(k)*s_awqnbca(k+1)*nonloc + + DO k=kts+1,kte-1 + a(k)= -dtz(k)*khdz(k)*rhoinv(k) + 0.5*dtz(k)*rhoinv(k)*s_aw(k)*nonloc + b(k)=1.+dtz(k)*(khdz(k) + khdz(k+1))*rhoinv(k) + & + & 0.5*dtz(k)*rhoinv(k)*(s_aw(k)-s_aw(k+1))*nonloc + c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1)*nonloc + d(k)=qnbca(k) + dtz(k)*rhoinv(k)*(s_awqnbca(k)-s_awqnbca(k+1))*nonloc + ENDDO + +! prescribed value + a(kte)=0. + b(kte)=1. + c(kte)=0. + d(kte)=qnbca(kte) + +! CALL tridiag(kte,a,b,c,d) +! CALL tridiag2(kte,a,b,c,d,x) + CALL tridiag3(kte,a,b,c,d,x) + + DO k=kts,kte + !qnbca2(k)=d(k-kts+1) + qnbca2(k)=x(k) + ENDDO + +ELSE + !If not mixing aerosols, set "updated" array equal to original array + qnbca2=qnbca +ENDIF + !============================================ ! Ozone - local mixing only !============================================ @@ -4943,8 +4854,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & d(kte)=ozone(kte) ! CALL tridiag(kte,a,b,c,d) -! CALL tridiag2(kte,a,b,c,d,x) - CALL tridiag3(kte,a,b,c,d,x) + CALL tridiag2(kte,a,b,c,d,x) +! CALL tridiag3(kte,a,b,c,d,x) DO k=kts,kte !ozone2(k)=d(k-kts+1) @@ -5041,6 +4952,19 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ENDDO ENDIF + !=================== + ! CLOUD SNOW TENDENCY + !=================== + IF (FLAG_QS) THEN + DO k=kts,kte + Dqs(k)=(sqs2(k)/(1.-sqs2(k)) - qs(k))/delt + ENDDO + ELSE + DO k=kts,kte + Dqs(k) = 0. + ENDDO + ENDIF + !=================== ! CLOUD ICE NUM CONC TENDENCY !=================== @@ -5065,9 +4989,9 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ENDIF !ensure non-negative moist species - CALL moisture_check(kte, delt, delp, exner, & - sqv2, sqc2, sqi2, thl, & - dqv, dqc, dqi, dth ) + CALL moisture_check(kte, delt, delp, exner, & + sqv2, sqc2, sqi2, sqs2, thl, & + dqv, dqc, dqi, dqs, dth ) !===================== ! OZONE TENDENCY CHECK @@ -5083,8 +5007,8 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & !=================== IF (FLAG_QI) THEN DO k=kts,kte - Dth(k)=(thl(k) + xlvcp/exner(k)*sqc2(k) & - & + xlscp/exner(k)*sqi2(k) & + Dth(k)=(thl(k) + xlvcp/exner(k)*sqc2(k) & + & + xlscp/exner(k)*(sqi2(k)+sqs(k)) & & - th(k))/delt !Use form from Tripoli and Cotton (1981) with their !suggested min temperature to improve accuracy: @@ -5124,6 +5048,19 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & ENDDO ENDIF + !======================== + ! BLACK-CARBON TENDENCIES + !======================== + IF (FLAG_QNBCA .AND. bl_mynn_mixscalars > 0) THEN + DO k=kts,kte + Dqnbca(k)=(qnbca2(k) - qnbca(k))/delt + ENDDO + ELSE + DO k=kts,kte + Dqnbca(k)=0. + ENDDO + ENDIF + !ensure non-negative moist species !note: if called down here, dth needs to be updated, but ! if called before the theta-tendency calculation, do not compute dth @@ -5136,21 +5073,28 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & do k=kts,kte wsp = sqrt(u(k)**2 + v(k)**2) wsp2 = sqrt((u(k)+du(k)*delt)**2 + (v(k)+du(k)*delt)**2) - if (wsp2 > 200.) then + th2 = th(k) + Dth(k)*delt + tk2 = th2*exner(k) + if (wsp2 > 200. .or. tk2 > 360. .or. tk2 < 160.) then problem = .true. - print*,"Huge wind speed: i=",i," k=",k," wsp=",wsp2 - print*," du=",du(k)*delt," dv=",dv(k)*delt + print*,"Outgoing problem at: i=",i," k=",k + print*," incoming wsp=",wsp," outgoing wsp=",wsp2 + print*," incoming T=",th(k)*exner(k),"outgoing T:",tk2 + print*," du=",du(k)*delt," dv=",dv(k)*delt," dth=",dth(k)*delt print*," km=",kmdz(k)*dz(k)," kh=",khdz(k)*dz(k) print*," u*=",ust," wspd=",wspd,"rhosfc=",rhosfc + print*," LH=",flq*rhosfc*1004.," HFX=",flt*rhosfc*1004. print*," drag term=",ust**2/wspd*dtz(k)*rhosfc/rho(kts) kproblem = k endif enddo if (problem) then - print*,"=temp:",thl(max(kproblem-5,1):min(kproblem+5,kte)) - print*,"===qv:",sqv(max(kproblem-5,1):min(kproblem+5,kte)) - print*,"====u:",u(max(kproblem-5,1):min(kproblem+5,kte)) - print*,"====v:",v(max(kproblem-5,1):min(kproblem+5,kte)) + print*,"==thl:",thl(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qv:",sqv2(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qc:",sqc2(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"===qi:",sqi2(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====u:",u(max(kproblem-3,1):min(kproblem+3,kte)) + print*,"====v:",v(max(kproblem-3,1):min(kproblem+3,kte)) endif endif @@ -5162,11 +5106,9 @@ SUBROUTINE mynn_tendencies(kts,kte,i, & END SUBROUTINE mynn_tendencies ! ================================================================== -!>\ingroup gp_mynnedmf -!!ensure non-negative moist species. - SUBROUTINE moisture_check(kte, delt, dp, exner, & - qv, qc, qi, th, & - dqv, dqc, dqi, dth ) + SUBROUTINE moisture_check(kte, delt, dp, exner, & + qv, qc, qi, qs, th, & + dqv, dqc, dqi, dqs, dth ) ! This subroutine was adopted from the CAM-UW ShCu scheme and ! adapted for use here. @@ -5182,33 +5124,36 @@ SUBROUTINE moisture_check(kte, delt, dp, exner, & ! applying corresponding input tendencies and corrective tendencies. implicit none - integer, intent(in) :: kte - real, intent(in) :: delt - real, dimension(kte), intent(in) :: dp, exner - real, dimension(kte), intent(inout) :: qv, qc, qi, th - real, dimension(kte), intent(inout) :: dqv, dqc, dqi, dth + integer, intent(in) :: kte + real(kind_phys), intent(in) :: delt + real(kind_phys), dimension(kte), intent(in) :: dp, exner + real(kind_phys), dimension(kte), intent(inout) :: qv, qc, qi, qs, th + real(kind_phys), dimension(kte), intent(inout) :: dqv, dqc, dqi, dqs, dth integer k - real :: dqc2, dqi2, dqv2, sum, aa, dum - real, parameter :: qvmin = 1e-20, & - qcmin = 0.0, & - qimin = 0.0 + real(kind_phys):: dqc2, dqi2, dqs2, dqv2, sum, aa, dum + real(kind_phys), parameter :: qvmin = 1e-20, & + qcmin = 0.0, & + qimin = 0.0 do k = kte, 1, -1 ! From the top to the surface dqc2 = max(0.0, qcmin-qc(k)) !qc deficit (>=0) dqi2 = max(0.0, qimin-qi(k)) !qi deficit (>=0) + dqs2 = max(0.0, qimin-qs(k)) !qs deficit (>=0) !fix tendencies dqc(k) = dqc(k) + dqc2/delt dqi(k) = dqi(k) + dqi2/delt - dqv(k) = dqv(k) - (dqc2+dqi2)/delt + dqs(k) = dqs(k) + dqs2/delt + dqv(k) = dqv(k) - (dqc2+dqi2+dqs2)/delt dth(k) = dth(k) + xlvcp/exner(k)*(dqc2/delt) + & - xlscp/exner(k)*(dqi2/delt) + xlscp/exner(k)*((dqi2+dqs2)/delt) !update species qc(k) = qc(k) + dqc2 qi(k) = qi(k) + dqi2 - qv(k) = qv(k) - dqc2 - dqi2 + qs(k) = qs(k) + dqs2 + qv(k) = qv(k) - dqc2 - dqi2 - dqs2 th(k) = th(k) + xlvcp/exner(k)*dqc2 + & - xlscp/exner(k)*dqi2 + xlscp/exner(k)*(dqi2+dqs2) !then fix qv dqv2 = max(0.0, qvmin-qv(k)) !qv deficit (>=0) @@ -5221,6 +5166,7 @@ SUBROUTINE moisture_check(kte, delt, dp, exner, & qv(k) = max(qv(k),qvmin) qc(k) = max(qc(k),qcmin) qi(k) = max(qi(k),qimin) + qs(k) = max(qs(k),qimin) end do ! Extra moisture used to satisfy 'qv(1)>=qvmin' is proportionally ! extracted from all the layers that has 'qv > 2*qvmin'. This fully @@ -5251,8 +5197,6 @@ END SUBROUTINE moisture_check ! ================================================================== -!>\ingroup gp_mynnedmf -!! SUBROUTINE mynn_mix_chem(kts,kte,i, & delt,dz,pblh, & nchem, kdvel, ndvel, & @@ -5261,40 +5205,40 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & flt, tcd, qcd, & dfh, & s_aw, s_awchem, & - emis_ant_no,frp, & - fire_turb ) + emis_ant_no, frp, rrfs_sd, & + enh_mix, smoke_dbg ) !------------------------------------------------------------------- INTEGER, INTENT(in) :: kts,kte,i - - REAL, DIMENSION(kts:kte), INTENT(IN) :: dfh,dz,tcd,qcd - REAL, DIMENSION(kts:kte), INTENT(INOUT) :: rho - REAL, INTENT(IN) :: delt,flt + real(kind_phys), DIMENSION(kts:kte), INTENT(IN) :: dfh,dz,tcd,qcd + real(kind_phys), DIMENSION(kts:kte), INTENT(INOUT) :: rho + real(kind_phys), INTENT(IN) :: flt + real(kind_phys), INTENT(IN) :: delt,pblh INTEGER, INTENT(IN) :: nchem, kdvel, ndvel - REAL, DIMENSION( kts:kte+1), INTENT(IN) :: s_aw - REAL, DIMENSION( kts:kte, nchem ), INTENT(INOUT) :: chem1 - REAL, DIMENSION( kts:kte+1,nchem), INTENT(IN) :: s_awchem - REAL, DIMENSION( ndvel ), INTENT(IN) :: vd1 - REAL, INTENT(IN) :: emis_ant_no,frp,pblh - LOGICAL, INTENT(IN) :: fire_turb + real(kind_phys), DIMENSION( kts:kte+1), INTENT(IN) :: s_aw + real(kind_phys), DIMENSION( kts:kte, nchem ), INTENT(INOUT) :: chem1 + real(kind_phys), DIMENSION( kts:kte+1,nchem), INTENT(IN) :: s_awchem + real(kind_phys), DIMENSION( ndvel ), INTENT(IN) :: vd1 + real(kind_phys), INTENT(IN) :: emis_ant_no,frp + LOGICAL, INTENT(IN) :: rrfs_sd,enh_mix,smoke_dbg !local vars - REAL, DIMENSION(kts:kte) :: dtz - REAL, DIMENSION(1:kte-kts+1) :: a,b,c,d,x - REAL :: rhs,dztop - REAL :: t,dzk - REAL :: hght - REAL :: khdz_old, khdz_back + real(kind_phys), DIMENSION(kts:kte) :: dtz + real(kind_phys), DIMENSION(kts:kte) :: a,b,c,d,x + real(kind_phys):: rhs,dztop + real(kind_phys):: t,dzk + real(kind_phys):: hght + real(kind_phys):: khdz_old, khdz_back INTEGER :: k,kk,kmaxfire ! JLS 12/21/21 INTEGER :: ic ! Chemical array loop index INTEGER, SAVE :: icall - REAL, DIMENSION(kts:kte) :: rhoinv - REAL, DIMENSION(kts:kte+1) :: rhoz,khdz - REAL, PARAMETER :: no_threshold = 0.1 - REAL, PARAMETER :: frp_threshold = 10.0 ! RAR 02/11/22: I increased the frp threshold to enhance mixing - REAL, PARAMETER :: pblh_threshold = 250.0 + real(kind_phys), DIMENSION(kts:kte) :: rhoinv + real(kind_phys), DIMENSION(kts:kte+1) :: rhoz,khdz + real(kind_phys), PARAMETER :: NO_threshold = 10.0 ! For anthropogenic sources + real(kind_phys), PARAMETER :: frp_threshold = 10.0 ! RAR 02/11/22: I increased the frp threshold to enhance mixing over big fires + real(kind_phys), PARAMETER :: pblh_threshold = 100.0 dztop=.5*(dz(kte)+dz(kte-1)) @@ -5324,18 +5268,19 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & khdz(k) = MAX(khdz(k), -0.5*(s_aw(k)-s_aw(k+1))) ENDDO - !Enhance diffusion over fires - IF ( fire_turb ) THEN + !Enhanced mixing over fires + IF ( rrfs_sd .and. enh_mix ) THEN DO k=kts+1,kte-1 khdz_old = khdz(k) khdz_back = pblh * 0.15 / dz(k) !Modify based on anthropogenic emissions of NO and FRP IF ( pblh < pblh_threshold ) THEN - IF ( emis_ant_no > no_threshold ) THEN - khdz(k) = MAX(1.1*khdz(k),sqrt((emis_ant_no / no_threshold)) / dz(k) * rhoz(k)) ! JLS 12/21/21 + IF ( emis_ant_no > NO_threshold ) THEN + khdz(k) = MAX(1.1*khdz(k),sqrt((emis_ant_no / NO_threshold)) / dz(k) * rhoz(k)) ! JLS 12/21/21 ! khdz(k) = MAX(khdz(k),khdz_back) ENDIF IF ( frp > frp_threshold ) THEN + kmaxfire = ceiling(log(frp)) khdz(k) = MAX(1.1*khdz(k), (1. - k/(kmaxfire*2.)) * ((log(frp))**2.- 2.*log(frp)) / dz(k)*rhoz(k)) ! JLS 12/21/21 ! khdz(k) = MAX(khdz(k),khdz_back) ENDIF @@ -5354,7 +5299,7 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & b(k)=1.+dtz(k)*(khdz(k+1)+khdz(k))*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1) c(k)= -dtz(k)*khdz(k+1)*rhoinv(k) - 0.5*dtz(k)*rhoinv(k)*s_aw(k+1) d(k)=chem1(k,ic) & !dtz(k)*flt !neglecting surface sources - & + dtz(k) * -vd1(ic)*chem1(1,ic) & + & - dtz(k)*vd1(ic)*chem1(k,ic) & & - dtz(k)*rhoinv(k)*s_awchem(k+1,ic) DO k=kts+1,kte-1 @@ -5371,11 +5316,14 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & c(kte)=0. d(kte)=chem1(kte,ic) - !CALL tridiag(kte,a,b,c,d) CALL tridiag3(kte,a,b,c,d,x) + IF ( smoke_dbg ) THEN + print*,'aerosol mixing ic,chem1,chem2(k,ic)',ic,(chem1(kts:kts+10,ic)),(x(kts:kts+10)) + print*,'aerosol PBL mixing ic,vd1(ic)',ic,vd1(ic) + END IF + DO k=kts,kte - !chem_new(k,ic)=d(k) chem1(k,ic)=x(k) ENDDO ENDDO @@ -5383,7 +5331,7 @@ SUBROUTINE mynn_mix_chem(kts,kte,i, & END SUBROUTINE mynn_mix_chem ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf SUBROUTINE retrieve_exchange_coeffs(kts,kte,& &dfm,dfh,dz,K_m,K_h) @@ -5391,13 +5339,13 @@ SUBROUTINE retrieve_exchange_coeffs(kts,kte,& INTEGER , INTENT(in) :: kts,kte - REAL, DIMENSION(KtS:KtE), INTENT(in) :: dz,dfm,dfh + real(kind_phys), DIMENSION(KtS:KtE), INTENT(in) :: dz,dfm,dfh - REAL, DIMENSION(KtS:KtE), INTENT(out) :: K_m, K_h + real(kind_phys), DIMENSION(KtS:KtE), INTENT(out) :: K_m, K_h INTEGER :: k - REAL :: dzk + real(kind_phys):: dzk K_m(kts)=0. K_h(kts)=0. @@ -5411,7 +5359,7 @@ SUBROUTINE retrieve_exchange_coeffs(kts,kte,& END SUBROUTINE retrieve_exchange_coeffs ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf SUBROUTINE tridiag(n,a,b,c,d) !! to solve system of linear eqs on tridiagonal matrix n times n @@ -5423,12 +5371,12 @@ SUBROUTINE tridiag(n,a,b,c,d) !------------------------------------------------------------------- INTEGER, INTENT(in):: n - REAL, DIMENSION(n), INTENT(in) :: a,b - REAL, DIMENSION(n), INTENT(inout) :: c,d + real(kind_phys), DIMENSION(n), INTENT(in) :: a,b + real(kind_phys), DIMENSION(n), INTENT(inout) :: c,d INTEGER :: i - REAL :: p - REAL, DIMENSION(n) :: q + real(kind_phys):: p + real(kind_phys), DIMENSION(n) :: q c(n)=0. q(1)=-c(1)/b(1) @@ -5447,7 +5395,7 @@ SUBROUTINE tridiag(n,a,b,c,d) END SUBROUTINE tridiag ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf subroutine tridiag2(n,a,b,c,d,x) implicit none ! a - sub-diagonal (means it is the diagonal below the main diagonal) @@ -5458,10 +5406,10 @@ subroutine tridiag2(n,a,b,c,d,x) ! n - number of unknowns (levels) integer,intent(in) :: n - real, dimension(n),intent(in) :: a,b,c,d - real ,dimension(n),intent(out) :: x - real ,dimension(n) :: cp,dp - real :: m + real(kind_phys), dimension(n), intent(in) :: a,b,c,d + real(kind_phys), dimension(n), intent(out):: x + real(kind_phys), dimension(n) :: cp,dp + real(kind_phys):: m integer :: i ! initialize c-prime and d-prime @@ -5482,7 +5430,7 @@ subroutine tridiag2(n,a,b,c,d,x) end subroutine tridiag2 ! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf subroutine tridiag3(kte,a,b,c,d,x) !ccccccccccccccccccccccccccccccc @@ -5500,12 +5448,12 @@ subroutine tridiag3(kte,a,b,c,d,x) implicit none integer,intent(in) :: kte integer, parameter :: kts=1 - real, dimension(kte) :: a,b,c,d - real ,dimension(kte),intent(out) :: x + real(kind_phys), dimension(kte) :: a,b,c,d + real(kind_phys), dimension(kte), intent(out) :: x integer :: in ! integer kms,kme,kts,kte,in -! real a(kms:kme,3),c(kms:kme),x(kms:kme) +! real(kind_phys)a(kms:kme,3),c(kms:kme),x(kms:kme) do in=kte-1,kts,-1 d(in)=d(in)-c(in)*d(in+1)/b(in+1) @@ -5524,65 +5472,7 @@ subroutine tridiag3(kte,a,b,c,d,x) end subroutine tridiag3 ! ================================================================== - -!>\ingroup gp_mynnedmf -!! - SUBROUTINE mynn_bl_init_driver( & - &RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN, & - &RQCBLTEN,RQIBLTEN & !,RQNIBLTEN,RQNCBLTEN & - &,QKE, & - &EXCH_H & - !&,icloud_bl,qc_bl,cldfra_bl & - &,RESTART,ALLOWED_TO_READ,LEVEL & - &,IDS,IDE,JDS,JDE,KDS,KDE & - &,IMS,IME,JMS,JME,KMS,KME & - &,ITS,ITE,JTS,JTE,KTS,KTE) - - !--------------------------------------------------------------- - LOGICAL,INTENT(IN) :: ALLOWED_TO_READ,RESTART - INTEGER,INTENT(IN) :: LEVEL !,icloud_bl - - INTEGER,INTENT(IN) :: IDS,IDE,JDS,JDE,KDS,KDE, & - & IMS,IME,JMS,JME,KMS,KME, & - & ITS,ITE,JTS,JTE,KTS,KTE - - - REAL,DIMENSION(IMS:IME,KMS:KME),INTENT(INOUT) :: & - &RUBLTEN,RVBLTEN,RTHBLTEN,RQVBLTEN, & - &RQCBLTEN,RQIBLTEN,& !RQNIBLTEN,RQNCBLTEN & - &QKE,EXCH_H - - INTEGER :: I,J,K,ITF,JTF,KTF - - JTF=MIN0(JTE,JDE-1) - KTF=MIN0(KTE,KDE-1) - ITF=MIN0(ITE,IDE-1) - - IF(.NOT.RESTART)THEN - DO K=KTS,KTF - DO I=ITS,ITF - RUBLTEN(i,k)=0. - RVBLTEN(i,k)=0. - RTHBLTEN(i,k)=0. - RQVBLTEN(i,k)=0. - if( p_qc >= param_first_scalar ) RQCBLTEN(i,k)=0. - if( p_qi >= param_first_scalar ) RQIBLTEN(i,k)=0. - !if( p_qnc >= param_first_scalar ) RQNCBLTEN(i,k)=0. - !if( p_qni >= param_first_scalar ) RQNIBLTEN(i,k)=0. - !QKE(i,k)=0. - EXCH_H(i,k)=0. -! if(icloud_bl > 0) qc_bl(i,k)=0. -! if(icloud_bl > 0) cldfra_bl(i,k)=0. - ENDDO - ENDDO - ENDIF - - mynn_level=level - - END SUBROUTINE mynn_bl_init_driver - -! ================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This subroutine calculates hybrid diagnotic boundary-layer height (PBLH). !! !! NOTES ON THE PBLH FORMULATION: The 1.5-theta-increase method defines @@ -5627,15 +5517,15 @@ SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea,kzi) # define kte HARDCODE_VERTICAL #endif - REAL, INTENT(OUT) :: zi - REAL, INTENT(IN) :: landsea - REAL, DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D - REAL, DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D + real(kind_phys), INTENT(OUT) :: zi + real(kind_phys), INTENT(IN) :: landsea + real(kind_phys), DIMENSION(KTS:KTE), INTENT(IN) :: thetav1D, qke1D, dz1D + real(kind_phys), DIMENSION(KTS:KTE+1), INTENT(IN) :: zw1D !LOCAL VARS - REAL :: PBLH_TKE,qtke,qtkem1,wt,maxqke,TKEeps,minthv - REAL :: delt_thv !delta theta-v; dependent on land/sea point - REAL, PARAMETER :: sbl_lim = 200. !upper limit of stable BL height (m). - REAL, PARAMETER :: sbl_damp = 400. !transition length for blending (m). + real(kind_phys):: PBLH_TKE,qtke,qtkem1,wt,maxqke,TKEeps,minthv + real(kind_phys):: delt_thv !delta theta-v; dependent on land/sea point + real(kind_phys), PARAMETER :: sbl_lim = 200. !upper limit of stable BL height (m). + real(kind_phys), PARAMETER :: sbl_damp = 400. !transition length for blending (m). INTEGER :: I,J,K,kthv,ktke,kzi !Initialize KPBL (kzi) @@ -5744,7 +5634,8 @@ SUBROUTINE GET_PBLH(KTS,KTE,zi,thetav1D,qke1D,zw1D,dz1D,landsea,kzi) END SUBROUTINE GET_PBLH !> @} -!>\ingroup gp_mynnedmf +! ================================================================== +!>\ingroup gsd_mynn_edmf !! This subroutine is the Dynamic Multi-Plume (DMP) Mass-Flux Scheme. !! !! dmp_mf() calculates the nonlocal turbulent transport from the dynamic @@ -5762,46 +5653,47 @@ END SUBROUTINE GET_PBLH !! !! This scheme remains under development, so consider it experimental code. !! - SUBROUTINE DMP_mf( & - & kts,kte,dt,zw,dz,p,rho, & - & momentum_opt, & - & tke_opt, & - & scalar_opt, & - & u,v,w,th,thl,thv,tk, & - & qt,qv,qc,qke, & - & qnc,qni,qnwfa,qnifa, & - & exner,vt,vq,sgm, & - & ust,flt,fltv,flq,flqv, & - & pblh,kpbl,DX,landsea,ts, & + SUBROUTINE DMP_mf( & + & kts,kte,dt,zw,dz,p,rho, & + & momentum_opt, & + & tke_opt, & + & scalar_opt, & + & u,v,w,th,thl,thv,tk, & + & qt,qv,qc,qke, & + & qnc,qni,qnwfa,qnifa,qnbca, & + & exner,vt,vq,sgm, & + & ust,flt,fltv,flq,flqv, & + & pblh,kpbl,dx,landsea,ts, & ! outputs - updraft properties - & edmf_a,edmf_w, & - & edmf_qt,edmf_thl, & - & edmf_ent,edmf_qc, & + & edmf_a,edmf_w, & + & edmf_qt,edmf_thl, & + & edmf_ent,edmf_qc, & ! outputs - variables needed for solver - & s_aw,s_awthl,s_awqt, & - & s_awqv,s_awqc, & - & s_awu,s_awv,s_awqke, & - & s_awqnc,s_awqni, & - & s_awqnwfa,s_awqnifa, & - & sub_thl,sub_sqv, & - & sub_u,sub_v, & - & det_thl,det_sqv,det_sqc, & - & det_u,det_v, & + & s_aw,s_awthl,s_awqt, & + & s_awqv,s_awqc, & + & s_awu,s_awv,s_awqke, & + & s_awqnc,s_awqni, & + & s_awqnwfa,s_awqnifa, & + & s_awqnbca, & + & sub_thl,sub_sqv, & + & sub_u,sub_v, & + & det_thl,det_sqv,det_sqc, & + & det_u,det_v, & ! chem/smoke - & nchem,chem1,s_awchem, & - & mix_chem, & + & nchem,chem1,s_awchem, & + & mix_chem, & ! in/outputs - subgrid scale clouds & qc_bl1d,cldfra_bl1d, & & qc_bl1D_old,cldfra_bl1D_old, & ! inputs - flags for moist arrays - & F_QC,F_QI, & - F_QNC,F_QNI, & - & F_QNWFA,F_QNIFA, & - & Psig_shcu, & + & F_QC,F_QI, & + & F_QNC,F_QNI, & + & F_QNWFA,F_QNIFA,F_QNBCA, & + & Psig_shcu, & ! output info - &nup2,ktop,maxmf,ztop, & - ! unputs for stochastic perturbations - &spp_pbl,rstoch_col) + & nup2,ktop,maxmf,ztop, & + ! inputs for stochastic perturbations + & spp_pbl,rstoch_col ) ! inputs: INTEGER, INTENT(IN) :: KTS,KTE,KPBL,momentum_opt,tke_opt,scalar_opt @@ -5812,137 +5704,134 @@ SUBROUTINE DMP_mf( & #endif ! Stochastic - INTEGER, INTENT(IN) :: spp_pbl - REAL, DIMENSION(KTS:KTE) :: rstoch_col + INTEGER, INTENT(IN) :: spp_pbl + real(kind_phys), DIMENSION(KTS:KTE) :: rstoch_col - REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,W,TH,THL,TK,QT,QV,QC,& - exner,dz,THV,P,rho,qke,qnc,qni,qnwfa,qnifa - REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW !height at full-sigma - REAL, INTENT(IN) :: DT,UST,FLT,FLTV,FLQ,FLQV,PBLH,& - DX,Psig_shcu,landsea,ts - LOGICAL, OPTIONAL :: F_QC,F_QI,F_QNC,F_QNI,F_QNWFA,F_QNIFA + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: & + &U,V,W,TH,THL,TK,QT,QV,QC, & + &exner,dz,THV,P,rho,qke,qnc,qni,qnwfa,qnifa,qnbca + real(kind_phys),DIMENSION(KTS:KTE+1), INTENT(IN) :: zw !height at full-sigma + real(kind_phys), INTENT(IN) :: flt,fltv,flq,flqv,Psig_shcu, & + &landsea,ts,dx,dt,ust,pblh + LOGICAL, OPTIONAL :: F_QC,F_QI,F_QNC,F_QNI,F_QNWFA,F_QNIFA,F_QNBCA ! outputs - updraft properties - REAL,DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a,edmf_w, & - & edmf_qt,edmf_thl, edmf_ent,edmf_qc + real(kind_phys),DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a,edmf_w, & + & edmf_qt,edmf_thl,edmf_ent,edmf_qc !add one local edmf variable: - REAL,DIMENSION(KTS:KTE) :: edmf_th + real(kind_phys),DIMENSION(KTS:KTE) :: edmf_th ! output INTEGER, INTENT(OUT) :: nup2,ktop - REAL, INTENT(OUT) :: maxmf,ztop + real(kind_phys), INTENT(OUT) :: maxmf + real(kind_phys), INTENT(OUT) :: ztop ! outputs - variables needed for solver - REAL,DIMENSION(KTS:KTE+1) :: s_aw, & !sum ai*rho*wis_awphi - s_awthl, & !sum ai*rho*wi*phii - s_awqt, & - s_awqv, & - s_awqc, & - s_awqnc, & - s_awqni, & - s_awqnwfa, & - s_awqnifa, & - s_awu, & - s_awv, & - s_awqke, s_aw2 - - REAL,DIMENSION(KTS:KTE), INTENT(INOUT) :: qc_bl1d,cldfra_bl1d, & - qc_bl1d_old,cldfra_bl1d_old - - INTEGER, PARAMETER :: NUP=10, debug_mf=0 + real(kind_phys),DIMENSION(KTS:KTE+1) :: s_aw, & !sum ai*rho*wis_awphi + &s_awthl,s_awqt,s_awqv,s_awqc,s_awqnc,s_awqni, & + &s_awqnwfa,s_awqnifa,s_awqnbca,s_awu,s_awv, & + &s_awqke,s_aw2 + + real(kind_phys),DIMENSION(KTS:KTE), INTENT(INOUT) :: & + &qc_bl1d,cldfra_bl1d,qc_bl1d_old,cldfra_bl1d_old + + INTEGER, PARAMETER :: nup=10, debug_mf=0 !------------- local variables ------------------- ! updraft properties defined on interfaces (k=1 is the top of the ! first model layer - REAL,DIMENSION(KTS:KTE+1,1:NUP) :: UPW,UPTHL,UPQT,UPQC,UPQV, & - UPA,UPU,UPV,UPTHV,UPQKE,UPQNC, & - UPQNI,UPQNWFA,UPQNIFA + real(kind_phys),DIMENSION(KTS:KTE+1,1:NUP) :: & + &UPW,UPTHL,UPQT,UPQC,UPQV, & + &UPA,UPU,UPV,UPTHV,UPQKE,UPQNC, & + &UPQNI,UPQNWFA,UPQNIFA,UPQNBCA ! entrainment variables - REAL,DIMENSION(KTS:KTE,1:NUP) :: ENT,ENTf - INTEGER,DIMENSION(KTS:KTE,1:NUP) :: ENTi + real(kind_phys),DIMENSION(KTS:KTE,1:NUP) :: ENT,ENTf + INTEGER,DIMENSION(KTS:KTE,1:NUP) :: ENTi ! internal variables INTEGER :: K,I,k50 - REAL :: fltv2,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & - pwmin,pwmax,wmin,wmax,wlv,Psig_w,maxw,maxqc,wpbl - REAL :: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,QNCn,QNIn,QNWFAn,QNIFAn, & + real(kind_phys):: fltv2,wstar,qstar,thstar,sigmaW,sigmaQT, & + &sigmaTH,z0,pwmin,pwmax,wmin,wmax,wlv,Psig_w,maxw,maxqc,wpbl + real(kind_phys):: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,QNCn,QNIn, & + QNWFAn,QNIFAn,QNBCAn, & Wn2,Wn,EntEXP,EntEXM,EntW,BCOEFF,THVkm1,THVk,Pk,rho_int ! w parameters - REAL,PARAMETER :: & - &Wa=2./3., & - &Wb=0.002, & + real(kind_phys), PARAMETER :: & + &Wa=2./3., & + &Wb=0.002, & &Wc=1.5 ! Lateral entrainment parameters ( L0=100 and ENT0=0.1) were taken from ! Suselj et al (2013, jas). Note that Suselj et al (2014,waf) use L0=200 and ENT0=0.2. - REAL,PARAMETER :: & + real(kind_phys),PARAMETER :: & & L0=100., & & ENT0=0.1 ! Implement ideas from Neggers (2016, JAMES): - REAL, PARAMETER :: Atot = 0.10 ! Maximum total fractional area of all updrafts - REAL, PARAMETER :: lmax = 1000.! diameter of largest plume - REAL, PARAMETER :: dl = 100. ! diff size of each plume - the differential multiplied by the integrand - REAL, PARAMETER :: dcut = 1.2 ! max diameter of plume to parameterize relative to dx (km) - REAL :: d != -2.3 to -1.7 ;=-1.9 in Neggers paper; power law exponent for number density (N=Cl^d). + real(kind_phys), PARAMETER :: Atot = 0.10 ! Maximum total fractional area of all updrafts + real(kind_phys), PARAMETER :: lmax = 1000.! diameter of largest plume + real(kind_phys), PARAMETER :: dl = 100. ! diff size of each plume - the differential multiplied by the integrand + real(kind_phys), PARAMETER :: dcut = 1.2 ! max diameter of plume to parameterize relative to dx (km) + real(kind_phys):: d != -2.3 to -1.7 ;=-1.9 in Neggers paper; power law exponent for number density (N=Cl^d). ! Note that changing d to -2.0 makes each size plume equally contribute to the total coverage of all plumes. ! Note that changing d to -1.7 doubles the area coverage of the largest plumes relative to the smallest plumes. - REAL :: cn,c,l,n,an2,hux,maxwidth,wspd_pbl,cloud_base,width_flx + real(kind_phys):: cn,c,l,n,an2,hux,maxwidth,wspd_pbl,cloud_base,width_flx ! chem/smoke INTEGER, INTENT(IN) :: nchem - REAL,DIMENSION(:, :) :: chem1 - REAL,DIMENSION(kts:kte+1, nchem) :: s_awchem - REAL,DIMENSION(nchem) :: chemn - REAL,DIMENSION(KTS:KTE+1,1:NUP, nchem) :: UPCHEM + real(kind_phys),DIMENSION(:, :) :: chem1 + real(kind_phys),DIMENSION(kts:kte+1, nchem) :: s_awchem + real(kind_phys),DIMENSION(nchem) :: chemn + real(kind_phys),DIMENSION(KTS:KTE+1,1:NUP, nchem) :: UPCHEM INTEGER :: ic - REAL,DIMENSION(KTS:KTE+1, nchem) :: edmf_chem + real(kind_phys),DIMENSION(KTS:KTE+1, nchem) :: edmf_chem LOGICAL, INTENT(IN) :: mix_chem !JOE: add declaration of ERF - REAL :: ERF + real(kind_phys):: ERF LOGICAL :: superadiabatic ! VARIABLES FOR CHABOUREAU-BECHTOLD CLOUD FRACTION - REAL,DIMENSION(KTS:KTE), INTENT(INOUT) :: vt, vq, sgm - REAL :: sigq,xl,rsl,cpm,a,qmq,mf_cf,Q1,diffqt,qsat_tk,& - Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid, & + real(kind_phys),DIMENSION(KTS:KTE), INTENT(INOUT) :: vt, vq, sgm + real(kind_phys):: sigq,xl,rsl,cpm,a,qmq,mf_cf,Aup,Q1,diffqt,qsat_tk,& + Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid, & Ac_mf,Ac_strat,qc_mf + real(kind_phys), PARAMETER :: cf_thresh = 0.5 ! only overwrite stratus CF less than this value ! Variables for plume interpolation/saturation check - REAL,DIMENSION(KTS:KTE) :: exneri,dzi - REAL :: THp, QTp, QCp, QCs, esat, qsl - REAL :: csigma,acfac,ac_wsp,ac_cld + real(kind_phys),DIMENSION(KTS:KTE) :: exneri,dzi + real(kind_phys):: THp, QTp, QCp, QCs, esat, qsl + real(kind_phys):: csigma,acfac,ac_wsp,ac_cld !plume overshoot INTEGER :: overshoot - REAL :: bvf, Frz, dzp + real(kind_phys):: bvf, Frz, dzp !Flux limiter: not let mass-flux of heat between k=1&2 exceed (fluxportion)*(surface heat flux). !This limiter makes adjustments to the entire column. - REAL :: adjustment, flx1 - REAL, PARAMETER :: fluxportion=0.75 ! set liberally, so has minimal impact. 0.5 starts to have a noticeable impact + real(kind_phys):: adjustment, flx1 + real(kind_phys), PARAMETER :: fluxportion=0.75 ! set liberally, so has minimal impact. 0.5 starts to have a noticeable impact ! over land (decrease maxMF by 10-20%), but no impact over water. !Subsidence - REAL,DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v, & !tendencies due to subsidence - det_thl,det_sqv,det_sqc,det_u,det_v, & !tendencied due to detrainment - envm_a,envm_w,envm_thl,envm_sqv,envm_sqc, & + real(kind_phys),DIMENSION(KTS:KTE) :: sub_thl,sub_sqv,sub_u,sub_v, & !tendencies due to subsidence + det_thl,det_sqv,det_sqc,det_u,det_v, & !tendencied due to detrainment + envm_a,envm_w,envm_thl,envm_sqv,envm_sqc, & envm_u,envm_v !environmental variables defined at middle of layer - REAL,DIMENSION(KTS:KTE+1) :: envi_a,envi_w !environmental variables defined at model interface - REAL :: temp,sublim,qc_ent,qv_ent,qt_ent,thl_ent,detrate, & - detrateUV,oow,exc_fac,aratio,detturb,qc_grid,qc_sgs,& - qc_plume - REAL, PARAMETER :: Cdet = 1./45. - REAL, PARAMETER :: dzpmax = 300. !limit dz used in detrainment - can be excessing in thick layers + real(kind_phys),DIMENSION(KTS:KTE+1) :: envi_a,envi_w !environmental variables defined at model interface + real(kind_phys):: temp,sublim,qc_ent,qv_ent,qt_ent,thl_ent,detrate, & + detrateUV,oow,exc_fac,aratio,detturb,qc_grid,qc_sgs, & + qc_plume,exc_heat,exc_moist,tk_int + real(kind_phys), PARAMETER :: Cdet = 1./45. + real(kind_phys), PARAMETER :: dzpmax = 300. !limit dz used in detrainment - can be excessing in thick layers !parameter "Csub" determines the propotion of upward vertical velocity that contributes to !environmenatal subsidence. Some portion is expected to be compensated by downdrafts instead of !gentle environmental subsidence. 1.0 assumes all upward vertical velocity in the mass-flux scheme !is compensated by "gentle" environmental subsidence. - REAL, PARAMETER :: Csub=0.25 + real(kind_phys), PARAMETER :: Csub=0.25 !Factor for the pressure gradient effects on momentum transport - REAL, PARAMETER :: pgfac = 0.00 ! Zhang and Wu showed 0.4 is more appropriate for lower troposphere - REAL :: Uk,Ukm1,Vk,Vkm1,dxsa + real(kind_phys), PARAMETER :: pgfac = 0.00 ! Zhang and Wu showed 0.4 is more appropriate for lower troposphere + real(kind_phys):: Uk,Ukm1,Vk,Vkm1,dxsa ! check the inputs ! print *,'dt',dt @@ -5971,6 +5860,7 @@ SUBROUTINE DMP_mf( & UPQNI=0. UPQNWFA=0. UPQNIFA=0. + UPQNBCA=0. IF ( mix_chem ) THEN UPCHEM(KTS:KTE+1,1:NUP,1:nchem)=0.0 ENDIF @@ -6000,6 +5890,7 @@ SUBROUTINE DMP_mf( & s_awqni=0. s_awqnwfa=0. s_awqnifa=0. + s_awqnbca=0. IF ( mix_chem ) THEN s_awchem(kts:kte+1,1:nchem) = 0.0 ENDIF @@ -6193,25 +6084,41 @@ SUBROUTINE DMP_mf( & wlv=wmin+(wmax-wmin)/NUP2*(i-1) !SURFACE UPDRAFT VERTICAL VELOCITY - UPW(1,I)=wmin + REAL(i)/REAL(NUP)*(wmax-wmin) + UPW(1,I)=wmin + real(i)/real(NUP)*(wmax-wmin) !IF (UPW(1,I) > 0.5*ZW(2)/dt) UPW(1,I) = 0.5*ZW(2)/dt UPU(1,I)=(U(KTS)*DZ(KTS+1)+U(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPV(1,I)=(V(KTS)*DZ(KTS+1)+V(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQC(1,I)=0.0 !UPQC(1,I)=(QC(KTS)*DZ(KTS+1)+QC(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) - UPQT(1,I)=(QT(KTS)*DZ(KTS+1)+QT(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1))& - & +exc_fac*UPW(1,I)*sigmaQT/sigmaW + + exc_heat = exc_fac*UPW(1,I)*sigmaTH/sigmaW UPTHV(1,I)=(THV(KTS)*DZ(KTS+1)+THV(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) & - & +exc_fac*UPW(1,I)*sigmaTH/sigmaW + & + exc_heat !was UPTHL(1,I)= UPTHV(1,I)/(1.+svp1*UPQT(1,I)) !assume no saturated parcel at surface UPTHL(1,I)=(THL(KTS)*DZ(KTS+1)+THL(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) & - & +exc_fac*UPW(1,I)*sigmaTH/sigmaW + & + exc_heat + + !calculate exc_moist by use of surface fluxes + exc_moist=exc_fac*UPW(1,I)*sigmaQT/sigmaW + !calculate exc_moist by conserving rh: +! tk_int =(tk(kts)*dz(kts+1)+tk(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) +! pk =(p(kts)*dz(kts+1)+p(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) +! qtk =(qt(kts)*dz(kts+1)+qt(kts+1)*dz(kts))/(dz(kts)+dz(kts+1)) +! qsat_tk = qsat_blend(tk_int, pk) ! saturation water vapor mixing ratio at tk and p +! rhgrid =MAX(MIN(1.0,qtk/MAX(1.E-8,qsat_tk)),0.001) +! tk_int = tk_int + exc_heat +! qsat_tk = qsat_blend(tk_int, pk) +! exc_moist= max(rhgrid*qsat_tk - qtk, 0.0) + UPQT(1,I)=(QT(KTS)*DZ(KTS+1)+QT(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1))& + & +exc_moist + UPQKE(1,I)=(QKE(KTS)*DZ(KTS+1)+QKE(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNC(1,I)=(QNC(KTS)*DZ(KTS+1)+QNC(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNI(1,I)=(QNI(KTS)*DZ(KTS+1)+QNI(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNWFA(1,I)=(QNWFA(KTS)*DZ(KTS+1)+QNWFA(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) UPQNIFA(1,I)=(QNIFA(KTS)*DZ(KTS+1)+QNIFA(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) + UPQNBCA(1,I)=(QNBCA(KTS)*DZ(KTS+1)+QNBCA(KTS+1)*DZ(KTS))/(DZ(KTS)+DZ(KTS+1)) ENDDO IF ( mix_chem ) THEN @@ -6284,6 +6191,7 @@ SUBROUTINE DMP_mf( & QNIn=UPQNI(k-1,I)*(1.-EntExp) + QNI(k)*EntExp QNWFAn=UPQNWFA(k-1,I)*(1.-EntExp) + QNWFA(k)*EntExp QNIFAn=UPQNIFA(k-1,I)*(1.-EntExp) + QNIFA(k)*EntExp + QNBCAn=UPQNBCA(k-1,I)*(1.-EntExp) + QNBCA(k)*EntExp !capture the updated qc, qt & thl modified by entranment alone, !since they will be modified later if condensation occurs. @@ -6299,14 +6207,14 @@ SUBROUTINE DMP_mf( & !Vn =V(K) *(1-EntExp)+UPV(K-1,I)*EntExp !QKEn=QKE(k)*(1-EntExp)+UPQKE(K-1,I)*EntExp - IF ( mix_chem ) THEN + if ( mix_chem ) then do ic = 1,nchem ! Exponential Entrainment: !chemn(ic) = chem(k,ic)*(1-EntExp)+UPCHEM(K-1,I,ic)*EntExp ! Linear entrainment: chemn(ic)=UPCHEM(k-1,i,ic)*(1.-EntExp) + chem1(k,ic)*EntExp enddo - ENDIF + endif ! Define pressure at model interface Pk =(P(k)*DZ(k+1)+P(k+1)*DZ(k))/(DZ(k+1)+DZ(k)) @@ -6380,13 +6288,10 @@ SUBROUTINE DMP_mf( & dzp = dz(k) ENDIF - !Limit very tall plumes - Wn=Wn*EXP(-MAX(ZW(k+1)-MIN(pblh+2000.,3500.),0.0)/1000.) - - !JOE- minimize the plume penetratration in stratocu-topped PBL - ! IF (fltv2 < 0.06) THEN - ! IF(ZW(k+1) >= pblh-200. .AND. qc(k) > 1e-5 .AND. I > 4) Wn=0. - ! ENDIF + !minimize the plume penetratration in stratocu-topped PBL + !IF (fltv2 < 0.06) THEN + ! IF(ZW(k+1) >= pblh-200. .AND. qc(k) > 1e-5 .AND. I > 4) Wn=0. + !ENDIF !Modify environment variables (representative of the model layer - envm*) !following the updraft dynamical detrainment of Asai and Kasahara (1967, JAS). @@ -6424,6 +6329,7 @@ SUBROUTINE DMP_mf( & UPQNI(K,I)=QNIn UPQNWFA(K,I)=QNWFAn UPQNIFA(K,I)=QNIFAn + UPQNBCA(K,I)=QNBCAn UPA(K,I)=UPA(K-1,I) IF ( mix_chem ) THEN do ic = 1,nchem @@ -6479,13 +6385,13 @@ SUBROUTINE DMP_mf( & s_awthl(k+1)= s_awthl(k+1) + rho_int*UPA(K,i)*UPW(K,i)*UPTHL(K,i)*Psig_w s_awqt(k+1) = s_awqt(k+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQT(K,i)*Psig_w !to conform to grid mean properties, move qc to qv in grid mean - !saturated layers, so total water fluxes are preserve but + !saturated layers, so total water fluxes are preserved but !negative qc fluxes in unsaturated layers is reduced. - IF (qc(k) > 1e-12 .OR. qc(k+1) > 1e-12) then +! if (qc(k) > 1e-12 .or. qc(k+1) > 1e-12) then qc_plume = UPQC(K,i) - ELSE - qc_plume = 0.0 - ENDIF +! else +! qc_plume = 0.0 +! endif s_awqc(k+1) = s_awqc(k+1) + rho_int*UPA(K,i)*UPW(K,i)*qc_plume*Psig_w IF (momentum_opt > 0) THEN s_awu(k+1) = s_awu(k+1) + rho_int*UPA(K,i)*UPW(K,i)*UPU(K,i)*Psig_w @@ -6521,6 +6427,7 @@ SUBROUTINE DMP_mf( & s_awqni(k+1)= s_awqni(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNI(K,i)*Psig_w s_awqnwfa(k+1)= s_awqnwfa(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNWFA(K,i)*Psig_w s_awqnifa(k+1)= s_awqnifa(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNIFA(K,i)*Psig_w + s_awqnbca(k+1)= s_awqnbca(K+1) + rho_int*UPA(K,i)*UPW(K,i)*UPQNBCA(K,i)*Psig_w ENDDO ENDDO ENDIF @@ -6550,6 +6457,7 @@ SUBROUTINE DMP_mf( & s_awqni= s_awqni*adjustment s_awqnwfa= s_awqnwfa*adjustment s_awqnifa= s_awqnifa*adjustment + s_awqnbca= s_awqnbca*adjustment IF (momentum_opt > 0) THEN s_awu = s_awu*adjustment s_awv = s_awv*adjustment @@ -6596,9 +6504,9 @@ SUBROUTINE DMP_mf( & !smoke/chem IF ( mix_chem ) THEN - DO k=KTS,KTE-1 + DO k=kts,kte-1 IF(k > KTOP) exit - rho_int = (rho(k)*DZ(k+1)+rho(k+1)*DZ(k))/(DZ(k+1)+DZ(k)) + rho_int = (rho(k)*dz(k+1)+rho(k+1)*dz(k))/(dz(k+1)+dz(k)) DO I=1,NUP !NUP2 IF(I > NUP2) exit do ic = 1,nchem @@ -6615,14 +6523,14 @@ SUBROUTINE DMP_mf( & ENDIF !Calculate the effects environmental subsidence. - !All envi_*variables are valid at the interfaces, like the edmf_* variables + !All envi_*variables are valid at the interfaces, like the edmf_* variables IF (env_subs) THEN - DO k=KTS+1,KTE-1 + DO k=kts+1,kte-1 !First, smooth the profiles of w & a, since sharp vertical gradients !in plume variables are not likely extended to env variables !Note1: w is treated as negative further below !Note2: both w & a will be transformed into env variables further below - envi_w(k) = onethird*(edmf_w(K-1)+edmf_w(K)+edmf_w(K+1)) + envi_w(k) = onethird*(edmf_w(k-1)+edmf_w(k)+edmf_w(k+1)) envi_a(k) = onethird*(edmf_a(k-1)+edmf_a(k)+edmf_a(k+1))*adjustment ENDDO !define env variables at k=1 (top of first model layer) @@ -6643,22 +6551,26 @@ SUBROUTINE DMP_mf( & sublim = 1.0 ENDIF !Transform w & a into env variables - DO k=KTS,KTE + DO k=kts,kte temp=envi_a(k) envi_a(k)=1.0-temp envi_w(k)=csub*sublim*envi_w(k)*temp/(1.-temp) ENDDO !calculate tendencies from subsidence and detrainment valid at the middle of - !each model layer - dzi(kts) = 0.5*(DZ(kts)+DZ(kts+1)) - sub_thl(kts)=0.5*envi_w(kts)*envi_a(kts)*(thl(kts+1)-thl(kts))/dzi(kts) - sub_sqv(kts)=0.5*envi_w(kts)*envi_a(kts)*(qv(kts+1)-qv(kts))/dzi(kts) - DO k=KTS+1,KTE-1 - dzi(k) = 0.5*(DZ(k)+DZ(k+1)) - sub_thl(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (thl(k+1)-thl(k))/dzi(k) - sub_sqv(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (qv(k+1)-qv(k))/dzi(k) + !each model layer. The lowest model layer uses an assumes w=0 at the surface. + dzi(kts) = 0.5*(dz(kts)+dz(kts+1)) + rho_int = (rho(kts)*dz(kts+1)+rho(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) + sub_thl(kts)= 0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*thl(kts+1)-rho(kts)*thl(kts))/dzi(kts)/rho_int + sub_sqv(kts)= 0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*qv(kts+1)-rho(kts)*qv(kts))/dzi(kts)/rho_int + DO k=kts+1,kte-1 + dzi(k) = 0.5*(dz(k)+dz(k+1)) + rho_int = (rho(k)*dz(k+1)+rho(k+1)*dz(k))/(dz(k+1)+dz(k)) + sub_thl(k)= 0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & + (rho(k+1)*thl(k+1)-rho(k)*thl(k))/dzi(k)/rho_int + sub_sqv(k)= 0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & + (rho(k+1)*qv(k+1)-rho(k)*qv(k))/dzi(k)/rho_int ENDDO DO k=KTS,KTE-1 @@ -6668,13 +6580,17 @@ SUBROUTINE DMP_mf( & ENDDO IF (momentum_opt > 0) THEN - sub_u(kts)=0.5*envi_w(kts)*envi_a(kts)*(u(kts+1)-u(kts))/dzi(kts) - sub_v(kts)=0.5*envi_w(kts)*envi_a(kts)*(v(kts+1)-v(kts))/dzi(kts) - DO k=KTS+1,KTE-1 + rho_int = (rho(kts)*dz(kts+1)+rho(kts+1)*dz(kts))/(dz(kts+1)+dz(kts)) + sub_u(kts)=0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*u(kts+1)-rho(kts)*u(kts))/dzi(kts)/rho_int + sub_v(kts)=0.5*envi_w(kts)*envi_a(kts)* & + (rho(kts+1)*v(kts+1)-rho(kts)*v(kts))/dzi(kts)/rho_int + DO k=kts+1,kte-1 + rho_int = (rho(k)*dz(k+1)+rho(k+1)*dz(k))/(dz(k+1)+dz(k)) sub_u(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (u(k+1)-u(k))/dzi(k) + (rho(k+1)*u(k+1)-rho(k)*u(k))/dzi(k)/rho_int sub_v(k)=0.5*(envi_w(k)+envi_w(k-1))*0.5*(envi_a(k)+envi_a(k-1)) * & - (v(k+1)-v(k))/dzi(k) + (rho(k+1)*v(k+1)-rho(k)*v(k))/dzi(k)/rho_int ENDDO DO k=KTS,KTE-1 @@ -6695,27 +6611,27 @@ SUBROUTINE DMP_mf( & !JOE: ADD CLDFRA_bl1d, qc_bl1d. Note that they have already been defined in ! mym_condensation. Here, a shallow-cu component is added, but no cumulus -! clouds can be added at k=1 (start loop at k=2). - DO K=KTS+1,KTE-2 - IF(k > KTOP) exit - IF(0.5*(edmf_qc(k)+edmf_qc(k-1))>0.0)THEN - - !interpolate plume thl, th, and qt to mass levels +! clouds can be added at k=1 (start loop at k=2). + do k=kts+1,kte-2 + IF(k > KTOP) exit + IF(0.5*(edmf_qc(k)+edmf_qc(k-1))>0.0 .and. (cldfra_bl1d(k) < cf_thresh))THEN + !interpolate plume quantities to mass levels + Aup = (edmf_a(k)*dzi(k-1)+edmf_a(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) THp = (edmf_th(k)*dzi(k-1)+edmf_th(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) QTp = (edmf_qt(k)*dzi(k-1)+edmf_qt(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) !convert TH to T - t = THp*exner(k) +! t = THp*exner(k) !SATURATED VAPOR PRESSURE - esat = esat_blend(t) + esat = esat_blend(tk(k)) !SATURATED SPECIFIC HUMIDITY - qsl=ep_2*esat/max(1.e-4,(p(k)-ep_3*esat)) + qsl=ep_2*esat/max(1.e-7,(p(k)-ep_3*esat)) !condensed liquid in the plume on mass levels - IF (edmf_qc(k)>0.0 .AND. edmf_qc(k-1)>0.0)THEN - QCp = 0.5*(edmf_qc(k)+edmf_qc(k-1)) - ELSE - QCp = MAX(edmf_qc(k),edmf_qc(k-1)) - ENDIF + if (edmf_qc(k)>0.0 .and. edmf_qc(k-1)>0.0) then + QCp = (edmf_qc(k)*dzi(k-1)+edmf_qc(k-1)*dzi(k))/(dzi(k-1)+dzi(k)) + else + QCp = max(edmf_qc(k),edmf_qc(k-1)) + endif !COMPUTE CLDFRA & QC_BL FROM MASS-FLUX SCHEME and recompute vt & vq xl = xl_blend(tk(k)) ! obtain blended heat capacity @@ -6728,7 +6644,7 @@ SUBROUTINE DMP_mf( & b9 = a*rsl ! CB02 variable "b" q2p = xlvcp/exner(k) - pt = thl(k) +q2p*QCp*0.5*(edmf_a(k)+edmf_a(k-1)) ! potential temp (env + plume) + pt = thl(k) +q2p*QCp*Aup ! potential temp (env + plume) bb = b9*tk(k)/pt ! bb is "b9" in BCMT95. Their "b9" differs from ! "b9" in CB02 by a factor ! of T/theta. Strictly, b9 above is formulated in @@ -6748,17 +6664,33 @@ SUBROUTINE DMP_mf( & endif !CB form: - !sigq = 9.E-3 * 0.5*(edmf_a(k)+edmf_a(k-1)) * & - ! & 0.5*(edmf_w(k)+edmf_w(k-1)) * f ! convective component of sigma (CB2005) + !sigq = 3.5E-3 * Aup * 0.5*(edmf_w(k)+edmf_w(k-1)) * f ! convective component of sigma (CB2005) !sigq = SQRT(sigq**2 + sgm(k)**2) ! combined conv + stratus components !Per S.DeRoode 2009? - sigq = 10. * edmf_a(k) * (edmf_qt(k)-qt(k)) - - sigq = MAX(sigq, 1.0E-6) + !sigq = 5. * Aup * (QTp - qt(k)) + sigq = 10. * Aup * (QTp - qt(k)) + !constrain sigq wrt saturation: + sigq = max(sigq, qsat_tk*0.02 ) + sigq = min(sigq, qsat_tk*0.25 ) qmq = a * (qt(k) - qsat_tk) ! saturation deficit/excess; - ! the numerator of Q1 - mf_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.01),0.6) + Q1 = qmq/sigq ! the numerator of Q1 + + if ((landsea-1.5).GE.0) then ! WATER + !modified form from LES + !mf_cf = min(max(0.5 + 0.36 * atan(1.20*(Q1+0.2)),0.01),0.6) + !Original CB + mf_cf = min(max(0.5 + 0.36 * atan(1.55*Q1),0.01),0.6) + mf_cf = max(mf_cf, 1.2 * Aup) + mf_cf = min(mf_cf, 5.0 * Aup) + else ! LAND + !LES form + !mf_cf = min(max(0.5 + 0.36 * atan(1.20*(Q1+0.4)),0.01),0.6) + !Original CB + mf_cf = min(max(0.5 + 0.36 * atan(1.55*Q1),0.01),0.6) + mf_cf = max(mf_cf, 1.75 * Aup) + mf_cf = min(mf_cf, 5.0 * Aup) + endif !IF ( debug_code ) THEN ! print*,"In MYNN, StEM edmf" @@ -6769,74 +6701,71 @@ SUBROUTINE DMP_mf( & !ENDIF ! Update cloud fractions and specific humidities in grid cells - ! where the mass-flux scheme is active. Now, we also use the - ! stratus component of the SGS clouds as well. The stratus cloud - ! fractions (Ac_strat) are reduced slightly to give way to the - ! mass-flux SGS cloud fractions (Ac_mf). - IF (cldfra_bl1d(k) < 0.5) THEN - IF (mf_cf > 0.5*(edmf_a(k)+edmf_a(k-1))) THEN - !cldfra_bl1d(k) = mf_cf - !qc_bl1d(k) = QCp*0.5*(edmf_a(k)+edmf_a(k-1))/mf_cf - Ac_mf = mf_cf - Ac_strat = cldfra_bl1d(k)*(1.0-mf_cf) - cldfra_bl1d(k) = Ac_mf + Ac_strat - !dillute Qc from updraft area to larger cloud area - qc_mf = QCp*0.5*(edmf_a(k)+edmf_a(k-1))/mf_cf - !The mixing ratios from the stratus component are not well - !estimated in shallow-cumulus regimes. Ensure stratus clouds - !have mixing ratio similar to cumulus - QCs = MAX(qc_bl1d(k), 0.5*qc_mf) - qc_bl1d(k) = (qc_mf*Ac_mf + QCs*Ac_strat)/cldfra_bl1d(k) - ELSE - !cldfra_bl1d(k)=0.5*(edmf_a(k)+edmf_a(k-1)) - !qc_bl1d(k) = QCp - Ac_mf = 0.5*(edmf_a(k)+edmf_a(k-1)) - Ac_strat = cldfra_bl1d(k)*(1.0-Ac_mf) - cldfra_bl1d(k)=Ac_mf + Ac_strat - qc_mf = QCp - !Ensure stratus clouds have mixing ratio similar to cumulus - QCs = MAX(qc_bl1d(k), 0.5*qc_mf) - qc_bl1d(k) = (QCp*Ac_mf + QCs*Ac_strat)/cldfra_bl1d(k) - ENDIF - ELSE - Ac_mf = mf_cf - ENDIF + ! where the mass-flux scheme is active. The specific humidities + ! are converted to grid means (not in-cloud quantities). + if ((landsea-1.5).GE.0) then ! water + if (QCp * Aup > 5e-5) then + qc_bl1d(k) = 1.86 * (QCp * Aup) - 2.2e-5 + else + qc_bl1d(k) = 1.18 * (QCp * Aup) + endif + if (mf_cf .ge. Aup) then + qc_bl1d(k) = qc_bl1d(k) / mf_cf + endif + cldfra_bl1d(k) = mf_cf + Ac_mf = mf_cf + else ! land + if (QCp * Aup > 5e-5) then + qc_bl1d(k) = 1.86 * (QCp * Aup) - 2.2e-5 + else + qc_bl1d(k) = 1.18 * (QCp * Aup) + endif + if (mf_cf .ge. Aup) then + qc_bl1d(k) = qc_bl1d(k) / mf_cf + endif + cldfra_bl1d(k) = mf_cf + Ac_mf = mf_cf + endif !Now recalculate the terms for the buoyancy flux for mass-flux clouds: - !See mym_condensation for details on these formulations. The - !cloud-fraction bounding was added to improve cloud retention, - !following RAP and HRRR testing. - !Fng = 2.05 ! the non-Gaussian transport factor (assumed constant) - !Use Bechtold and Siebesma (1998) piecewise estimation of Fng: - Q1 = qmq/MAX(sigq,1E-6) - Q1=MAX(Q1,-5.0) - IF (Q1 .GE. 1.0) THEN + !See mym_condensation for details on these formulations. + !Use Bechtold and Siebesma (1998) piecewise estimation of Fng with + !limits ,since they really should be recalculated after all the other changes...: + !Only overwrite vt & vq in non-stratus condition + !if ((landsea-1.5).GE.0) then ! WATER + Q1=max(Q1,-2.25) + !else + ! Q1=max(Q1,-2.0) + !endif + + if (Q1 .ge. 1.0) then Fng = 1.0 - ELSEIF (Q1 .GE. -1.7 .AND. Q1 .LT. 1.0) THEN + elseif (Q1 .ge. -1.7 .and. Q1 .lt. 1.0) then Fng = EXP(-0.4*(Q1-1.0)) - ELSEIF (Q1 .GE. -2.5 .AND. Q1 .LT. -1.7) THEN + elseif (Q1 .ge. -2.5 .and. Q1 .lt. -1.7) then Fng = 3.0 + EXP(-3.8*(Q1+1.7)) - ELSE - Fng = MIN(23.9 + EXP(-1.6*(Q1+2.5)), 60.) - ENDIF + else + Fng = min(23.9 + EXP(-1.6*(Q1+2.5)), 60.) + endif - vt(k) = qww - MIN(0.40,Ac_mf)*beta*bb*Fng - 1. - vq(k) = alpha + MIN(0.40,Ac_mf)*beta*a*Fng - tv0 - ENDIF - ENDDO + !link the buoyancy flux function to active clouds only (c*Aup): + vt(k) = qww - (1.5*Aup)*beta*bb*Fng - 1. + vq(k) = alpha + (1.5*Aup)*beta*a*Fng - tv0 + endif !check for (qc in plume) .and. (cldfra_bl < threshold) + enddo !k-loop ENDIF !end nup2 > 0 !modify output (negative: dry plume, positive: moist plume) - IF (ktop > 0) THEN + if (ktop > 0) then maxqc = maxval(edmf_qc(1:ktop)) - IF ( maxqc < 1.E-8) maxmf = -1.0*maxmf - ENDIF + if ( maxqc < 1.E-8) maxmf = -1.0*maxmf + endif ! -! debugging +! debugging ! -IF (edmf_w(1) > 4.0) THEN +if (edmf_w(1) > 4.0) then ! surface values print *,'flq:',flq,' fltv:',fltv2 print *,'pblh:',pblh,' wstar:',wstar @@ -6883,16 +6812,18 @@ SUBROUTINE DMP_mf( & END SUBROUTINE DMP_MF !================================================================= -!>\ingroup gp_mynnedmf -!! zero or one condensation for edmf: calculates THV and QC +!>\ingroup gsd_mynn_edmf +!! This subroutine subroutine condensation_edmf(QT,THL,P,zagl,THV,QC) ! -real,intent(in) :: QT,THL,P,zagl -real,intent(out) :: THV -real,intent(inout):: QC +! zero or one condensation for edmf: calculates THV and QC +! +real(kind_phys),intent(in) :: QT,THL,P,zagl +real(kind_phys),intent(out) :: THV +real(kind_phys),intent(inout):: QC integer :: niter,i -real :: diff,exn,t,th,qs,qcold +real(kind_phys):: diff,exn,t,th,qs,qcold ! constants used from module_model_constants.F ! p1000mb @@ -6934,7 +6865,7 @@ subroutine condensation_edmf(QT,THL,P,zagl,THV,QC) !THIS BASICALLY GIVE THE SAME RESULT AS THE PREVIOUS LINE !TH = THL + xlv/cp/EXN*QC - !THV= TH*(1. + 0.608*QT) + !THV= TH*(1. + p608*QT) !print *,'t,p,qt,qs,qc' !print *,t,p,qt,qs,qc @@ -6944,15 +6875,16 @@ end subroutine condensation_edmf !=============================================================== -!> zero or one condensation for edmf: calculates THL and QC -!! similar to condensation_edmf but with different inputs subroutine condensation_edmf_r(QT,THL,P,zagl,THV,QC) ! -real,intent(in) :: QT,THV,P,zagl -real,intent(out) :: THL, QC +! zero or one condensation for edmf: calculates THL and QC +! similar to condensation_edmf but with different inputs +! +real(kind_phys),intent(in) :: QT,THV,P,zagl +real(kind_phys),intent(out) :: THL, QC integer :: niter,i -real :: diff,exn,t,th,qs,qcold +real(kind_phys):: diff,exn,t,th,qs,qcold ! number of iterations niter=50 @@ -6979,10 +6911,12 @@ subroutine condensation_edmf_r(QT,THL,P,zagl,THV,QC) end subroutine condensation_edmf_r !=============================================================== -!> This is the downdraft mass flux scheme - analogus to edmf_JPL but -!! flipped updraft to downdraft. This scheme is currently only tested -!! for Stratocumulus cloud conditions. For a detailed desctiption of the -!! model, see paper. +! =================================================================== +! This is the downdraft mass flux scheme - analogus to edmf_JPL but +! flipped updraft to downdraft. This scheme is currently only tested +! for Stratocumulus cloud conditions. For a detailed desctiption of the +! model, see paper. + SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & &u,v,th,thl,thv,tk,qt,qv,qc, & &rho,exner, & @@ -6996,57 +6930,58 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & &rthraten ) INTEGER, INTENT(IN) :: KTS,KTE,KPBL - REAL,DIMENSION(KTS:KTE), INTENT(IN) :: U,V,TH,THL,TK,QT,QV,QC,& - THV,P,rho,exner,rthraten,dz + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: U,V,TH,THL,TK,QT,QV,QC,& + THV,P,rho,exner,dz + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: rthraten ! zw .. heights of the downdraft levels (edges of boxes) - REAL,DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW - REAL, INTENT(IN) :: DT,UST,WTHL,WQT,PBLH - + real(kind_phys),DIMENSION(KTS:KTE+1), INTENT(IN) :: ZW + real(kind_phys), INTENT(IN) :: WTHL,WQT + real(kind_phys), INTENT(IN) :: dt,ust,pblh ! outputs - downdraft properties - REAL,DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a_dd,edmf_w_dd, & + real(kind_phys),DIMENSION(KTS:KTE), INTENT(OUT) :: edmf_a_dd,edmf_w_dd, & & edmf_qt_dd,edmf_thl_dd, edmf_ent_dd,edmf_qc_dd ! outputs - variables needed for solver (sd_aw - sum ai*wi, sd_awphi - sum ai*wi*phii) - REAL,DIMENSION(KTS:KTE+1) :: sd_aw, sd_awthl, sd_awqt, sd_awu, & + real(kind_phys),DIMENSION(KTS:KTE+1) :: sd_aw, sd_awthl, sd_awqt, sd_awu, & sd_awv, sd_awqc, sd_awqv, sd_awqke, sd_aw2 - REAL,DIMENSION(KTS:KTE), INTENT(IN) :: qc_bl1d, cldfra_bl1d + real(kind_phys),DIMENSION(KTS:KTE), INTENT(IN) :: qc_bl1d, cldfra_bl1d INTEGER, PARAMETER :: NDOWN=5, debug_mf=0 !fixing number of plumes to 5 ! draw downdraft starting height randomly between cloud base and cloud top INTEGER, DIMENSION(1:NDOWN) :: DD_initK - REAL , DIMENSION(1:NDOWN) :: randNum + real(kind_phys) , DIMENSION(1:NDOWN) :: randNum ! downdraft properties - REAL,DIMENSION(KTS:KTE+1,1:NDOWN) :: DOWNW,DOWNTHL,DOWNQT,& + real(kind_phys),DIMENSION(KTS:KTE+1,1:NDOWN) :: DOWNW,DOWNTHL,DOWNQT,& DOWNQC,DOWNA,DOWNU,DOWNV,DOWNTHV ! entrainment variables - REAl,DIMENSION(KTS+1:KTE+1,1:NDOWN) :: ENT,ENTf + Real(Kind_phys),DIMENSION(KTS+1:KTE+1,1:NDOWN) :: ENT,ENTf INTEGER,DIMENSION(KTS+1:KTE+1,1:NDOWN) :: ENTi ! internal variables INTEGER :: K,I,ki, kminrad, qlTop, p700_ind, qlBase - REAL :: wthv,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & + real(kind_phys):: wthv,wstar,qstar,thstar,sigmaW,sigmaQT,sigmaTH,z0, & pwmin,pwmax,wmin,wmax,wlv,wtv,went,mindownw - REAL :: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,Wn2,Wn,THVk,Pk, & + real(kind_phys):: B,QTn,THLn,THVn,QCn,Un,Vn,QKEn,Wn2,Wn,THVk,Pk, & EntEXP,EntW, Beta_dm, EntExp_M, rho_int - REAL :: jump_thetav, jump_qt, jump_thetal, & + real(kind_phys):: jump_thetav, jump_qt, jump_thetal, & refTHL, refTHV, refQT ! DD specific internal variables - REAL :: minrad,zminrad, radflux, F0, wst_rad, wst_dd + real(kind_phys):: minrad,zminrad, radflux, F0, wst_rad, wst_dd logical :: cloudflg - REAL :: sigq,xl,rsl,cpm,a,mf_cf,diffqt,& + real(kind_phys):: sigq,xl,rsl,cpm,a,mf_cf,diffqt,& Fng,qww,alpha,beta,bb,f,pt,t,q2p,b9,satvp,rhgrid ! w parameters - REAL,PARAMETER :: & + real(kind_phys),PARAMETER :: & &Wa=1., & &Wb=1.5,& &Z00=100.,& &BCOEFF=0.2 ! entrainment parameters - REAL,PARAMETER :: & + real(kind_phys),PARAMETER :: & & L0=80,& & ENT0=0.2 @@ -7108,7 +7043,7 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & do i=1,NDOWN ! downdraft starts somewhere between cloud base to cloud top ! the probability is equally distributed - DD_initK(i) = qlTop ! nint(randNum(i)*REAL(qlTop-qlBase)) + qlBase + DD_initK(i) = qlTop ! nint(randNum(i)*real(qlTop-qlBase)) + qlBase enddo ! LOOP RADFLUX @@ -7178,13 +7113,13 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & do I=1,NDOWN !downdraft now starts at different height ki = DD_initK(I) - wlv=wmin+(wmax-wmin)/REAL(NDOWN)*(i-1) - wtv=wmin+(wmax-wmin)/REAL(NDOWN)*i + wlv=wmin+(wmax-wmin)/real(NDOWN)*(i-1) + wtv=wmin+(wmax-wmin)/real(NDOWN)*i !DOWNW(ki,I)=0.5*(wlv+wtv) DOWNW(ki,I)=wlv !DOWNA(ki,I)=0.5*ERF(wtv/(sqrt(2.)*sigmaW))-0.5*ERF(wlv/(sqrt(2.)*sigmaW)) - DOWNA(ki,I)=.1/REAL(NDOWN) + DOWNA(ki,I)=.1/real(NDOWN) DOWNU(ki,I)=(u(ki-1)*DZ(ki) + u(ki)*DZ(ki-1)) /(DZ(ki)+DZ(ki-1)) DOWNV(ki,I)=(v(ki-1)*DZ(ki) + v(ki)*DZ(ki-1)) /(DZ(ki)+DZ(ki-1)) @@ -7342,19 +7277,21 @@ SUBROUTINE DDMF_JPL(kts,kte,dt,zw,dz,p, & END SUBROUTINE DDMF_JPL !=============================================================== -!> Add scale-aware factor (Psig) here, taken from Honnert et al. (2011) \cite Honnert_2011 -!! and/or from Shin and Hong (2013) \cite Shin_2013. + SUBROUTINE SCALE_AWARE(dx,PBL1,Psig_bl,Psig_shcu) !--------------------------------------------------------------- ! NOTES ON SCALE-AWARE FORMULATION ! + !JOE: add scale-aware factor (Psig) here, taken from Honnert et al. (2011, + ! JAS) and/or from Hyeyum Hailey Shin and Song-You Hong (2013, JAS) + ! ! Psig_bl tapers local mixing ! Psig_shcu tapers nonlocal mixing - REAL,INTENT(IN) :: dx,PBL1 - REAL, INTENT(OUT) :: Psig_bl,Psig_shcu - REAL :: dxdh + real(kind_phys), INTENT(IN) :: dx,pbl1 + real(kind_phys), INTENT(OUT) :: Psig_bl,Psig_shcu + real(kind_phys) :: dxdh Psig_bl=1.0 Psig_shcu=1.0 @@ -7415,7 +7352,7 @@ SUBROUTINE SCALE_AWARE(dx,PBL1,Psig_bl,Psig_shcu) END SUBROUTINE SCALE_AWARE ! ===================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! \author JAYMES- added 22 Apr 2015 !! This function calculates saturation vapor pressure. Separate ice and liquid functions !! are used (identical to those in module_mp_thompson.F, v3.6). Then, the @@ -7426,22 +7363,42 @@ FUNCTION esat_blend(t) IMPLICIT NONE - REAL, INTENT(IN):: t - REAL :: esat_blend,XC,ESL,ESI,chi - - XC=MAX(-80.,t - t0c) !note t0c = 273.15, tice is set in module mynn_common - -! For 253 < t < 273.16 K, the vapor pressures are "blended" as a function of temperature, -! using the approach of Chaboureau and Bechtold (2002), JAS, p. 2363. The resulting + real(kind_phys), INTENT(IN):: t + real(kind_phys):: esat_blend,XC,ESL,ESI,chi + !liquid + real(kind_phys), PARAMETER:: J0= .611583699E03 + real(kind_phys), PARAMETER:: J1= .444606896E02 + real(kind_phys), PARAMETER:: J2= .143177157E01 + real(kind_phys), PARAMETER:: J3= .264224321E-1 + real(kind_phys), PARAMETER:: J4= .299291081E-3 + real(kind_phys), PARAMETER:: J5= .203154182E-5 + real(kind_phys), PARAMETER:: J6= .702620698E-8 + real(kind_phys), PARAMETER:: J7= .379534310E-11 + real(kind_phys), PARAMETER:: J8=-.321582393E-13 + !ice + real(kind_phys), PARAMETER:: K0= .609868993E03 + real(kind_phys), PARAMETER:: K1= .499320233E02 + real(kind_phys), PARAMETER:: K2= .184672631E01 + real(kind_phys), PARAMETER:: K3= .402737184E-1 + real(kind_phys), PARAMETER:: K4= .565392987E-3 + real(kind_phys), PARAMETER:: K5= .521693933E-5 + real(kind_phys), PARAMETER:: K6= .307839583E-7 + real(kind_phys), PARAMETER:: K7= .105785160E-9 + real(kind_phys), PARAMETER:: K8= .161444444E-12 + + XC=MAX(-80.,t - t0c) !note t0c = 273.15, tice is set in module mynn_common to 240 + +! For 240 < t < 268.16 K, the vapor pressures are "blended" as a function of temperature, +! using the approach similar to Chaboureau and Bechtold (2002), JAS, p. 2363. The resulting ! values are returned from the function. - IF (t .GE. t0c) THEN + IF (t .GE. (t0c-6.)) THEN esat_blend = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) ELSE IF (t .LE. tice) THEN esat_blend = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) ELSE - ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) - ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) - chi = (t0c - t)/(t0c - tice) + ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) + chi = ((t0c-6.) - t)/((t0c-6.) - tice) esat_blend = (1.-chi)*ESL + chi*ESI END IF @@ -7449,41 +7406,56 @@ END FUNCTION esat_blend ! ==================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This function extends function "esat" and returns a "blended" -!! saturation mixing ratio. +!! saturation mixing ratio. Tice currently set to 240 K, t0c = 273.15 K. !!\author JAYMES - FUNCTION qsat_blend(t, P, waterice) + FUNCTION qsat_blend(t, P) IMPLICIT NONE - REAL, INTENT(IN):: t, P - CHARACTER(LEN=1), OPTIONAL, INTENT(IN) :: waterice - CHARACTER(LEN=1) :: wrt - REAL :: qsat_blend,XC,ESL,ESI,RSLF,RSIF,chi - - IF ( .NOT. PRESENT(waterice) ) THEN - wrt = 'b' - ELSE - wrt = waterice - ENDIF + real(kind_phys), INTENT(IN):: t, P + real(kind_phys):: qsat_blend,XC,ESL,ESI,RSLF,RSIF,chi + !liquid + real(kind_phys), PARAMETER:: J0= .611583699E03 + real(kind_phys), PARAMETER:: J1= .444606896E02 + real(kind_phys), PARAMETER:: J2= .143177157E01 + real(kind_phys), PARAMETER:: J3= .264224321E-1 + real(kind_phys), PARAMETER:: J4= .299291081E-3 + real(kind_phys), PARAMETER:: J5= .203154182E-5 + real(kind_phys), PARAMETER:: J6= .702620698E-8 + real(kind_phys), PARAMETER:: J7= .379534310E-11 + real(kind_phys), PARAMETER:: J8=-.321582393E-13 + !ice + real(kind_phys), PARAMETER:: K0= .609868993E03 + real(kind_phys), PARAMETER:: K1= .499320233E02 + real(kind_phys), PARAMETER:: K2= .184672631E01 + real(kind_phys), PARAMETER:: K3= .402737184E-1 + real(kind_phys), PARAMETER:: K4= .565392987E-3 + real(kind_phys), PARAMETER:: K5= .521693933E-5 + real(kind_phys), PARAMETER:: K6= .307839583E-7 + real(kind_phys), PARAMETER:: K7= .105785160E-9 + real(kind_phys), PARAMETER:: K8= .161444444E-12 XC=MAX(-80.,t - t0c) - IF ((t .GE. t0c) .OR. (wrt .EQ. 'w')) THEN - ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + IF (t .GE. (t0c-6.)) THEN + ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + ESL = min(ESL, P*0.15) ! Even with P=1050mb and T=55C, the sat. vap. pres only contributes to ~15% of total pres. qsat_blend = 0.622*ESL/max(P-ESL, 1e-5) -! ELSE IF (t .LE. 253.) THEN ELSE IF (t .LE. tice) THEN ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) + ESI = min(ESI, P*0.15) qsat_blend = 0.622*ESI/max(P-ESI, 1e-5) ELSE ESL = J0+XC*(J1+XC*(J2+XC*(J3+XC*(J4+XC*(J5+XC*(J6+XC*(J7+XC*J8))))))) + ESL = min(ESL, P*0.15) ESI = K0+XC*(K1+XC*(K2+XC*(K3+XC*(K4+XC*(K5+XC*(K6+XC*(K7+XC*K8))))))) + ESI = min(ESI, P*0.15) RSLF = 0.622*ESL/max(P-ESL, 1e-5) RSIF = 0.622*ESI/max(P-ESI, 1e-5) -! chi = (273.16-t)/20.16 - chi = (t0c - t)/(t0c - tice) +! chi = (268.16-t)/(268.16-240.) + chi = ((t0c-6.) - t)/((t0c-6.) - tice) qsat_blend = (1.-chi)*RSLF + chi*RSIF END IF @@ -7491,7 +7463,7 @@ END FUNCTION qsat_blend ! =================================================================== -!>\ingroup gp_mynnedmf +!>\ingroup gsd_mynn_edmf !! This function interpolates the latent heats of vaporization and sublimation into !! a single, temperature-dependent, "blended" value, following !! Chaboureau and Bechtold (2002) \cite Chaboureau_2002, Appendix. @@ -7500,8 +7472,8 @@ FUNCTION xl_blend(t) IMPLICIT NONE - REAL, INTENT(IN):: t - REAL :: xl_blend,xlvt,xlst,chi + real(kind_phys), INTENT(IN):: t + real(kind_phys):: xl_blend,xlvt,xlst,chi !note: t0c = 273.15, tice is set in mynn_common IF (t .GE. t0c) THEN @@ -7511,7 +7483,7 @@ FUNCTION xl_blend(t) ELSE xlvt = xlv + (cpv-cliq)*(t-t0c) !vaporization/condensation xlst = xls + (cpv-cice)*(t-t0c) !sublimation/deposition -! chi = (273.16-t)/20.16 +! chi = (273.16-t)/(273.16-240.) chi = (t0c - t)/(t0c - tice) xl_blend = (1.-chi)*xlvt + chi*xlst !blended END IF @@ -7519,21 +7491,22 @@ FUNCTION xl_blend(t) END FUNCTION xl_blend ! =================================================================== -!> New stability function parameters for momentum (Puhales, 2020, WRF 4.2.1) -!! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of -!! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly -!! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an -!! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very -!! stable conditions [z/L ~ O(10)]. + FUNCTION phim(zet) + ! New stability function parameters for momentum (Puhales, 2020, WRF 4.2.1) + ! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of + ! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly + ! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an + ! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very + ! stable conditions [z/L ~ O(10)]. IMPLICIT NONE - REAL, INTENT(IN):: zet - REAL :: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi - REAL, PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st - REAL, PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st - REAL, PARAMETER :: am_unst=10., ah_unst=34. - REAL :: phi_m,phim + real(kind_phys), INTENT(IN):: zet + real(kind_phys):: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi + real(kind_phys), PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st + real(kind_phys), PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st + real(kind_phys), PARAMETER :: am_unst=10., ah_unst=34. + real(kind_phys):: phi_m,phim if ( zet >= 0.0 ) then dummy_0=1+zet**bm_st @@ -7569,22 +7542,23 @@ FUNCTION phim(zet) phim = phi_m END FUNCTION phim +! =================================================================== -!> New stability function parameters for heat (Puhales, 2020, WRF 4.2.1) -!! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of -!! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly -!! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an -!! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very -!! stable conditions [z/L ~ O(10)]. FUNCTION phih(zet) + ! New stability function parameters for heat (Puhales, 2020, WRF 4.2.1) + ! The forms in unstable conditions (z/L < 0) use Grachev et al. (2000), which are a blend of + ! the classical (Kansas) forms (i.e., Paulson 1970, Dyer and Hicks 1970), valid for weakly + ! unstable conditions (-1 < z/L < 0). The stability functions for stable conditions use an + ! updated form taken from Cheng and Brutsaert (2005), which extends the validity into very + ! stable conditions [z/L ~ O(10)]. IMPLICIT NONE - REAL, INTENT(IN):: zet - REAL :: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi - REAL, PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st - REAL, PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st - REAL, PARAMETER :: am_unst=10., ah_unst=34. - REAL :: phh,phih + real(kind_phys), INTENT(IN):: zet + real(kind_phys):: dummy_0,dummy_1,dummy_11,dummy_2,dummy_22,dummy_3,dummy_33,dummy_4,dummy_44,dummy_psi + real(kind_phys), PARAMETER :: am_st=6.1, bm_st=2.5, rbm_st=1./bm_st + real(kind_phys), PARAMETER :: ah_st=5.3, bh_st=1.1, rbh_st=1./bh_st + real(kind_phys), PARAMETER :: am_unst=10., ah_unst=34. + real(kind_phys):: phh,phih if ( zet >= 0.0 ) then dummy_0=1+zet**bh_st @@ -7618,29 +7592,29 @@ FUNCTION phih(zet) END FUNCTION phih ! ================================================================== -!>\ingroup gp_mynnedmf -!! Calculate the buoyancy production of TKE from cloud-top cooling. SUBROUTINE topdown_cloudrad(kts,kte,dz1,zw,xland,kpbl,PBLH, & &sqc,sqi,sqw,thl,th1,ex1,p1,rho1,thetav, & &cldfra_bl1D,rthraten, & &maxKHtopdown,KHtopdown,TKEprodTD ) !input - integer, intent(in) :: kte,kts - real, dimension(kts:kte), intent(in) :: dz1,sqc,sqi,sqw,& - thl,th1,ex1,p1,rho1,thetav,cldfra_bl1D,rthraten - real, dimension(kts:kte+1), intent(in) :: zw - real, intent(in) :: pblh,xland - integer,intent(in) :: kpbl + integer, intent(in) :: kte,kts + real(kind_phys), dimension(kts:kte), intent(in) :: dz1,sqc,sqi,sqw,& + thl,th1,ex1,p1,rho1,thetav,cldfra_bl1D + real(kind_phys), dimension(kts:kte), intent(in) :: rthraten + real(kind_phys), dimension(kts:kte+1), intent(in) :: zw + real(kind_phys), intent(in) :: pblh + real(kind_phys), intent(in) :: xland + integer , intent(in) :: kpbl !output - real, intent(out) :: maxKHtopdown - real, dimension(kts:kte), intent(out) :: KHtopdown,TKEprodTD + real(kind_phys), intent(out) :: maxKHtopdown + real(kind_phys), dimension(kts:kte), intent(out) :: KHtopdown,TKEprodTD !local - real, dimension(kts:kte) :: zfac,wscalek2,zfacent - real :: bfx0,sflux,wm2,wm3,h1,h2,bfxpbl,dthvx,tmp1 - real :: temps,templ,zl1,wstar3_2 - real :: ent_eff,radsum,radflux,we,rcldb,rvls,minrad,zminrad - real, parameter :: pfac =2.0, zfmin = 0.01, phifac=8.0 + real(kind_phys), dimension(kts:kte) :: zfac,wscalek2,zfacent + real(kind_phys) :: bfx0,sflux,wm2,wm3,h1,h2,bfxpbl,dthvx,tmp1 + real(kind_phys) :: temps,templ,zl1,wstar3_2 + real(kind_phys) :: ent_eff,radsum,radflux,we,rcldb,rvls,minrad,zminrad + real(kind_phys), parameter :: pfac =2.0, zfmin = 0.01, phifac=8.0 integer :: k,kk,kminrad logical :: cloudflg diff --git a/physics/module_gfdl_cloud_microphys.F90 b/physics/module_gfdl_cloud_microphys.F90 index 3ebcfc587..5cab1abbc 100644 --- a/physics/module_gfdl_cloud_microphys.F90 +++ b/physics/module_gfdl_cloud_microphys.F90 @@ -3563,7 +3563,8 @@ end subroutine setupm !>\ingroup mod_gfdl_cloud_mp !! The subroutine 'gfdl_cloud_microphys_init' initializes the GFDL !! cloud microphysics. -subroutine gfdl_cloud_microphys_mod_init (me, master, nlunit, input_nml_file, logunit, fn_nml) +subroutine gfdl_cloud_microphys_mod_init (me, master, nlunit, input_nml_file, logunit, & + fn_nml, errmsg, errflg) implicit none @@ -3574,6 +3575,8 @@ subroutine gfdl_cloud_microphys_mod_init (me, master, nlunit, input_nml_file, lo character (len = 64), intent (in) :: fn_nml character (len = *), intent (in) :: input_nml_file(:) + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg integer :: ios logical :: exists @@ -3588,13 +3591,19 @@ subroutine gfdl_cloud_microphys_mod_init (me, master, nlunit, input_nml_file, lo ! master = (mpp_pe () .eq.mpp_root_pe ()) + ! Initialize CCPP error-handling + errflg = 0 + errmsg = '' + #ifdef INTERNAL_FILE_NML read (input_nml_file, nml = gfdl_cloud_microphysics_nml) #else inquire (file = trim (fn_nml), exist = exists) if (.not. exists) then write (6, *) 'gfdl - mp :: namelist file: ', trim (fn_nml), ' does not exist' - stop + errflg = 1 + errmsg = 'ERROR(gfdl_cloud_microphys_mod_init): namelist file '//trim (fn_nml)//' does not exist' + return else open (unit = nlunit, file = fn_nml, action = 'read' , status = 'old', iostat = ios) endif diff --git a/physics/module_mp_nssl_2mom.F90 b/physics/module_mp_nssl_2mom.F90 index 6b184c35f..d190e94b4 100644 --- a/physics/module_mp_nssl_2mom.F90 +++ b/physics/module_mp_nssl_2mom.F90 @@ -1228,6 +1228,7 @@ SUBROUTINE nssl_2mom_init( & rho_qh = nssl_params(8) rho_qhl = nssl_params(9) rho_qs = nssl_params(10) + alphar = nssl_params(14) ! ipelec = Nint(nssl_params(11)) ! isaund = Nint(nssl_params(12)) @@ -8117,7 +8118,8 @@ subroutine radardd02(nx,ny,nz,nor,na,an,temk, & ! write(0,*) 'Hail,snow c: ',an(ix,jy,kz,lnh),an(ix,jy,kz,lns) ! write(0,*) 'dtmps,dtmph = ',dtmps,dtmph ! ENDIF - IF ( .not. dtmp(ix,kz) .lt. 1.e30 .or. dbz(ix,jy,kz) > 190.0 ) THEN + + IF ( ndebug>1 .and. .not. dtmp(ix,kz) .lt. 1.e30 .or. dbz(ix,jy,kz) > 190.0 ) THEN ! IF ( ix == 31 .and. kz == 20 .and. jy == 23 ) THEN ! write(0,*) 'my_rank = ',my_rank write(0,*) 'ix,jy,kz = ',ix,jy,kz diff --git a/physics/module_mp_thompson.F90 b/physics/module_mp_thompson.F90 index 70c48feba..b828c9ab0 100644 --- a/physics/module_mp_thompson.F90 +++ b/physics/module_mp_thompson.F90 @@ -1003,7 +1003,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & ids,ide, jds,jde, kds,kde, & ! domain dims ims,ime, jms,jme, kms,kme, & ! memory dims its,ite, jts,jte, kts,kte, & ! tile dims - reset_dBZ, istep, nsteps, & + fullradar_diag, istep, nsteps, & errmsg, errflg, & ! Extended diagnostics, array pointers ! only associated if ext_diag flag is .true. @@ -1070,7 +1070,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & INTEGER, INTENT(IN) :: decfl ! To support subcycling: current step and maximum number of steps INTEGER, INTENT (IN) :: istep, nsteps - LOGICAL, INTENT (IN) :: reset_dBZ + LOGICAL, INTENT (IN) :: fullradar_diag ! Extended diagnostics, array pointers only associated if ext_diag flag is .true. LOGICAL, INTENT (IN) :: ext_diag LOGICAL, OPTIONAL, INTENT(IN):: aero_ind_fdb @@ -1677,7 +1677,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & if (diagflag .and. do_radar_ref == 1) then ! ! Only set melti to true at the output times - if (reset_dBZ) then + if (fullradar_diag) then melti=.true. else melti=.false. diff --git a/physics/module_sf_exchcoef.f90 b/physics/module_sf_exchcoef.f90 index 0e3dae80c..6ec9ed835 100644 --- a/physics/module_sf_exchcoef.f90 +++ b/physics/module_sf_exchcoef.f90 @@ -636,7 +636,7 @@ SUBROUTINE znot_t_v8(uref,znott) END SUBROUTINE znot_t_v8 - SUBROUTINE znot_wind10m(w10m,znott,znotm,icoef_sf) + SUBROUTINE znot_wind10m(w10m,znott,znotm,icoef_sf,errmsg,errflg) IMPLICIT NONE ! w10m(m/s) : 10-m wind speed @@ -647,8 +647,15 @@ SUBROUTINE znot_wind10m(w10m,znott,znotm,icoef_sf) REAL, INTENT(IN) :: w10m INTEGER, INTENT(IN) :: icoef_sf REAL, INTENT(OUT):: znott, znotm + character(len=*),intent(out) :: errmsg + integer, intent(out) :: errflg real :: zm,zt,windmks, zlev,z10, tmp, zlevt, aaa, zm1,zt1 + + ! Initialize error-handling + errflg = 0 + errmsg = '' + zlev=20.0 zlevt=10.0 z10=10.0 @@ -722,7 +729,9 @@ SUBROUTINE znot_wind10m(w10m,znott,znotm,icoef_sf) call znot_t_v8(windmks,zt1) else write(0,*)'stop, icoef_sf must be one of 0,1,2,3,4,5,6,7,8' - stop + errflg = 1 + errmsg = 'ERROR(znot_wind10m): icoef_sf must be one of 0,1,2,3,4,5,6,7,8' + return endif znott=zt1 znotm=zm1 diff --git a/physics/module_sf_mynn.F90 b/physics/module_sf_mynn.F90 index 4a908d206..33678fa3a 100644 --- a/physics/module_sf_mynn.F90 +++ b/physics/module_sf_mynn.F90 @@ -1,5 +1,5 @@ !>\file module_sf_mynn.F90 -!! This file contains +!! This file contains !WRF:MODEL_LAYER:PHYSICS ! !>\ingroup mynn_sfc @@ -17,10 +17,10 @@ MODULE module_sf_mynn !2) Fixed isflux=0 option to turn off scalar fluxes, but keep momentum ! fluxes for idealized studies (credit: Anna Fitch). !3) Kinematic viscosity varies with temperature according to Andreas (1989). -!4) Uses the blended Monin-Obukhov flux-profile relationships COARE (Fairall +!4) Uses the blended Monin-Obukhov flux-profile relationships COARE (Fairall ! et al 2003) for the unstable regime (a blended mix of Dyer-Hicks 1974 and ! Grachev et al (2000). Uses Cheng and Brutsaert (2005) for stable conditions. -!5) The following overviews the namelist variables that control the +!5) The following overviews the namelist variables that control the ! aerodynamic roughness lengths (over water) and the thermal and moisture ! roughness lengths (defaults are recommended): ! @@ -36,7 +36,7 @@ MODULE module_sf_mynn ! "isftcflx" namelist option is used to select the following scalar options: ! (default) =0: z0, zt, and zq from the COARE algorithm. Set COARE_OPT (below) to ! 3.0 (Fairall et al. 2003, default) -! 3.5 (Edson et al 2013) +! 3.5 (Edson et al 2013) ! =1: z0 from Davis et al (2008), zt & zq from COARE 3.0/3.5 ! =2: z0 from Davis et al (2008), zt & zq from Garratt (1992) ! =3: z0 from Taylor and Yelland (2004), zt and zq from COARE 3.0/3.5 @@ -45,7 +45,7 @@ MODULE module_sf_mynn ! SNOW/ICE only: ! Andreas (2002) snow/ice parameterization for thermal and ! moisture roughness is used over all gridpoints with snow deeper than -! 0.1 m. This algorithm calculates a z0 for snow (Andreas et al. 2005, BLM), +! 0.1 m. This algorithm calculates a z0 for snow (Andreas et al. 2005, BLM), ! which is only used as part of the thermal and moisture roughness ! length calculation, not to directly impact the surface winds. ! @@ -56,7 +56,7 @@ MODULE module_sf_mynn ! !2) Option to activate stochastic parameter perturbations (SPP), which ! perturb z0, zt, and zq, along with many other parameters in the MYNN- -! EDMF scheme. +! EDMF scheme. ! !NOTE: This code was primarily tested in combination with the RUC LSM. ! Performance with the Noah (or other) LSM is relatively unknown. @@ -82,36 +82,41 @@ MODULE module_sf_mynn !use subroutines from sfc_diff: ! USE sfc_diff, only: znot_t_v6, znot_t_v7, znot_m_v6, znot_m_v7 +!use kind=kind_phys for real-types + use machine , only : kind_phys + !------------------------------------------------------------------- IMPLICIT NONE !------------------------------------------------------------------- !For non-WRF -! REAL , PARAMETER :: g = 9.81 -! REAL , PARAMETER :: r_d = 287. -! REAL , PARAMETER :: cp = 7.*r_d/2. -! REAL , PARAMETER :: r_v = 461.6 -! REAL , PARAMETER :: cpv = 4.*r_v -! REAL , PARAMETER :: rcp = r_d/cp -! REAL , PARAMETER :: XLV = 2.5E6 -! REAL , PARAMETER :: XLF = 3.50E5 - REAL , PARAMETER :: p1000mb = 100000. -! REAL , PARAMETER :: EP_2 = r_d/r_v - - REAL, PARAMETER :: xlvcp=xlv/cp, ep_3=1.-ep_2 - REAL, PARAMETER :: wmin=0.1 ! Minimum wind speed - REAL, PARAMETER :: VCONVC=1.25 - REAL, PARAMETER :: onethird = 1./3. - REAL, PARAMETER :: sqrt3 = 1.7320508075688773 - REAL, PARAMETER :: atan1 = 0.785398163397 !in radians - REAL, PARAMETER :: log01=log(0.01), log05=log(0.05), log07=log(0.07) - REAL, PARAMETER :: SNOWZ0=0.011 - REAL, PARAMETER :: COARE_OPT=3.0 ! 3.0 or 3.5 +! REAL(kind=kind_phys), PARAMETER :: g = 9.81 +! REAL(kind=kind_phys), PARAMETER :: r_d = 287. +! REAL(kind=kind_phys), PARAMETER :: cp = 7.*r_d/2. +! REAL(kind=kind_phys), PARAMETER :: r_v = 461.6 +! REAL(kind=kind_phys), PARAMETER :: cpv = 4.*r_v +! REAL(kind=kind_phys), PARAMETER :: rcp = r_d/cp +! REAL(kind=kind_phys), PARAMETER :: XLV = 2.5E6 +! REAL(kind=kind_phys), PARAMETER :: XLF = 3.50E5 + REAL(kind=kind_phys), PARAMETER :: p1000mb = 100000. +! REAL(kind=kind_phys), PARAMETER :: EP_2 = r_d/r_v + + REAL(kind=kind_phys), PARAMETER :: xlvcp=xlv/cp, ep_3=1.-ep_2 + REAL(kind=kind_phys), PARAMETER :: wmin=0.1 ! Minimum wind speed + REAL(kind=kind_phys), PARAMETER :: VCONVC=1.25 + REAL(kind=kind_phys), PARAMETER :: onethird = 1./3. + REAL(kind=kind_phys), PARAMETER :: sqrt3 = 1.7320508075688773 + REAL(kind=kind_phys), PARAMETER :: atan1 = 0.785398163397 !in radians + REAL(kind=kind_phys), PARAMETER :: log01=log(0.01) + REAL(kind=kind_phys), PARAMETER :: log05=log(0.05) + REAL(kind=kind_phys), PARAMETER :: log07=log(0.07) + REAL(kind=kind_phys), PARAMETER :: SNOWZ0=0.011 + REAL(kind=kind_phys), PARAMETER :: COARE_OPT=3.0 ! 3.0 or 3.5 !For debugging purposes: INTEGER, PARAMETER :: debug_code = 0 !0: no extra ouput !1: check input !2: everything - heavy I/O - REAL, DIMENSION(0:1000 ),SAVE :: psim_stab,psim_unstab, & + REAL(kind=kind_phys), DIMENSION(0:1000 ),SAVE :: psim_stab,psim_unstab, & psih_stab,psih_unstab CONTAINS @@ -193,7 +198,7 @@ SUBROUTINE SFCLAY_mynn( & !-- XLAND land mask (1 for land, 2 for water) !-- HFX upward heat flux at the surface (W/m^2) ! HFX = HFLX * rho * cp -!-- HFLX upward temperature flux at the surface (K m s^-1) +!-- HFLX upward temperature flux at the surface (K m s^-1) !-- QFX upward moisture flux at the surface (kg/m^2/s) ! QFX = QFLX * rho !-- QFLX upward moisture flux at the surface (kg kg-1 m s-1) @@ -211,7 +216,7 @@ SUBROUTINE SFCLAY_mynn( & !-- T2 diagnostic 2m temperature (K) !-- Q2 diagnostic 2m mixing ratio (kg/kg) !-- SNOWH Snow height (m) -!-- GZ1OZ0 log((z1+ZNT)/ZNT) where ZNT is roughness length +!-- GZ1OZ0 log((z1+ZNT)/ZNT) where ZNT is roughness length !-- WSPD wind speed at lowest model level (m/s) !-- BR bulk Richardson number in surface layer !-- ISFFLX isfflx=1 for surface heat and moisture fluxes @@ -232,7 +237,7 @@ SUBROUTINE SFCLAY_mynn( & ! (water =1: z0 from Davis et al (2008), zt & zq from COARE3.0/3.5 ! only) =2: z0 from Davis et al (2008), zt & zq from Garratt (1992) ! =3: z0 from Taylor and Yelland (2004), zt and zq from COARE 3.0/3.5 -!-- iz0tlnd =0: Zilitinkevich (1995) with Czil=0.085, +!-- iz0tlnd =0: Zilitinkevich (1995) with Czil=0.085, ! (land =1: Czil_new (modified according to Chen & Zhang 2008) ! only) =2: Modified Yang et al (2002, 2008) - generalized for all landuse ! =3: constant zt = z0/7.4 (Garratt 1992) @@ -264,9 +269,9 @@ SUBROUTINE SFCLAY_mynn( & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte INTEGER, INTENT(IN) :: itimestep,iter - REAL, INTENT(IN) :: SVP1,SVP2,SVP3,SVPT0 - REAL, INTENT(IN) :: EP1,EP2,KARMAN - REAL, INTENT(IN) :: CP,G,ROVCP,R,XLV !,DX + REAL(kind=kind_phys), INTENT(IN) :: SVP1,SVP2,SVP3,SVPT0 + REAL(kind=kind_phys), INTENT(IN) :: EP1,EP2,KARMAN + REAL(kind=kind_phys), INTENT(IN) :: CP,G,ROVCP,R,XLV !,DX !NAMELIST/CONFIGURATION OPTIONS: INTEGER, INTENT(IN) :: ISFFLX, LSM, LSM_RUC INTEGER, OPTIONAL, INTENT(IN) :: ISFTCFLX, IZ0TLND @@ -278,13 +283,13 @@ SUBROUTINE SFCLAY_mynn( & !Input data integer, dimension(ims:ime), intent(in) :: vegtype - real, dimension(ims:ime), intent(in) :: & + real(kind=kind_phys), dimension(ims:ime), intent(in) :: & & sigmaf,shdmax,z0pert,ztpert !=================================== ! 3D VARIABLES !=================================== - REAL, DIMENSION( ims:ime, kms:kme ) , & - INTENT(IN ) :: dz8w, & + REAL(kind=kind_phys), DIMENSION( ims:ime, kms:kme ) , & + INTENT(IN ) :: dz8w, & QV3D, & P3D, & T3D, & @@ -293,25 +298,25 @@ SUBROUTINE SFCLAY_mynn( & th3d,pi3d !GJF: This array must be assumed-shape since it is conditionally-allocated - REAL, DIMENSION( :,: ), & - INTENT(IN) :: pattern_spp_sfc + REAL(kind=kind_phys), DIMENSION( :,: ), & + INTENT(IN) :: pattern_spp_sfc !=================================== ! 2D VARIABLES !=================================== - REAL, DIMENSION( ims:ime ) , & - INTENT(IN ) :: MAVAIL, & + REAL(kind=kind_phys), DIMENSION( ims:ime ) , & + INTENT(IN ) :: MAVAIL, & PBLH, & XLAND, & PSFCPA, & DX - REAL, DIMENSION( ims:ime ) , & - INTENT(OUT ) :: U10,V10, & + REAL(kind=kind_phys), DIMENSION( ims:ime ) , & + INTENT(OUT ) :: U10,V10, & TH2,T2,Q2 - REAL, DIMENSION( ims:ime ) , & - INTENT(INOUT) :: HFLX,HFX, & + REAL(kind=kind_phys), DIMENSION( ims:ime ) , & + INTENT(INOUT) :: HFLX,HFX, & QFLX,QFX, & LH, & MOL,RMOL, & @@ -333,12 +338,12 @@ SUBROUTINE SFCLAY_mynn( & LOGICAL, DIMENSION( ims:ime ), INTENT(IN) :: & & wet, dry, icy, flag_iter - REAL, DIMENSION( ims:ime ), INTENT(IN) :: & + REAL(kind=kind_phys), DIMENSION( ims:ime ), INTENT(IN) :: & & tskin_wat, tskin_lnd, tskin_ice, & & tsurf_wat, tsurf_lnd, tsurf_ice, & & snowh_wat, snowh_lnd, snowh_ice - REAL, DIMENSION( ims:ime), INTENT(INOUT) :: & + REAL(kind=kind_phys), DIMENSION( ims:ime), INTENT(INOUT) :: & & ZNT_wat, ZNT_lnd, ZNT_ice, & & UST_wat, UST_lnd, UST_ice, & & cm_wat, cm_lnd, cm_ice, & @@ -359,12 +364,12 @@ SUBROUTINE SFCLAY_mynn( & !ADDITIONAL OUTPUT !JOE-begin - REAL, DIMENSION( ims:ime ) :: qstar + REAL(kind=kind_phys), DIMENSION( ims:ime ) :: qstar !JOE-end !=================================== ! 1D LOCAL ARRAYS !=================================== - REAL, DIMENSION( its:ite ) :: U1D,V1D, & !level1 winds + REAL(kind=kind_phys), DIMENSION( its:ite ) :: U1D,V1D, & !level1 winds U1D2,V1D2, & !level2 winds QV1D, & P1D, & @@ -372,18 +377,22 @@ SUBROUTINE SFCLAY_mynn( & dz8w1d, & !level 1 height dz2w1d !level 2 height - REAL, DIMENSION( its:ite ) :: rstoch1D + REAL(kind=kind_phys), DIMENSION( its:ite ) :: rstoch1D INTEGER :: I,J,K,itf,ktf !----------------------------------------------------------- + ! Initialize error-handling + errflg = 0 + errmsg = '' + IF (debug_code >= 1) THEN write(*,*)"======= printing of constants:" - write(*,*)"cp=", cp," g=", g - write(*,*)"Rd=", r_d," Rv=", r_v, " cpc=", cpv - write(*,*)"cliq=", cliq," cice=", Cice," rcp=", rcp - write(*,*)"xlv=", XLV," xlf=", XLF - write(*,*)"ep1=", EP_1, " ep2=", EP_2 + write(*,*)"cp=", cp," g=", g + write(*,*)"Rd=", r_d," Rv=", r_v, " cpc=", cpv + write(*,*)"cliq=", cliq," cice=", Cice," rcp=", rcp + write(*,*)"xlv=", XLV," xlf=", XLF + write(*,*)"ep1=", EP_1, " ep2=", EP_2 ENDIF itf=ite !MIN0(ite,ide-1) @@ -412,9 +421,9 @@ SUBROUTINE SFCLAY_mynn( & IF (itimestep==1 .AND. iter==1) THEN DO i=its,ite !Everything here is used before calculated - UST_WAT(i)=MAX(0.04*SQRT(U1D(i)*U1D(i) + V1D(i)*V1D(i)),0.001) - UST_LND(i)=MAX(0.04*SQRT(U1D(i)*U1D(i) + V1D(i)*V1D(i)),0.001) - UST_ICE(i)=MAX(0.04*SQRT(U1D(i)*U1D(i) + V1D(i)*V1D(i)),0.001) + UST_WAT(i)=MAX(0.04*SQRT(U1D(i)*U1D(i) + V1D(i)*V1D(i)),0.001_kind_phys) + UST_LND(i)=MAX(0.04*SQRT(U1D(i)*U1D(i) + V1D(i)*V1D(i)),0.001_kind_phys) + UST_ICE(i)=MAX(0.04*SQRT(U1D(i)*U1D(i) + V1D(i)*V1D(i)),0.001_kind_phys) MOL(i)=0.0 QFLX(i)=0. HFLX(i)=0. @@ -531,11 +540,11 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & its,ite, jts,jte, kts,kte, & J, itimestep, iter, lsm, lsm_ruc - REAL, PARAMETER :: XKA=2.4E-5 !molecular diffusivity - REAL, PARAMETER :: PRT=1. !prandlt number - REAL, PARAMETER :: snowh_thresh = 50. !mm - REAL, INTENT(IN) :: SVP1,SVP2,SVP3,SVPT0,EP1,EP2 - REAL, INTENT(IN) :: KARMAN,CP,G,ROVCP,R,XLV !,DX + REAL(kind=kind_phys), PARAMETER :: XKA=2.4E-5 !molecular diffusivity + REAL(kind=kind_phys), PARAMETER :: PRT=1. !prandlt number + REAL(kind=kind_phys), PARAMETER :: snowh_thresh = 50. !mm + REAL(kind=kind_phys), INTENT(IN) :: SVP1,SVP2,SVP3,SVPT0,EP1,EP2 + REAL(kind=kind_phys), INTENT(IN) :: KARMAN,CP,G,ROVCP,R,XLV !,DX !----------------------------- ! NAMELIST OPTIONS @@ -550,28 +559,32 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !Input data integer, dimension(ims:ime), intent(in) :: vegtype - real, dimension(ims:ime), intent(in) :: & + real(kind=kind_phys), dimension(ims:ime), intent(in) :: & & sigmaf,shdmax,z0pert,ztpert !----------------------------- ! 1D ARRAYS !----------------------------- - REAL, DIMENSION( ims:ime ), INTENT(IN) :: MAVAIL, & + REAL(kind=kind_phys), DIMENSION( ims:ime ), & + INTENT(IN) :: MAVAIL, & PBLH, & XLAND, & PSFCPA, & DX - REAL, DIMENSION( its:ite ), INTENT(IN) :: U1D,V1D, & + REAL(kind=kind_phys), DIMENSION( its:ite ), & + INTENT(IN) :: U1D,V1D, & U1D2,V1D2, & QV1D,P1D, & T1D, & dz8w1d, & dz2w1d - REAL, DIMENSION( ims:ime ), INTENT(OUT) :: QFX,HFX, & + REAL(kind=kind_phys), DIMENSION( ims:ime ), & + INTENT(OUT) :: QFX,HFX, & RMOL - REAL, DIMENSION( ims:ime ), INTENT(INOUT) :: HFLX,QFLX, & + REAL(kind=kind_phys), DIMENSION( ims:ime ), & + INTENT(INOUT) :: HFLX,QFLX, & LH,MOL, & QGH,QSFC, & ZNT, & @@ -589,12 +602,12 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & LOGICAL, DIMENSION( ims:ime ), INTENT(IN) :: & & wet, dry, icy, flag_iter - REAL, DIMENSION( ims:ime ), INTENT(in) :: & + REAL(kind=kind_phys), DIMENSION( ims:ime ), INTENT(in) :: & & tskin_wat, tskin_lnd, tskin_ice, & & tsurf_wat, tsurf_lnd, tsurf_ice, & & snowh_wat, snowh_lnd, snowh_ice - REAL, DIMENSION( ims:ime ), INTENT(inout) :: & + REAL(kind=kind_phys), DIMENSION( ims:ime ), INTENT(inout) :: & & ZNT_wat, ZNT_lnd, ZNT_ice, & & UST_wat, UST_lnd, UST_ice, & & cm_wat, cm_lnd, cm_ice, & @@ -609,15 +622,20 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & & QFLX_wat, QFLX_lnd, QFLX_ice, & & qsfc_wat, qsfc_lnd, qsfc_ice - REAL, DIMENSION( its:ite ), INTENT(IN) :: rstoch1D + REAL(kind=kind_phys), DIMENSION( its:ite ), & + & INTENT(IN) :: rstoch1D ! DIAGNOSTIC OUTPUT - REAL, DIMENSION( ims:ime ), INTENT(OUT) :: U10,V10, & - TH2,T2,Q2 + REAL(kind=kind_phys), DIMENSION( ims:ime ), & + & INTENT(OUT) :: U10, V10, & + & TH2, T2, & + & Q2 !-------------------------------------------- !JOE-additinal output - REAL, DIMENSION( ims:ime ), INTENT(OUT) :: wstar,qstar + REAL(kind=kind_phys), DIMENSION( ims:ime ), & + & INTENT(OUT) :: wstar, & + & qstar !JOE-end ! CCPP error handling @@ -627,7 +645,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !---------------------------------------------------------------- ! LOCAL VARS !---------------------------------------------------------------- - REAL, DIMENSION(its:ite) :: & + REAL(kind=kind_phys), DIMENSION(its:ite) :: & ZA, & !Height of lowest 1/2 sigma level(m) ZA2, & !Height of 2nd lowest 1/2 sigma level(m) THV1D, & !Theta-v at lowest 1/2 sigma (K) @@ -663,13 +681,16 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & INTEGER :: N,I,K,L,yesno - REAL :: PL,E1,TABS - REAL :: WSPD_lnd, WSPD_ice, WSPD_wat - REAL :: DTHVDZ,DTHVM,VCONV,ZOL2,ZOL10,ZOLZA,ZOLZ0,ZOLZT - REAL :: DTG,DTTHX,PSIQ,PSIQ2,PSIQ10,PSIT10 - REAL :: FLUXC,VSGD - REAL :: restar,VISC,DQG,OLDUST,OLDTST + REAL(kind=kind_phys) :: PL,E1,TABS + REAL(kind=kind_phys) :: WSPD_lnd, WSPD_ice, WSPD_wat + REAL(kind=kind_phys) :: DTHVDZ,DTHVM,VCONV,ZOL2,ZOL10,ZOLZA,ZOLZ0,ZOLZT + REAL(kind=kind_phys) :: DTG,DTTHX,PSIQ,PSIQ2,PSIQ10,PSIT10 + REAL(kind=kind_phys) :: FLUXC,VSGD + REAL(kind=kind_phys) :: restar,VISC,DQG,OLDUST,OLDTST + ! Initialize error-handling + errflg = 0 + errmsg = '' !------------------------------------------------------------------- DO I=its,ite @@ -690,14 +711,14 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) E1=SVP1*EXP(SVP2*(TSK_wat(I)-SVPT0)/(TSK_wat(i)-SVP3)) ENDIF - QSFC_wat(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity - QSFCMR_wat(I)=EP2*E1/(PSFC(I)-E1) !mixing ratio + QSFC_wat(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity + QSFCMR_wat(I)=EP2*E1/(PSFC(I)-E1) !mixing ratio IF(QSFC_wat(I)>1..or.QSFC_wat(I)<0.) print *,' QSFC_wat(I)',itimestep,i,QSFC_wat(I),TSK_wat(i) ENDIF IF (dry(i)) THEN TSK_lnd(I) = tskin_lnd(i) if( lsm == lsm_ruc) then - QSFCMR_lnd(I)=QSFC_lnd(I)/(1.-QSFC_lnd(I)) !mixing ratio + QSFCMR_lnd(I)=QSFC_lnd(I)/(1.-QSFC_lnd(I)) !mixing ratio else TABS = 0.5*(TSK_lnd(I) + T1D(I)) IF (TABS .LT. 273.15) THEN @@ -717,7 +738,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & IF (icy(i)) THEN TSK_ice(I) = tskin_ice(i) if( lsm == lsm_ruc) then - QSFCMR_ice(I)=QSFC_ice(I)/(1.-QSFC_ice(I)) !mixing ratio + QSFCMR_ice(I)=QSFC_ice(I)/(1.-QSFC_ice(I)) !mixing ratio else IF (TSK_ice(I) .LT. 273.15) THEN !SATURATION VAPOR PRESSURE WRT ICE (SVP1=.6112; 10*mb) @@ -746,7 +767,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) E1=SVP1*EXP(SVP2*(TSK_wat(I)-SVPT0)/(TSK_wat(i)-SVP3)) ENDIF - QSFC_wat(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity + QSFC_wat(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity ENDIF IF (dry(i).and.(QSFC_lnd(I)>1..or.QSFC_lnd(I)<0.)) then !print *,'bad QSFC_lnd(I)',itimestep,iter,i,QSFC_lnd(I),TSKin_lnd(I) @@ -818,7 +839,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & if(dry(i)) then TSK_lnd(I) = tskin_lnd(i) !TSK_lnd(I) = 0.5 * (tsurf_lnd(i)+tskin_lnd(i)) - ! CONVERT SKIN TEMPERATURES TO POTENTIAL TEMPERATURE: + ! CONVERT SKIN TEMPERATURES TO POTENTIAL TEMPERATURE: THSK_lnd(I) = TSK_lnd(I)*THCON(I) !(K) THVSK_lnd(I) = THSK_lnd(I)*(1.+EP1*qsfc_lnd(I)) if(THVSK_lnd(I) < 170. .or. THVSK_lnd(I) > 360.) & @@ -827,7 +848,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & if(icy(i)) then TSK_ice(I) = tskin_ice(i) !TSK_ice(I) = 0.5 * (tsurf_ice(i)+tskin_ice(i)) - ! CONVERT SKIN TEMPERATURES TO POTENTIAL TEMPERATURE: + ! CONVERT SKIN TEMPERATURES TO POTENTIAL TEMPERATURE: THSK_ice(I) = TSK_ice(I)*THCON(I) !(K) THVSK_ice(I) = THSK_ice(I)*(1.+EP1*qsfc_ice(I)) !(K) if(THVSK_ice(I) < 170. .or. THVSK_ice(I) > 360.) & @@ -836,7 +857,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & if(wet(i)) then TSK_wat(I) = tskin_wat(i) !TSK_wat(I) = 0.5 * (tsurf_wat(i)+tskin_wat(i)) - ! CONVERT SKIN TEMPERATURES TO POTENTIAL TEMPERATURE: + ! CONVERT SKIN TEMPERATURES TO POTENTIAL TEMPERATURE: THSK_wat(I) = TSK_wat(I)*THCON(I) !(K) THVSK_wat(I) = THSK_wat(I)*(1.+EP1*QVSH(I)) !(K) if(THVSK_wat(I) < 170. .or. THVSK_wat(I) > 360.) & @@ -846,7 +867,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ENDDO DO I=its,ite - ! CONVERT LOWEST LAYER TEMPERATURE TO POTENTIAL TEMPERATURE: + ! CONVERT LOWEST LAYER TEMPERATURE TO POTENTIAL TEMPERATURE: TH1D(I)=T1D(I)*(100000./P1D(I))**ROVCP !(Theta, K) TC1D(I)=T1D(I)-273.15 !(T, Celsius) ENDDO @@ -859,7 +880,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & DO I=its,ite RHO1D(I)=P1D(I)/(R*TV1D(I)) !now using value calculated in sfc driver - ZA(I)=0.5*dz8w1d(I) !height of first half-sigma level + ZA(I)=0.5*dz8w1d(I) !height of first half-sigma level ZA2(I)=dz8w1d(I) + 0.5*dz2w1d(I) !height of 2nd half-sigma level GOVRTH(I)=G/TH1D(I) ENDDO @@ -932,35 +953,35 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & IF (wet(i)) THEN DTHVDZ=(THV1D(I)-THVSK_wat(I)) !-------------------------------------------------------- - ! Calculate the convective velocity scale (WSTAR) and - ! subgrid-scale velocity (VSGD) following Beljaars (1995, QJRMS) + ! Calculate the convective velocity scale (WSTAR) and + ! subgrid-scale velocity (VSGD) following Beljaars (1995, QJRMS) ! and Mahrt and Sun (1995, MWR), respectively !------------------------------------------------------- !tgs - the line below could be used when hflx_wat,qflx_wat are moved from ! Interstitial to Sfcprop !fluxc = max(hflx_wat(i) + ep1*THVSK_wat(I)*qflx_wat(i),0.) fluxc = max(hfx(i)/RHO1D(i)/cp & - & + ep1*THVSK_wat(I)*qfx(i)/RHO1D(i),0.) + & + ep1*THVSK_wat(I)*qfx(i)/RHO1D(i),0._kind_phys) !WSTAR(I) = vconvc*(g/TSK(i)*pblh(i)*fluxc)**onethird WSTAR(I) = vconvc*(g/TSK_wat(i)*pblh(i)*fluxc)**onethird !-------------------------------------------------------- ! Mahrt and Sun low-res correction - modified for water points (halved) ! (for 13 km ~ 0.18 m/s; for 3 km == 0 m/s) !-------------------------------------------------------- - VSGD = MIN( 0.25 * (max(dx(i)/5000.-1.,0.))**onethird , 0.5) + VSGD = MIN( 0.25 * (max(dx(i)/5000.-1.,0._kind_phys))**onethird , 0.5_kind_phys) WSPD_wat=SQRT(WSPD(I)*WSPD(I)+WSTAR(I)*WSTAR(I)+vsgd*vsgd) WSPD_wat=MAX(WSPD_wat,wmin) !-------------------------------------------------------- - ! CALCULATE THE BULK RICHARDSON NUMBER OF SURFACE LAYER, - ! ACCORDING TO AKB(1976), EQ(12). + ! CALCULATE THE BULK RICHARDSON NUMBER OF SURFACE LAYER, + ! ACCORDING TO AKB(1976), EQ(12). !-------------------------------------------------------- rb_wat(I)=GOVRTH(I)*ZA(I)*DTHVDZ/(WSPD_wat*WSPD_wat) IF (ITIMESTEP == 1) THEN - rb_wat(I)=MAX(rb_wat(I),-2.0) - rb_wat(I)=MIN(rb_wat(I), 2.0) + rb_wat(I)=MAX(rb_wat(I),-2.0_kind_phys) + rb_wat(I)=MIN(rb_wat(I), 2.0_kind_phys) ELSE - rb_wat(I)=MAX(rb_wat(I),-4.0) - rb_wat(I)=MIN(rb_wat(I), 4.0) + rb_wat(I)=MAX(rb_wat(I),-4.0_kind_phys) + rb_wat(I)=MIN(rb_wat(I), 4.0_kind_phys) ENDIF ENDIF ! end water point @@ -975,16 +996,16 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! Interstitial to Sfcprop !fluxc = max(hflx_lnd(i) + ep1*THVSK_lnd(I)*qflx_lnd(i),0.) fluxc = max(hfx(i)/RHO1D(i)/cp & - & + ep1*THVSK_lnd(I)*qfx(i)/RHO1D(i),0.) + & + ep1*THVSK_lnd(I)*qfx(i)/RHO1D(i),0._kind_phys) ! WSTAR(I) = vconvc*(g/TSK(i)*pblh(i)*fluxc)**onethird ! increase height scale, assuming that the non-local transoport ! from the mass-flux (plume) mixing exceedsd the PBLH. - WSTAR(I) = vconvc*(g/TSK_lnd(i)*MIN(1.5*pblh(i),4000.)*fluxc)**onethird + WSTAR(I) = vconvc*(g/TSK_lnd(i)*MIN(1.5*pblh(i),4000._kind_phys)*fluxc)**onethird !-------------------------------------------------------- ! Mahrt and Sun low-res correction ! (for 13 km ~ 0.37 m/s; for 3 km == 0 m/s) !-------------------------------------------------------- - VSGD = MIN( 0.32 * (max(dx(i)/5000.-1.,0.))**onethird , 0.5) + VSGD = MIN( 0.32 * (max(dx(i)/5000.-1.,0._kind_phys))**onethird , 0.5_kind_phys) WSPD_lnd=SQRT(WSPD(I)*WSPD(I)+WSTAR(I)*WSTAR(I)+vsgd*vsgd) WSPD_lnd=MAX(WSPD_lnd,wmin) !-------------------------------------------------------- @@ -999,11 +1020,11 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! ust_lnd(i)=WSPD_lnd*0.1*(1.0 - 10.0*rb_lnd(I))**onethird !ENDIF IF (ITIMESTEP == 1) THEN - rb_lnd(I)=MAX(rb_lnd(I),-2.0) - rb_lnd(I)=MIN(rb_lnd(I), 2.0) + rb_lnd(I)=MAX(rb_lnd(I),-2.0_kind_phys) + rb_lnd(I)=MIN(rb_lnd(I), 2.0_kind_phys) ELSE - rb_lnd(I)=MAX(rb_lnd(I),-4.0) - rb_lnd(I)=MIN(rb_lnd(I), 4.0) + rb_lnd(I)=MAX(rb_lnd(I),-4.0_kind_phys) + rb_lnd(I)=MIN(rb_lnd(I), 4.0_kind_phys) ENDIF ENDIF ! end land point @@ -1018,16 +1039,16 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! Interstitial to Sfcprop !fluxc = max(hflx_ice(i) + ep1*THVSK_ice(I)*qflx_ice(i)/RHO1D(i),0.) fluxc = max(hfx(i)/RHO1D(i)/cp & - & + ep1*THVSK_ice(I)*qfx(i)/RHO1D(i),0.) + & + ep1*THVSK_ice(I)*qfx(i)/RHO1D(i),0._kind_phys) ! WSTAR(I) = vconvc*(g/TSK(i)*pblh(i)*fluxc)**onethird ! increase height scale, assuming that the non-local transport ! from the mass-flux (plume) mixing exceedsd the PBLH. - WSTAR(I) = vconvc*(g/TSK_ice(i)*MIN(1.5*pblh(i),4000.)*fluxc)**onethird + WSTAR(I) = vconvc*(g/TSK_ice(i)*MIN(1.5*pblh(i),4000._kind_phys)*fluxc)**onethird !-------------------------------------------------------- ! Mahrt and Sun low-res correction ! (for 13 km ~ 0.37 m/s; for 3 km == 0 m/s) !-------------------------------------------------------- - VSGD = MIN( 0.32 * (max(dx(i)/5000.-1.,0.))**onethird , 0.5) + VSGD = MIN( 0.32 * (max(dx(i)/5000.-1.,0._kind_phys))**onethird , 0.5_kind_phys) WSPD_ice=SQRT(WSPD(I)*WSPD(I)+WSTAR(I)*WSTAR(I)+vsgd*vsgd) WSPD_ice=MAX(WSPD_ice,wmin) !-------------------------------------------------------- @@ -1036,11 +1057,11 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !-------------------------------------------------------- rb_ice(I)=GOVRTH(I)*ZA(I)*DTHVDZ/(WSPD_ice*WSPD_ice) IF (ITIMESTEP == 1) THEN - rb_ice(I)=MAX(rb_ice(I),-2.0) - rb_ice(I)=MIN(rb_ice(I), 2.0) + rb_ice(I)=MAX(rb_ice(I),-2.0_kind_phys) + rb_ice(I)=MIN(rb_ice(I), 2.0_kind_phys) ELSE - rb_ice(I)=MAX(rb_ice(I),-4.0) - rb_ice(I)=MIN(rb_ice(I), 4.0) + rb_ice(I)=MAX(rb_ice(I),-4.0_kind_phys) + rb_ice(I)=MIN(rb_ice(I), 4.0_kind_phys) ENDIF ENDIF ! end ice point @@ -1061,15 +1082,15 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !if (itimestep .GT. 1) THEN ! IF(MOL(I).LT.0.)BR(I)=MIN(BR(I),0.0) !ENDIF - + endif ! flag_iter ENDDO 1006 format(A,F7.3,A,f9.4,A,f9.5,A,f9.4) 1007 format(A,F2.0,A,f6.2,A,f7.3,A,f7.2) -!-------------------------------------------------------------------- -!-------------------------------------------------------------------- +!-------------------------------------------------------------------- +!-------------------------------------------------------------------- !--- BEGIN I-LOOP !-------------------------------------------------------------------- !-------------------------------------------------------------------- @@ -1124,7 +1145,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! add stochastic perturbation of ZNT if (spp_sfc==1) then - ZNTstoch_wat(I) = MAX(ZNT_wat(I) + ZNT_wat(I)*1.0*rstoch1D(i), 1e-6) + ZNTstoch_wat(I) = MAX(ZNT_wat(I) + ZNT_wat(I)*1.0*rstoch1D(i), 1e-6_kind_phys) else ZNTstoch_wat(I) = ZNT_wat(I) endif @@ -1138,7 +1159,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! AHW: Garrattt formula: Calculate roughness Reynolds number ! Kinematic viscosity of air (linear approx to ! temp dependence at sea level) - restar=MAX(ust_wat(i)*ZNTstoch_wat(i)/visc, 0.1) + restar=MAX(ust_wat(i)*ZNTstoch_wat(i)/visc, 0.1_kind_phys) !-------------------------------------- !CALCULATE z_t and z_q @@ -1167,7 +1188,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & rstoch1D(i),spp_sfc) ENDIF ELSEIF ( ISFTCFLX .EQ. 2 ) THEN - CALL garratt_1992(ZT_wat(i),ZQ_wat(i),ZNTstoch_wat(i),restar,2.0) + CALL garratt_1992(ZT_wat(i),ZQ_wat(i),ZNTstoch_wat(i),restar,2.0_kind_phys) ELSEIF ( ISFTCFLX .EQ. 3 ) THEN IF (COARE_OPT .EQ. 3.0) THEN CALL fairall_etal_2003(ZT_wat(i),ZQ_wat(i),restar,UST_wat(i),visc,& @@ -1178,7 +1199,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ENDIF ELSEIF ( ISFTCFLX .EQ. 4 ) THEN !GFS zt formulation - CALL GFS_zt_wat(ZT_wat(i),ZNTstoch_wat(i),restar,WSPD(i),ZA(i),sfc_z0_type) + CALL GFS_zt_wat(ZT_wat(i),ZNTstoch_wat(i),restar,WSPD(i),ZA(i),sfc_z0_type,errmsg,errflg) ZQ_wat(i)=ZT_wat(i) ENDIF ELSE @@ -1202,7 +1223,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & GZ2OZt_wat(I)= LOG((2.0+ZNTstoch_wat(i))/ZT_wat(i)) GZ10OZ0_wat(I)=LOG((10.+ZNTstoch_wat(I))/ZNTstoch_wat(I)) GZ10OZt_wat(I)=LOG((10.+ZNTstoch_wat(i))/ZT_wat(i)) - zratio_wat(i)=ZNTstoch_wat(I)/ZT_wat(I) !need estimate for Li et al. + zratio_wat(i)=ZNTstoch_wat(I)/ZT_wat(I) !need estimate for Li et al. ENDIF !end water point @@ -1214,7 +1235,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! add stochastic perturbaction of ZNT if (spp_sfc==1) then - ZNTstoch_lnd(I) = MAX(ZNT_lnd(I) + ZNT_lnd(I)*1.0*rstoch1D(i), 1e-6) + ZNTstoch_lnd(I) = MAX(ZNT_lnd(I) + ZNT_lnd(I)*1.0*rstoch1D(i), 1e-6_kind_phys) else ZNTstoch_lnd(I) = ZNT_lnd(I) endif @@ -1223,7 +1244,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! LAND !-------------------------------------- !COMPUTE ROUGHNESS REYNOLDS NUMBER (restar) USING DEFAULT ZNT - restar=MAX(ust_lnd(i)*ZNTstoch_lnd(i)/visc, 0.1) + restar=MAX(ust_lnd(i)*ZNTstoch_lnd(i)/visc, 0.1_kind_phys) !-------------------------------------- !GET z_t and z_q @@ -1234,7 +1255,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & IF ( PRESENT(IZ0TLND) ) THEN IF ( IZ0TLND .LE. 1 ) THEN CALL zilitinkevich_1995(ZNTstoch_lnd(i),ZT_lnd(i),ZQ_lnd(i),restar,& - UST_lnd(I),KARMAN,1.0,IZ0TLND,spp_sfc,rstoch1D(i)) + UST_lnd(I),KARMAN,1.0_kind_phys,IZ0TLND,spp_sfc,rstoch1D(i)) ELSEIF ( IZ0TLND .EQ. 2 ) THEN ! DH note - at this point, qstar is either not initialized ! or initialized to zero, but certainly not set correctly @@ -1245,7 +1266,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & qstar(I),restar,visc) ELSEIF ( IZ0TLND .EQ. 3 ) THEN !Original MYNN in WRF-ARW used this form: - CALL garratt_1992(ZT_lnd(i),ZQ_lnd(i),ZNTSTOCH_lnd(i),restar,1.0) + CALL garratt_1992(ZT_lnd(i),ZQ_lnd(i),ZNTSTOCH_lnd(i),restar,1.0_kind_phys) ELSEIF ( IZ0TLND .EQ. 4 ) THEN !GFS: CALL GFS_zt_lnd(ZT_lnd(i),ZNTSTOCH_lnd(i),sigmaf(i),ztpert(i),UST_lnd(i)) @@ -1254,12 +1275,12 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ELSE !DEFAULT TO ZILITINKEVICH CALL zilitinkevich_1995(ZNTSTOCH_lnd(i),ZT_lnd(i),ZQ_lnd(i),restar,& - UST_lnd(I),KARMAN,1.0,0,spp_sfc,rstoch1D(i)) + UST_lnd(I),KARMAN,1.0_kind_phys,0,spp_sfc,rstoch1D(i)) ENDIF ENDIF - IF (ZNTstoch_lnd(i) < 1E-8 .OR. Zt_lnd(i) < 1E-10) THEN + IF (ZNTstoch_lnd(i) < 1E-8 .OR. Zt_lnd(i) < 1E-10) THEN write(0,*)"===(land) capture bad input in mynn sfc layer, i=:",i - write(0,*)" ZNT=", ZNTstoch_lnd(i)," ZT=",Zt_lnd(i) + write(0,*)" ZNT=", ZNTstoch_lnd(i)," ZT=",Zt_lnd(i) write(0,*)" tsk=", tskin_lnd(i)," restar=",restar,& " tsurf=", tsurf_lnd(i)," qsfc=", qsfc_lnd(i)," znt=", znt_lnd(i),& " ust=", ust_lnd(i)," snowh=", snowh_lnd(i),"psfcpa=",PSFCPA(i), & @@ -1281,7 +1302,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! add stochastic perturbaction of ZNT if (spp_sfc==1) then - ZNTstoch_ice(I) = MAX(ZNT_ice(I) + ZNT_ice(I)*1.0*rstoch1D(i), 1e-6) + ZNTstoch_ice(I) = MAX(ZNT_ice(I) + ZNT_ice(I)*1.0*rstoch1D(i), 1e-6_kind_phys) else ZNTstoch_ice(I) = ZNT_ice(I) endif @@ -1290,7 +1311,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! ICE !-------------------------------------- !COMPUTE ROUGHNESS REYNOLDS NUMBER (restar) USING DEFAULT ZNT - restar=MAX(ust_ice(i)*ZNTstoch_ice(i)/visc, 0.1) + restar=MAX(ust_ice(i)*ZNTstoch_ice(i)/visc, 0.1_kind_phys) !-------------------------------------- !GET z_t and z_q !-------------------------------------- @@ -1327,8 +1348,8 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !COMPUTE z/L first guess: CALL Li_etal_2010(ZOL(I),rb_wat(I),ZA(I)/ZNTstoch_wat(I),zratio_wat(I)) !ZOL(I)=ZA(I)*KARMAN*G*MOL(I)/(TH1D(I)*MAX(UST_wat(I)*UST_wat(I),0.0001)) - ZOL(I)=MAX(ZOL(I),0.0) - ZOL(I)=MIN(ZOL(I),20.) + ZOL(I)=MAX(ZOL(I),0.0_kind_phys) + ZOL(I)=MIN(ZOL(I),20._kind_phys) IF (debug_code >= 1) THEN IF (ZNTstoch_wat(i) < 1E-8 .OR. Zt_wat(i) < 1E-10) THEN @@ -1345,14 +1366,14 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !zol(I)=zolri(rb_wat(I),ZA(I),ZNTstoch_wat(I),ZT_wat(I),ZOL(I),psi_opt) !Use brute-force method zol(I)=zolrib(rb_wat(I),ZA(I),ZNTstoch_wat(I),zt_wat(I),GZ1OZ0_wat(I),GZ1OZt_wat(I),ZOL(I),psi_opt) - ZOL(I)=MAX(ZOL(I),0.0) - ZOL(I)=MIN(ZOL(I),20.) + ZOL(I)=MAX(ZOL(I),0.0_kind_phys) + ZOL(I)=MIN(ZOL(I),20._kind_phys) zolzt = zol(I)*zt_wat(I)/ZA(I) ! zt/L zolz0 = zol(I)*ZNTstoch_wat(I)/ZA(I) ! z0/L zolza = zol(I)*(za(I)+ZNTstoch_wat(I))/za(I) ! (z+z0/L zol10 = zol(I)*(10.+ZNTstoch_wat(I))/za(I) ! (10+z0)/L - zol2 = zol(I)*(2.+ZNTstoch_wat(I))/za(I) ! (2+z0)/L + zol2 = zol(I)*(2.+ZNTstoch_wat(I))/za(I) ! (2+z0)/L !COMPUTE PSIM and PSIH !CALL PSI_Suselj_Sood_2010(PSIM(I),PSIH(I),ZOL(I)) @@ -1370,9 +1391,9 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! 1.0 over Monin-Obukhov length RMOL(I)= ZOL(I)/ZA(I) - ELSEIF(rb_wat(I) .EQ. 0.) THEN - !========================================================= - !-----CLASS 3; FORCED CONVECTION/NEUTRAL: + ELSEIF(rb_wat(I) .EQ. 0.) THEN + !========================================================= + !-----CLASS 3; FORCED CONVECTION/NEUTRAL: !========================================================= PSIM(I)=0.0 @@ -1386,14 +1407,14 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ELSEIF(rb_wat(I) .LT. 0.)THEN !========================================================== - !-----CLASS 4; FREE CONVECTION: + !-----CLASS 4; FREE CONVECTION: !========================================================== !COMPUTE z/L first guess: CALL Li_etal_2010(ZOL(I),rb_wat(I),ZA(I)/ZNTstoch_wat(I),zratio_wat(I)) !ZOL(I)=ZA(I)*KARMAN*G*MOL(I)/(TH1D(I)*MAX(UST_wat(I)*UST_wat(I),0.001)) - ZOL(I)=MAX(ZOL(I),-20.0) - ZOL(I)=MIN(ZOL(I),0.0) + ZOL(I)=MAX(ZOL(I),-20.0_kind_phys) + ZOL(I)=MIN(ZOL(I),0.0_kind_phys) IF (debug_code >= 1) THEN IF (ZNTstoch_wat(i) < 1E-8 .OR. Zt_wat(i) < 1E-10) THEN @@ -1410,8 +1431,8 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !zol(I)=zolri(rb_wat(I),ZA(I),ZNTstoch_wat(I),ZT_wat(I),ZOL(I),psi_opt) !Use brute-force method zol(I)=zolrib(rb_wat(I),ZA(I),ZNTstoch_wat(I),zt_wat(I),GZ1OZ0_wat(I),GZ1OZt_wat(I),ZOL(I),psi_opt) - ZOL(I)=MAX(ZOL(I),-20.0) - ZOL(I)=MIN(ZOL(I),0.0) + ZOL(I)=MAX(ZOL(I),-20.0_kind_phys) + ZOL(I)=MIN(ZOL(I),0.0_kind_phys) zolzt = zol(I)*zt_wat(I)/ZA(I) ! zt/L zolz0 = zol(I)*ZNTstoch_wat(I)/ZA(I) ! z0/L @@ -1440,17 +1461,17 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & PSIM10(I)=MIN(PSIM10(I),0.9*GZ10OZ0_wat(I)) PSIH10(I)=MIN(PSIH10(I),0.9*GZ10OZt_wat(I)) - RMOL(I) = ZOL(I)/ZA(I) + RMOL(I) = ZOL(I)/ZA(I) ENDIF ! CALCULATE THE RESISTANCE: - PSIX_wat(I) =MAX(GZ1OZ0_wat(I)-PSIM(I) , 1.0) ! = fm - PSIX10_wat(I)=MAX(GZ10OZ0_wat(I)-PSIM10(I), 1.0) ! = fm10 - PSIT_wat(I) =MAX(GZ1OZt_wat(I)-PSIH(I) , 1.0) ! = fh - PSIT2_wat(I) =MAX(GZ2OZt_wat(I)-PSIH2(I) , 1.0) ! = fh2 - PSIQ_wat(I) =MAX(LOG((ZA(I)+ZQ_wat(i))/ZQ_wat(I))-PSIH(I) ,1.0) - PSIQ2_wat(I) =MAX(LOG((2.0+ZQ_wat(i))/ZQ_wat(I))-PSIH2(I) ,1.0) + PSIX_wat(I) =MAX(GZ1OZ0_wat(I)-PSIM(I) , 1.0_kind_phys) ! = fm + PSIX10_wat(I)=MAX(GZ10OZ0_wat(I)-PSIM10(I), 1.0_kind_phys) ! = fm10 + PSIT_wat(I) =MAX(GZ1OZt_wat(I)-PSIH(I) , 1.0_kind_phys) ! = fh + PSIT2_wat(I) =MAX(GZ2OZt_wat(I)-PSIH2(I) , 1.0_kind_phys) ! = fh2 + PSIQ_wat(I) =MAX(LOG((ZA(I)+ZQ_wat(i))/ZQ_wat(I))-PSIH(I) ,1.0_kind_phys) + PSIQ2_wat(I) =MAX(LOG((2.0+ZQ_wat(i))/ZQ_wat(I))-PSIH2(I) ,1.0_kind_phys) ENDIF ! end water points @@ -1460,8 +1481,8 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !COMPUTE z/L first guess: CALL Li_etal_2010(ZOL(I),rb_lnd(I),ZA(I)/ZNTstoch_lnd(I),zratio_lnd(I)) !ZOL(I)=ZA(I)*KARMAN*G*MOL(I)/(TH1D(I)*MAX(UST_lnd(I)*UST_lnd(I),0.0001)) - ZOL(I)=MAX(ZOL(I),0.0) - ZOL(I)=MIN(ZOL(I),20.) + ZOL(I)=MAX(ZOL(I),0.0_kind_phys) + ZOL(I)=MIN(ZOL(I),20._kind_phys) IF (debug_code >= 1) THEN IF (ZNTstoch_lnd(i) < 1E-8 .OR. Zt_lnd(i) < 1E-10) THEN @@ -1478,14 +1499,14 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !zol(I)=zolri(rb_lnd(I),ZA(I),ZNTstoch_lnd(I),ZT_lnd(I),ZOL(I),psi_opt) !Use brute-force method zol(I)=zolrib(rb_lnd(I),ZA(I),ZNTstoch_lnd(I),zt_lnd(I),GZ1OZ0_lnd(I),GZ1OZt_lnd(I),ZOL(I),psi_opt) - ZOL(I)=MAX(ZOL(I),0.0) - ZOL(I)=MIN(ZOL(I),20.) + ZOL(I)=MAX(ZOL(I),0.0_kind_phys) + ZOL(I)=MIN(ZOL(I),20._kind_phys) zolzt = zol(I)*zt_lnd(I)/ZA(I) ! zt/L zolz0 = zol(I)*ZNTstoch_lnd(I)/ZA(I) ! z0/L zolza = zol(I)*(za(I)+ZNTstoch_lnd(I))/za(I) ! (z+z0/L zol10 = zol(I)*(10.+ZNTstoch_lnd(I))/za(I) ! (10+z0)/L - zol2 = zol(I)*(2.+ZNTstoch_lnd(I))/za(I) ! (2+z0)/L + zol2 = zol(I)*(2.+ZNTstoch_lnd(I))/za(I) ! (2+z0)/L !COMPUTE PSIM and PSIH !CALL PSI_Beljaars_Holtslag_1991(PSIM(I),PSIH(I),ZOL(I)) @@ -1502,9 +1523,9 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! 1.0 over Monin-Obukhov length RMOL(I)= ZOL(I)/ZA(I) - ELSEIF(rb_lnd(I) .EQ. 0.) THEN - !========================================================= - !-----CLASS 3; FORCED CONVECTION/NEUTRAL: + ELSEIF(rb_lnd(I) .EQ. 0.) THEN + !========================================================= + !-----CLASS 3; FORCED CONVECTION/NEUTRAL: !========================================================= PSIM(I)=0.0 @@ -1518,14 +1539,14 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ELSEIF(rb_lnd(I) .LT. 0.)THEN !========================================================== - !-----CLASS 4; FREE CONVECTION: + !-----CLASS 4; FREE CONVECTION: !========================================================== !COMPUTE z/L first guess: CALL Li_etal_2010(ZOL(I),rb_lnd(I),ZA(I)/ZNTstoch_lnd(I),zratio_lnd(I)) !ZOL(I)=ZA(I)*KARMAN*G*MOL(I)/(TH1D(I)*MAX(UST_lnd(I)*UST_lnd(I),0.001)) - ZOL(I)=MAX(ZOL(I),-20.0) - ZOL(I)=MIN(ZOL(I),0.0) + ZOL(I)=MAX(ZOL(I),-20.0_kind_phys) + ZOL(I)=MIN(ZOL(I),0.0_kind_phys) IF (debug_code >= 1) THEN IF (ZNTstoch_lnd(i) < 1E-8 .OR. Zt_lnd(i) < 1E-10) THEN @@ -1542,8 +1563,8 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !zol(I)=zolri(rb_lnd(I),ZA(I),ZNTstoch_lnd(I),ZT_lnd(I),ZOL(I),psi_opt) !Use brute-force method zol(I)=zolrib(rb_lnd(I),ZA(I),ZNTstoch_lnd(I),zt_lnd(I),GZ1OZ0_lnd(I),GZ1OZt_lnd(I),ZOL(I),psi_opt) - ZOL(I)=MAX(ZOL(I),-20.0) - ZOL(I)=MIN(ZOL(I),0.0) + ZOL(I)=MAX(ZOL(I),-20.0_kind_phys) + ZOL(I)=MIN(ZOL(I),0.0_kind_phys) zolzt = zol(I)*zt_lnd(I)/ZA(I) ! zt/L zolz0 = zol(I)*ZNTstoch_lnd(I)/ZA(I) ! z0/L @@ -1571,17 +1592,17 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & PSIM10(I)=MIN(PSIM10(I),0.9*GZ10OZ0_lnd(I)) PSIH10(I)=MIN(PSIH10(I),0.9*GZ10OZt_lnd(I)) - RMOL(I) = ZOL(I)/ZA(I) + RMOL(I) = ZOL(I)/ZA(I) ENDIF ! CALCULATE THE RESISTANCE: - PSIX_lnd(I) =MAX(GZ1OZ0_lnd(I)-PSIM(I), 1.0) - PSIX10_lnd(I)=MAX(GZ10OZ0_lnd(I)-PSIM10(I), 1.0) - PSIT_lnd(I) =MAX(GZ1OZt_lnd(I)-PSIH(I) , 1.0) - PSIT2_lnd(I) =MAX(GZ2OZt_lnd(I)-PSIH2(I), 1.0) - PSIQ_lnd(I) =MAX(LOG((ZA(I)+ZQ_lnd(i))/ZQ_lnd(I))-PSIH(I) ,1.0) - PSIQ2_lnd(I) =MAX(LOG((2.0+ZQ_lnd(i))/ZQ_lnd(I))-PSIH2(I) ,1.0) + PSIX_lnd(I) =MAX(GZ1OZ0_lnd(I)-PSIM(I), 1.0_kind_phys) + PSIX10_lnd(I)=MAX(GZ10OZ0_lnd(I)-PSIM10(I), 1.0_kind_phys) + PSIT_lnd(I) =MAX(GZ1OZt_lnd(I)-PSIH(I) , 1.0_kind_phys) + PSIT2_lnd(I) =MAX(GZ2OZt_lnd(I)-PSIH2(I), 1.0_kind_phys) + PSIQ_lnd(I) =MAX(LOG((ZA(I)+ZQ_lnd(i))/ZQ_lnd(I))-PSIH(I) ,1.0_kind_phys) + PSIQ2_lnd(I) =MAX(LOG((2.0+ZQ_lnd(i))/ZQ_lnd(I))-PSIH2(I) ,1.0_kind_phys) ENDIF ! end land points @@ -1591,8 +1612,8 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !COMPUTE z/L first guess: CALL Li_etal_2010(ZOL(I),rb_ice(I),ZA(I)/ZNTstoch_ice(I),zratio_ice(I)) !ZOL(I)=ZA(I)*KARMAN*G*MOL(I)/(TH1D(I)*MAX(UST_ice(I)*UST_ice(I),0.0001)) - ZOL(I)=MAX(ZOL(I),0.0) - ZOL(I)=MIN(ZOL(I),20.) + ZOL(I)=MAX(ZOL(I),0.0_kind_phys) + ZOL(I)=MIN(ZOL(I),20._kind_phys) IF (debug_code >= 1) THEN IF (ZNTstoch_ice(i) < 1E-8 .OR. Zt_ice(i) < 1E-10) THEN @@ -1609,14 +1630,14 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !zol(I)=zolri(rb_ice(I),ZA(I),ZNTstoch_ice(I),ZT_ice(I),ZOL(I),psi_opt) !Use brute-force method zol(I)=zolrib(rb_ice(I),ZA(I),ZNTstoch_ice(I),zt_ice(I),GZ1OZ0_ice(I),GZ1OZt_ice(I),ZOL(I),psi_opt) - ZOL(I)=MAX(ZOL(I),0.0) - ZOL(I)=MIN(ZOL(I),20.) + ZOL(I)=MAX(ZOL(I),0.0_kind_phys) + ZOL(I)=MIN(ZOL(I),20._kind_phys) zolzt = zol(I)*zt_ice(I)/ZA(I) ! zt/L zolz0 = zol(I)*ZNTstoch_ice(I)/ZA(I) ! z0/L zolza = zol(I)*(za(I)+ZNTstoch_ice(I))/za(I) ! (z+z0/L zol10 = zol(I)*(10.+ZNTstoch_ice(I))/za(I) ! (10+z0)/L - zol2 = zol(I)*(2.+ZNTstoch_ice(I))/za(I) ! (2+z0)/L + zol2 = zol(I)*(2.+ZNTstoch_ice(I))/za(I) ! (2+z0)/L !COMPUTE PSIM and PSIH !CALL PSI_Beljaars_Holtslag_1991(PSIM(I),PSIH(I),ZOL(I)) @@ -1633,9 +1654,9 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! 1.0 over Monin-Obukhov length RMOL(I)= ZOL(I)/ZA(I) - ELSEIF(rb_ice(I) .EQ. 0.) THEN - !========================================================= - !-----CLASS 3; FORCED CONVECTION/NEUTRAL: + ELSEIF(rb_ice(I) .EQ. 0.) THEN + !========================================================= + !-----CLASS 3; FORCED CONVECTION/NEUTRAL: !========================================================= PSIM(I)=0.0 @@ -1649,14 +1670,14 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ELSEIF(rb_ice(I) .LT. 0.)THEN !========================================================== - !-----CLASS 4; FREE CONVECTION: + !-----CLASS 4; FREE CONVECTION: !========================================================== !COMPUTE z/L first guess: CALL Li_etal_2010(ZOL(I),rb_ice(I),ZA(I)/ZNTstoch_ice(I),zratio_ice(I)) !ZOL(I)=ZA(I)*KARMAN*G*MOL(I)/(TH1D(I)*MAX(UST_ice(I)*UST_ice(I),0.001)) - ZOL(I)=MAX(ZOL(I),-20.0) - ZOL(I)=MIN(ZOL(I),0.0) + ZOL(I)=MAX(ZOL(I),-20.0_kind_phys) + ZOL(I)=MIN(ZOL(I),0.0_kind_phys) IF (debug_code >= 1) THEN IF (ZNTstoch_ice(i) < 1E-8 .OR. Zt_ice(i) < 1E-10) THEN @@ -1673,8 +1694,8 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !zol(I)=zolri(rb_ice(I),ZA(I),ZNTstoch_ice(I),ZT_ice(I),ZOL(I),psi_opt) !Use brute-force method zol(I)=zolrib(rb_ice(I),ZA(I),ZNTstoch_ice(I),zt_ice(I),GZ1OZ0_ice(I),GZ1OZt_ice(I),ZOL(I),psi_opt) - ZOL(I)=MAX(ZOL(I),-20.0) - ZOL(I)=MIN(ZOL(I),0.0) + ZOL(I)=MAX(ZOL(I),-20.0_kind_phys) + ZOL(I)=MIN(ZOL(I),0.0_kind_phys) zolzt = zol(I)*zt_ice(I)/ZA(I) ! zt/L zolz0 = zol(I)*ZNTstoch_ice(I)/ZA(I) ! z0/L @@ -1702,33 +1723,33 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & PSIM10(I)=MIN(PSIM10(I),0.9*GZ10OZ0_ice(I)) PSIH10(I)=MIN(PSIH10(I),0.9*GZ10OZt_ice(I)) - RMOL(I) = ZOL(I)/ZA(I) + RMOL(I) = ZOL(I)/ZA(I) ENDIF ! CALCULATE THE RESISTANCE: - PSIX_ice(I) =MAX(GZ1OZ0_ice(I)-PSIM(I) , 1.0) - PSIX10_ice(I)=MAX(GZ10OZ0_ice(I)-PSIM10(I), 1.0) - PSIT_ice(I) =MAX(GZ1OZt_ice(I)-PSIH(I) , 1.0) - PSIT2_ice(I) =MAX(GZ2OZt_ice(I)-PSIH2(I) , 1.0) - PSIQ_ice(I) =MAX(LOG((ZA(I)+ZQ_ice(i))/ZQ_ice(I))-PSIH(I) ,1.0) - PSIQ2_ice(I) =MAX(LOG((2.0+ZQ_ice(i))/ZQ_ice(I))-PSIH2(I) ,1.0) + PSIX_ice(I) =MAX(GZ1OZ0_ice(I)-PSIM(I) , 1.0_kind_phys) + PSIX10_ice(I)=MAX(GZ10OZ0_ice(I)-PSIM10(I), 1.0_kind_phys) + PSIT_ice(I) =MAX(GZ1OZt_ice(I)-PSIH(I) , 1.0_kind_phys) + PSIT2_ice(I) =MAX(GZ2OZt_ice(I)-PSIH2(I) , 1.0_kind_phys) + PSIQ_ice(I) =MAX(LOG((ZA(I)+ZQ_ice(i))/ZQ_ice(I))-PSIH(I) ,1.0_kind_phys) + PSIQ2_ice(I) =MAX(LOG((2.0+ZQ_ice(i))/ZQ_ice(I))-PSIH2(I) ,1.0_kind_phys) ENDIF ! end ice points !------------------------------------------------------------ - !-----COMPUTE THE FRICTIONAL VELOCITY: + !-----COMPUTE THE FRICTIONAL VELOCITY: !------------------------------------------------------------ IF (wet(I)) THEN - ! TO PREVENT OSCILLATIONS AVERAGE WITH OLD VALUE + ! TO PREVENT OSCILLATIONS AVERAGE WITH OLD VALUE OLDUST = UST_wat(I) !UST_wat(I)=0.5*UST_wat(I)+0.5*KARMAN*WSPD(I)/PSIX_wat(I) - !NON-AVERAGED: + !NON-AVERAGED: UST_wat(I)=KARMAN*WSPD(I)/PSIX_wat(I) stress_wat(i)=ust_wat(i)**2 - ! Compute u* without vconv for use in HFX calc when isftcflx > 0 + ! Compute u* without vconv for use in HFX calc when isftcflx > 0 WSPDI(I)=MAX(SQRT(U1D(I)*U1D(I)+V1D(I)*V1D(I)), wmin) !tgs - should USTM be separater for dry, icy, wet? USTM(I)=0.5*USTM(I)+0.5*KARMAN*WSPDI(I)/PSIX_wat(I) @@ -1741,7 +1762,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! TO PREVENT OSCILLATIONS AVERAGE WITH OLD VALUE OLDUST = UST_lnd(I) UST_lnd(I)=0.5*UST_lnd(I)+0.5*KARMAN*WSPD(I)/PSIX_lnd(I) - !NON-AVERAGED: + !NON-AVERAGED: !UST_lnd(I)=KARMAN*WSPD(I)/PSIX_lnd(I) !From Tilden Meyers: !IF (rb_lnd(I) .GE. 0.0) THEN @@ -1749,7 +1770,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !ELSE ! ust_lnd(i)=WSPD_lnd*0.1*(1.0 - 10.0*rb_lnd(I))**onethird !ENDIF - UST_lnd(I)=MAX(UST_lnd(I),0.005) + UST_lnd(I)=MAX(UST_lnd(I),0.005_kind_phys) stress_lnd(i)=ust_lnd(i)**2 !set ustm = ust over land. @@ -1761,9 +1782,9 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ! TO PREVENT OSCILLATIONS AVERAGE WITH OLD VALUE OLDUST = UST_ice(I) UST_ice(I)=0.5*UST_ice(I)+0.5*KARMAN*WSPD(I)/PSIX_ice(I) - !NON-AVERAGED: + !NON-AVERAGED: !UST_ice(I)=KARMAN*WSPD(I)/PSIX_ice(I) - UST_ice(I)=MAX(UST_ice(I),0.005) + UST_ice(I)=MAX(UST_ice(I),0.005_kind_phys) stress_ice(i)=ust_ice(i)**2 !Set ustm = ust over ice. @@ -1844,17 +1865,17 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & DO I=its,ite if( flag_iter(i) ) then - IF (ISFFLX .LT. 1) THEN + IF (ISFFLX .LT. 1) THEN - QFX(i) = 0. + QFX(i) = 0. HFX(i) = 0. HFLX(i) = 0. - FLHC(I) = 0. - FLQC(I) = 0. - LH(I) = 0. - CHS(I) = 0. - CH(I) = 0. - CHS2(i) = 0. + FLHC(I) = 0. + FLQC(I) = 0. + LH(I) = 0. + CHS(I) = 0. + CH(I) = 0. + CHS2(i) = 0. CQS2(i) = 0. ch_wat(I)= 0. cm_wat(I)= 0. @@ -1881,7 +1902,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !---------------------------------- QFX(I)=FLQC(I)*(QSFCMR_lnd(I)-QV1D(I)) !QFX(I)=FLQC(I)*(QSFC_lnd(I)-QV1D(I)) - QFX(I)=MAX(QFX(I),-0.02) !allows small neg QFX + QFX(I)=MAX(QFX(I),-0.02_kind_phys) !allows small neg QFX LH(i)=XLV*QFX(i) ! BWG, 2020-06-17: Mod next 2 lines for fractional QFLX_lnd(i)=QFX(i)/RHO1D(i) @@ -1892,7 +1913,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !---------------------------------- !HFX(I)=FLHC(I)*(THSK_lnd(I)-TH1D(I)) HFX(I)=RHO1D(I)*CPM(I)*KARMAN*WSPD(i)/PSIX_lnd(I)*KARMAN/PSIT_lnd(I)*(THSK_lnd(I)-TH1D(i)) - HFX(I)=MAX(HFX(I),-250.) + HFX(I)=MAX(HFX(I),-250._kind_phys) ! BWG, 2020-06-17: Mod next 2 lines for fractional HFLX_lnd(I)=HFX(I)/(RHO1D(I)*cpm(I)) HFLX(I)=HFLX_lnd(I) @@ -1926,14 +1947,14 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !---------------------------------- QFX(I)=FLQC(I)*(QSFCMR_wat(I)-QV1D(I)) !QFX(I)=FLQC(I)*(QSFC_wat(I)-QV1D(I)) - QFX(I)=MAX(QFX(I),-0.02) !allows small neg QFX + QFX(I)=MAX(QFX(I),-0.02_kind_phys) !allows small neg QFX LH(I)=XLV*QFX(I) ! BWG, 2020-06-17: Mod next 2 lines for fractional QFLX_wat(i)=QFX(i)/RHO1D(i) QFLX(i)=QFLX_wat(i) !---------------------------------- - ! COMPUTE SURFACE HEAT FLUX: + ! COMPUTE SURFACE HEAT FLUX: !---------------------------------- !HFX(I)=FLHC(I)*(THSK_wat(I)-TH1D(I)) HFX(I)=RHO1D(I)*CPM(I)*KARMAN*WSPD(i)/PSIX_wat(I)*KARMAN/PSIT_wat(I)*(THSK_wat(I)-TH1D(i)) @@ -1970,11 +1991,11 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & IF (compute_flux) THEN !---------------------------------- - ! COMPUTE SURFACE MOISTURE FLUX: + ! COMPUTE SURFACE MOISTURE FLUX: !---------------------------------- QFX(I)=FLQC(I)*(QSFCMR_ice(I)-QV1D(I)) !QFX(I)=FLQC(I)*(QSFC_ice(I)-QV1D(I)) - QFX(I)=MAX(QFX(I),-0.02) !allows small neg QFX + QFX(I)=MAX(QFX(I),-0.02_kind_phys) !allows small neg QFX LH(I)=XLF*QFX(I) ! BWG, 2020-06-17: Mod next 2 lines for fractional QFLX_ice(i)=QFX(i)/RHO1D(i) @@ -1985,7 +2006,7 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & !---------------------------------- !HFX(I)=FLHC(I)*(THSK_ice(I)-TH1D(I)) HFX(I)=RHO1D(I)*CPM(I)*KARMAN*WSPD(i)/PSIX_ice(I)*KARMAN/PSIT_ice(I)*(THSK_ice(I)-TH1D(i)) - HFX(I)=MAX(HFX(I),-250.) + HFX(I)=MAX(HFX(I),-250._kind_phys) ! BWG, 2020-06-17: Mod next 2 lines for fractional HFLX_ice(I)=HFX(I)/(RHO1D(I)*cpm(I)) HFLX(I)=HFLX_ice(I) @@ -2255,28 +2276,28 @@ SUBROUTINE SFCLAY1D_mynn(flag_iter, & ENDIF ! end debug option END SUBROUTINE SFCLAY1D_mynn -!------------------------------------------------------------------- +!------------------------------------------------------------------- !>\ingroup mynn_sfc !> This subroutine returns the thermal and moisture roughness lengths !! from Zilitinkevich (1995) and Zilitinkevich et al. (2001) over -!! land and water, respectively. +!! land and water, respectively. !! !! MODS: !! 20120705 : added IZ0TLND option. Note: This option was designed !! to work with the Noah LSM and may be specific for that -!! LSM only. Tests with RUC LSM showed no improvements. +!! LSM only. Tests with RUC LSM showed no improvements. SUBROUTINE zilitinkevich_1995(Z_0,Zt,Zq,restar,ustar,KARMAN,& & landsea,IZ0TLND2,spp_sfc,rstoch) IMPLICIT NONE - REAL, INTENT(IN) :: Z_0,restar,ustar,KARMAN,landsea - INTEGER, OPTIONAL, INTENT(IN):: IZ0TLND2 - REAL, INTENT(OUT) :: Zt,Zq - REAL :: CZIL !=0.100 in Chen et al. (1997) - !=0.075 in Zilitinkevich (1995) - !=0.500 in Lemone et al. (2008) + REAL(kind=kind_phys), INTENT(IN) :: Z_0,restar,ustar,KARMAN,landsea + INTEGER, OPTIONAL, INTENT(IN) :: IZ0TLND2 + REAL(kind=kind_phys), INTENT(OUT) :: Zt,Zq + REAL(kind=kind_phys) :: CZIL !=0.100 in Chen et al. (1997) + !=0.075 in Zilitinkevich (1995) + !=0.500 in Lemone et al. (2008) INTEGER, INTENT(IN) :: spp_sfc - REAL, INTENT(IN) :: rstoch + REAL(kind=kind_phys), INTENT(IN) :: rstoch IF (landsea-1.5 .GT. 0) THEN !WATER @@ -2285,18 +2306,18 @@ SUBROUTINE zilitinkevich_1995(Z_0,Zt,Zq,restar,ustar,KARMAN,& !Their equations 15 and 16). IF (restar .LT. 0.1) THEN Zt = Z_0*EXP(KARMAN*2.0) - Zt = MIN( Zt, 6.0e-5) - Zt = MAX( Zt, 2.0e-9) + Zt = MIN( Zt, 6.0e-5_kind_phys) + Zt = MAX( Zt, 2.0e-9_kind_phys) Zq = Z_0*EXP(KARMAN*3.0) - Zq = MIN( Zq, 6.0e-5) - Zq = MAX( Zq, 2.0e-9) + Zq = MIN( Zq, 6.0e-5_kind_phys) + Zq = MAX( Zq, 2.0e-9_kind_phys) ELSE Zt = Z_0*EXP(-KARMAN*(4.0*SQRT(restar)-3.2)) - Zt = MIN( Zt, 6.0e-5) - Zt = MAX( Zt, 2.0e-9) + Zt = MIN( Zt, 6.0e-5_kind_phys) + Zt = MAX( Zt, 2.0e-9_kind_phys) Zq = Z_0*EXP(-KARMAN*(4.0*SQRT(restar)-4.2)) - Zq = MIN( Zt, 6.0e-5) - Zq = MAX( Zt, 2.0e-9) + Zq = MIN( Zt, 6.0e-5_kind_phys) + Zq = MAX( Zt, 2.0e-9_kind_phys) ENDIF ELSE !LAND @@ -2315,15 +2336,15 @@ SUBROUTINE zilitinkevich_1995(Z_0,Zt,Zq,restar,ustar,KARMAN,& Zq = MIN( Zq, 0.75*Z_0) ! stochastically perturb thermal and moisture roughness length. -! currently set to half the amplitude: +! currently set to half the amplitude: if (spp_sfc==1) then Zt = Zt + Zt * 0.5 * rstoch - Zt = MAX(Zt, 0.0001) + Zt = MAX(Zt, 0.0001_kind_phys) Zq = Zt endif ENDIF - + return END SUBROUTINE zilitinkevich_1995 @@ -2332,29 +2353,30 @@ END SUBROUTINE zilitinkevich_1995 SUBROUTINE davis_etal_2008(Z_0,ustar) !a.k.a. : Donelan et al. (2004) - !This formulation for roughness length was designed to match + !This formulation for roughness length was designed to match !the labratory experiments of Donelan et al. (2004). !This is an update version from Davis et al. 2008, which !corrects a small-bias in Z_0 (AHW real-time 2012). IMPLICIT NONE - REAL, INTENT(IN) :: ustar - REAL, INTENT(OUT) :: Z_0 - REAL :: ZW, ZN1, ZN2 - REAL, PARAMETER :: G=9.81, OZO=1.59E-5 + REAL(kind=kind_phys), INTENT(IN) :: ustar + REAL(kind=kind_phys), INTENT(OUT) :: Z_0 + REAL(kind=kind_phys) :: ZW, ZN1, ZN2 + REAL(kind=kind_phys), PARAMETER :: G=9.81, OZO=1.59E-5 !OLD FORM: Z_0 = 10.*EXP(-10./(ustar**onethird)) !NEW FORM: - ZW = MIN((ustar/1.06)**(0.3),1.0) + ZW = MIN((ustar/1.06)**(0.3),1.0_kind_phys) ZN1 = 0.011*ustar*ustar/G + OZO ZN2 = 10.*exp(-9.5*ustar**(-onethird)) + & - 0.11*1.5E-5/AMAX1(ustar,0.01) + 0.11*1.5E-5/MAX(ustar,0.01_kind_phys) + !0.11*1.5E-5/AMAX1(ustar,0.01) Z_0 = (1.0-ZW) * ZN1 + ZW * ZN2 - Z_0 = MAX( Z_0, 1.27e-7) !These max/mins were suggested by - Z_0 = MIN( Z_0, 2.85e-3) !Davis et al. (2008) - + Z_0 = MAX( Z_0, 1.27e-7_kind_phys) !These max/mins were suggested by + Z_0 = MIN( Z_0, 2.85e-3_kind_phys) !Davis et al. (2008) + return END SUBROUTINE davis_etal_2008 @@ -2365,22 +2387,22 @@ END SUBROUTINE davis_etal_2008 SUBROUTINE Taylor_Yelland_2001(Z_0,ustar,wsp10) IMPLICIT NONE - REAL, INTENT(IN) :: ustar,wsp10 - REAL, INTENT(OUT) :: Z_0 - REAL, parameter :: g=9.81, pi=3.14159265 - REAL :: hs, Tp, Lp + REAL(kind=kind_phys), INTENT(IN) :: ustar,wsp10 + REAL(kind=kind_phys), INTENT(OUT) :: Z_0 + REAL(kind=kind_phys), parameter :: g=9.81, pi=3.14159265 + REAL(kind=kind_phys) :: hs, Tp, Lp !hs is the significant wave height hs = 0.0248*(wsp10**2.) !Tp dominant wave period - Tp = 0.729*MAX(wsp10,0.1) + Tp = 0.729*MAX(wsp10,0.1_kind_phys) !Lp is the wavelength of the dominant wave Lp = g*Tp**2/(2*pi) Z_0 = 1200.*hs*(hs/Lp)**4.5 - Z_0 = MAX( Z_0, 1.27e-7) !These max/mins were suggested by - Z_0 = MIN( Z_0, 2.85e-3) !Davis et al. (2008) - + Z_0 = MAX( Z_0, 1.27e-7_kind_phys) !These max/mins were suggested by + Z_0 = MIN( Z_0, 2.85e-3_kind_phys) !Davis et al. (2008) + return END SUBROUTINE Taylor_Yelland_2001 @@ -2393,18 +2415,18 @@ END SUBROUTINE Taylor_Yelland_2001 SUBROUTINE charnock_1955(Z_0,ustar,wsp10,visc,zu) IMPLICIT NONE - REAL, INTENT(IN) :: ustar, visc, wsp10, zu - REAL, INTENT(OUT) :: Z_0 - REAL, PARAMETER :: G=9.81, CZO2=0.011 - REAL :: CZC !variable charnock "constant" - REAL :: wsp10m ! logarithmically calculated 10 m + REAL(kind=kind_phys), INTENT(IN) :: ustar, visc, wsp10, zu + REAL(kind=kind_phys), INTENT(OUT) :: Z_0 + REAL(kind=kind_phys), PARAMETER :: G=9.81, CZO2=0.011 + REAL(kind=kind_phys) :: CZC ! variable charnock "constant" + REAL(kind=kind_phys) :: wsp10m ! logarithmically calculated 10 m wsp10m = wsp10*log(10./1e-4)/log(zu/1e-4) - CZC = CZO2 + 0.007*MIN(MAX((wsp10m-10.)/8., 0.), 1.0) + CZC = CZO2 + 0.007*MIN(MAX((wsp10m-10.)/8., 0._kind_phys), 1.0_kind_phys) - Z_0 = CZC*ustar*ustar/G + (0.11*visc/MAX(ustar,0.05)) - Z_0 = MAX( Z_0, 1.27e-7) !These max/mins were suggested by - Z_0 = MIN( Z_0, 2.85e-3) !Davis et al. (2008) + Z_0 = CZC*ustar*ustar/G + (0.11*visc/MAX(ustar,0.05_kind_phys)) + Z_0 = MAX( Z_0, 1.27e-7_kind_phys) !These max/mins were suggested by + Z_0 = MIN( Z_0, 2.85e-3_kind_phys) !Davis et al. (2008) return @@ -2418,21 +2440,21 @@ END SUBROUTINE charnock_1955 SUBROUTINE edson_etal_2013(Z_0,ustar,wsp10,visc,zu) IMPLICIT NONE - REAL, INTENT(IN) :: ustar, visc, wsp10, zu - REAL, INTENT(OUT) :: Z_0 - REAL, PARAMETER :: G=9.81 - REAL, PARAMETER :: m=0.0017, b=-0.005 - REAL :: CZC ! variable charnock "constant" - REAL :: wsp10m ! logarithmically calculated 10 m + REAL(kind=kind_phys), INTENT(IN) :: ustar, visc, wsp10, zu + REAL(kind=kind_phys), INTENT(OUT) :: Z_0 + REAL(kind=kind_phys), PARAMETER :: G=9.81 + REAL(kind=kind_phys), PARAMETER :: m=0.0017, b=-0.005 + REAL(kind=kind_phys) :: CZC ! variable charnock "constant" + REAL(kind=kind_phys) :: wsp10m ! logarithmically calculated 10 m wsp10m = wsp10*log(10/1e-4)/log(zu/1e-4) - wsp10m = MIN(19., wsp10m) + wsp10m = MIN(19._kind_phys, wsp10m) CZC = m*wsp10m + b - CZC = MAX(CZC, 0.0) + CZC = MAX(CZC, 0.0_kind_phys) - Z_0 = CZC*ustar*ustar/G + (0.11*visc/MAX(ustar,0.07)) - Z_0 = MAX( Z_0, 1.27e-7) !These max/mins were suggested by - Z_0 = MIN( Z_0, 2.85e-3) !Davis et al. (2008) + Z_0 = CZC*ustar*ustar/G + (0.11*visc/MAX(ustar,0.07_kind_phys)) + Z_0 = MAX( Z_0, 1.27e-7_kind_phys) !These max/mins were suggested by + Z_0 = MIN( Z_0, 2.85e-3_kind_phys) !Davis et al. (2008) return @@ -2448,25 +2470,25 @@ END SUBROUTINE edson_etal_2013 SUBROUTINE garratt_1992(Zt,Zq,Z_0,Ren,landsea) IMPLICIT NONE - REAL, INTENT(IN) :: Ren, Z_0,landsea - REAL, INTENT(OUT) :: Zt,Zq - REAL :: Rq - REAL, PARAMETER :: e=2.71828183 + REAL(kind=kind_phys), INTENT(IN) :: Ren, Z_0,landsea + REAL(kind=kind_phys), INTENT(OUT) :: Zt,Zq + REAL(kind=kind_phys) :: Rq + REAL(kind=kind_phys), PARAMETER :: e=2.71828183 IF (landsea-1.5 .GT. 0) THEN !WATER Zt = Z_0*EXP(2.0 - (2.48*(Ren**0.25))) Zq = Z_0*EXP(2.0 - (2.28*(Ren**0.25))) - Zq = MIN( Zq, 5.5e-5) - Zq = MAX( Zq, 2.0e-9) - Zt = MIN( Zt, 5.5e-5) - Zt = MAX( Zt, 2.0e-9) !same lower limit as ECMWF + Zq = MIN( Zq, 5.5e-5_kind_phys) + Zq = MAX( Zq, 2.0e-9_kind_phys) + Zt = MIN( Zt, 5.5e-5_kind_phys) + Zt = MAX( Zt, 2.0e-9_kind_phys) !same lower limit as ECMWF ELSE !LAND Zq = Z_0/(e**2.) !taken from Garratt (1980,1992) Zt = Zq ENDIF - + return END SUBROUTINE garratt_1992 @@ -2484,9 +2506,9 @@ END SUBROUTINE garratt_1992 SUBROUTINE fairall_etal_2003(Zt,Zq,Ren,ustar,visc,rstoch,spp_sfc) IMPLICIT NONE - REAL, INTENT(IN) :: Ren,ustar,visc,rstoch + REAL(kind=kind_phys), INTENT(IN) :: Ren,ustar,visc,rstoch INTEGER, INTENT(IN):: spp_sfc - REAL, INTENT(OUT) :: Zt,Zq + REAL(kind=kind_phys), INTENT(OUT) :: Zt,Zq IF (Ren .le. 2.) then @@ -2509,11 +2531,11 @@ SUBROUTINE fairall_etal_2003(Zt,Zq,Ren,ustar,visc,rstoch,spp_sfc) Zq = Zt endif - Zt = MIN(Zt,1.0e-4) - Zt = MAX(Zt,2.0e-9) + Zt = MIN(Zt,1.0e-4_kind_phys) + Zt = MAX(Zt,2.0e-9_kind_phys) - Zq = MIN(Zt,1.0e-4) - Zq = MAX(Zt,2.0e-9) + Zq = MIN(Zt,1.0e-4_kind_phys) + Zq = MAX(Zt,2.0e-9_kind_phys) return @@ -2528,20 +2550,20 @@ END SUBROUTINE fairall_etal_2003 SUBROUTINE fairall_etal_2014(Zt,Zq,Ren,ustar,visc,rstoch,spp_sfc) IMPLICIT NONE - REAL, INTENT(IN) :: Ren,ustar,visc,rstoch + REAL(kind=kind_phys), INTENT(IN) :: Ren,ustar,visc,rstoch INTEGER, INTENT(IN):: spp_sfc - REAL, INTENT(OUT) :: Zt,Zq + REAL(kind=kind_phys), INTENT(OUT) :: Zt,Zq !Zt = (5.5e-5)*(Ren**(-0.60)) - Zt = MIN(1.6E-4, 5.8E-5/(Ren**0.72)) + Zt = MIN(1.6E-4_kind_phys, 5.8E-5/(Ren**0.72)) Zq = Zt IF (spp_sfc ==1) THEN - Zt = MAX(Zt + Zt*0.5*rstoch,2.0e-9) - Zq = MAX(Zt + Zt*0.5*rstoch,2.0e-9) + Zt = MAX(Zt + Zt*0.5*rstoch,2.0e-9_kind_phys) + Zq = MAX(Zt + Zt*0.5*rstoch,2.0e-9_kind_phys) ELSE - Zt = MAX(Zt,2.0e-9) - Zq = MAX(Zt,2.0e-9) + Zt = MAX(Zt,2.0e-9_kind_phys) + Zq = MAX(Zt,2.0e-9_kind_phys) ENDIF return @@ -2549,18 +2571,18 @@ SUBROUTINE fairall_etal_2014(Zt,Zq,Ren,ustar,visc,rstoch,spp_sfc) END SUBROUTINE fairall_etal_2014 !-------------------------------------------------------------------- !>\ingroup mynn_sfc -!> This is a modified version of Yang et al (2002 QJRMS, 2008 JAMC) -!! and Chen et al (2010, J of Hydromet). Although it was originally -!! designed for arid regions with bare soil, it is modified +!> This is a modified version of Yang et al (2002 QJRMS, 2008 JAMC) +!! and Chen et al (2010, J of Hydromet). Although it was originally +!! designed for arid regions with bare soil, it is modified !! here to perform over a broader spectrum of vegetation. !! -!!The original formulation relates the thermal roughness length (Zt) +!!The original formulation relates the thermal roughness length (Zt) !!to u* and T*: -!! +!! !! Zt = ht * EXP(-beta*(ustar**0.5)*(ABS(tstar)**0.25)) !! -!!where ht = Renc*visc/ustar and the critical Reynolds number -!!(Renc) = 70. Beta was originally = 10 (2002 paper) but was revised +!!where ht = Renc*visc/ustar and the critical Reynolds number +!!(Renc) = 70. Beta was originally = 10 (2002 paper) but was revised !!to 7.2 (in 2008 paper). Their form typically varies the !!ratio Z0/Zt by a few orders of magnitude (1-1E4). !! @@ -2575,24 +2597,24 @@ END SUBROUTINE fairall_etal_2014 SUBROUTINE Yang_2008(Z_0,Zt,Zq,ustar,tstar,qst,Ren,visc) IMPLICIT NONE - REAL, INTENT(IN) :: Z_0, Ren, ustar, tstar, qst, visc - REAL :: ht, &! roughness height at critical Reynolds number - tstar2, &! bounded T*, forced to be non-positive - qstar2, &! bounded q*, forced to be non-positive - Z_02, &! bounded Z_0 for variable Renc2 calc - Renc2 ! variable Renc, function of Z_0 - REAL, INTENT(OUT) :: Zt,Zq - REAL, PARAMETER :: Renc=300., & !old constant Renc - beta=1.5, & !important for diurnal variation - m=170., & !slope for Renc2 function - b=691. !y-intercept for Renc2 function - - Z_02 = MIN(Z_0,0.5) - Z_02 = MAX(Z_02,0.04) + REAL(kind=kind_phys), INTENT(IN) :: Z_0, Ren, ustar, tstar, qst, visc + REAL(kind=kind_phys) :: ht, &! roughness height at critical Reynolds number + tstar2, &! bounded T*, forced to be non-positive + qstar2, &! bounded q*, forced to be non-positive + Z_02, &! bounded Z_0 for variable Renc2 calc + Renc2 ! variable Renc, function of Z_0 + REAL(kind=kind_phys), INTENT(OUT) :: Zt,Zq + REAL(kind=kind_phys), PARAMETER :: Renc=300., & !old constant Renc + beta=1.5, & !important for diurnal variation + m=170., & !slope for Renc2 function + b=691. !y-intercept for Renc2 function + + Z_02 = MIN(Z_0,0.5_kind_phys) + Z_02 = MAX(Z_02,0.04_kind_phys) Renc2= b + m*log(Z_02) - ht = Renc2*visc/MAX(ustar,0.01) - tstar2 = MIN(tstar, 0.0) - qstar2 = MIN(qst,0.0) + ht = Renc2*visc/MAX(ustar,0.01_kind_phys) + tstar2 = MIN(tstar, 0.0_kind_phys) + qstar2 = MIN(qst,0.0_kind_phys) Zt = ht * EXP(-beta*(ustar**0.5)*(ABS(tstar2)**1.0)) Zq = ht * EXP(-beta*(ustar**0.5)*(ABS(qstar2)**1.0)) @@ -2609,14 +2631,14 @@ END SUBROUTINE Yang_2008 !>\ingroup mynn_sfc SUBROUTINE GFS_z0_lnd(z0max,shdmax,z1,vegtype,ivegsrc,z0pert) - REAL, INTENT(OUT) :: z0max - REAL, INTENT(IN) :: shdmax,z1,z0pert - INTEGER, INTENT(IN):: vegtype,ivegsrc - REAL :: tem1, tem2 + REAL(kind=kind_phys), INTENT(OUT) :: z0max + REAL(kind=kind_phys), INTENT(IN) :: shdmax,z1,z0pert + INTEGER, INTENT(IN) :: vegtype,ivegsrc + REAL(kind=kind_phys) :: tem1, tem2 ! z0max = max(1.0e-6, min(0.01 * z0max, z1)) !already converted into meters in the wrapper - z0max = max(1.0e-6, min(z0max, z1)) + z0max = max(1.0e-6_kind_phys, min(z0max, z1)) !** xubin's new z0 over land tem1 = 1.0 - shdmax tem2 = tem1 * tem1 @@ -2629,10 +2651,10 @@ SUBROUTINE GFS_z0_lnd(z0max,shdmax,z1,vegtype,ivegsrc,z0pert) elseif (vegtype == 6) then z0max = exp( tem2*log01 + tem1*log05 ) elseif (vegtype == 7) then -! z0max = exp( tem2*log01 + tem1*log01 ) +! z0max = exp( tem2*log01 + tem1*log01 ) z0max = 0.01 elseif (vegtype == 16) then -! z0max = exp( tem2*log01 + tem1*log01 ) +! z0max = exp( tem2*log01 + tem1*log01 ) z0max = 0.01 else z0max = exp( tem2*log01 + tem1*log(z0max) ) @@ -2645,10 +2667,10 @@ SUBROUTINE GFS_z0_lnd(z0max,shdmax,z1,vegtype,ivegsrc,z0pert) elseif (vegtype == 8) then z0max = exp( tem2*log01 + tem1*log05 ) elseif (vegtype == 9) then -! z0max = exp( tem2*log01 + tem1*log01 ) +! z0max = exp( tem2*log01 + tem1*log01 ) z0max = 0.01 elseif (vegtype == 11) then -! z0max = exp( tem2*log01 + tem1*log01 ) +! z0max = exp( tem2*log01 + tem1*log01 ) z0max = 0.01 else z0max = exp( tem2*log01 + tem1*log(z0max) ) @@ -2656,12 +2678,12 @@ SUBROUTINE GFS_z0_lnd(z0max,shdmax,z1,vegtype,ivegsrc,z0pert) endif -! mg, sfc-perts: add surface perturbations to z0max over land +! mg, sfc-perts: add surface perturbations to z0max over land if (z0pert /= 0.0 ) then z0max = z0max * (10.**z0pert) endif - z0max = max(z0max, 1.0e-6) + z0max = max(z0max, 1.0e-6_kind_phys) END SUBROUTINE GFS_z0_lnd !-------------------------------------------------------------------- @@ -2669,10 +2691,10 @@ END SUBROUTINE GFS_z0_lnd !>\ingroup mynn_sfc SUBROUTINE GFS_zt_lnd(ztmax,z0max,sigmaf,ztpert,ustar_lnd) - REAL, INTENT(OUT) :: ztmax - REAL, INTENT(IN) :: z0max,sigmaf,ztpert,ustar_lnd - REAL :: czilc, tem1, tem2 - REAL, PARAMETER :: ca = 0.4 + REAL(kind=kind_phys), INTENT(OUT) :: ztmax + REAL(kind=kind_phys), INTENT(IN) :: z0max,sigmaf,ztpert,ustar_lnd + REAL(kind=kind_phys) :: czilc, tem1, tem2 + REAL(kind=kind_phys), PARAMETER :: ca = 0.4 ! czilc = 10.0 ** (- (0.40/0.07) * z0) ! fei's canopy height dependance of czil czilc = 0.8 @@ -2690,25 +2712,25 @@ SUBROUTINE GFS_zt_lnd(ztmax,z0max,sigmaf,ztpert,ustar_lnd) if (ztpert /= 0.0) then ztmax = ztmax * (10.**ztpert) endif - ztmax = max(ztmax, 1.0e-6) + ztmax = max(ztmax, 1.0e-6_kind_phys) END SUBROUTINE GFS_zt_lnd !-------------------------------------------------------------------- !>\ingroup mynn_sfc SUBROUTINE GFS_z0_wat(z0rl_wat,ustar_wat,WSPD,z1,sfc_z0_type,redrag) - REAL, INTENT(OUT) :: z0rl_wat - REAL, INTENT(INOUT):: ustar_wat - REAL, INTENT(IN) :: wspd,z1 + REAL(kind=kind_phys), INTENT(OUT) :: z0rl_wat + REAL(kind=kind_phys), INTENT(INOUT):: ustar_wat + REAL(kind=kind_phys), INTENT(IN) :: wspd,z1 LOGICAL, INTENT(IN):: redrag INTEGER, INTENT(IN):: sfc_z0_type - REAL :: z0,z0max,wind10m - REAL, PARAMETER :: charnock = 0.014, z0s_max=.317e-2 + REAL(kind=kind_phys) :: z0,z0max,wind10m + REAL(kind=kind_phys), PARAMETER :: charnock = 0.014, z0s_max=.317e-2 ! z0 = 0.01 * z0rl_wat !Already converted to meters in the wrapper z0 = z0rl_wat - z0max = max(1.0e-6, min(z0,z1)) + z0max = max(1.0e-6_kind_phys, min(z0,z1)) ustar_wat = sqrt(g * z0 / charnock) wind10m = wspd*log(10./1e-4)/log(z1/1e-4) !wind10m = sqrt(u10m(i)*u10m(i)+v10m(i)*v10m(i)) @@ -2727,10 +2749,10 @@ SUBROUTINE GFS_z0_wat(z0rl_wat,ustar_wat,WSPD,z1,sfc_z0_type,redrag) if (redrag) then !z0rl_wat = 100.0 * max(min(z0, z0s_max), 1.e-7) - z0rl_wat = max(min(z0, z0s_max), 1.e-7) + z0rl_wat = max(min(z0, z0s_max), 1.e-7_kind_phys) else !z0rl_wat = 100.0 * max(min(z0,.1), 1.e-7) - z0rl_wat = max(min(z0,.1), 1.e-7) + z0rl_wat = max(min(z0,.1_kind_phys), 1.e-7_kind_phys) endif elseif (sfc_z0_type == 6) then ! wang @@ -2748,18 +2770,24 @@ SUBROUTINE GFS_z0_wat(z0rl_wat,ustar_wat,WSPD,z1,sfc_z0_type,redrag) END SUBROUTINE GFS_z0_wat !-------------------------------------------------------------------- !>\ingroup mynn_sfc - SUBROUTINE GFS_zt_wat(ztmax,z0rl_wat,restar,WSPD,z1,sfc_z0_type) + SUBROUTINE GFS_zt_wat(ztmax,z0rl_wat,restar,WSPD,z1,sfc_z0_type,errmsg,errflg) - REAL, INTENT(OUT) :: ztmax - REAL, INTENT(IN) :: wspd,z1,z0rl_wat,restar + REAL(kind=kind_phys), INTENT(OUT) :: ztmax + REAL(kind=kind_phys), INTENT(IN) :: wspd,z1,z0rl_wat,restar INTEGER, INTENT(IN):: sfc_z0_type - REAL :: z0,z0max,wind10m,rat,ustar_wat - REAL, PARAMETER :: charnock = 0.014, z0s_max=.317e-2 + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg + REAL(kind=kind_phys) :: z0,z0max,wind10m,rat,ustar_wat + REAL(kind=kind_phys), PARAMETER :: charnock = 0.014, z0s_max=.317e-2 + + ! Initialize error-handling + errflg = 0 + errmsg = '' ! z0 = 0.01 * z0rl_wat !Already converted to meters in the wrapper z0 = z0rl_wat - z0max = max(1.0e-6, min(z0,z1)) + z0max = max(1.0e-6_kind_phys, min(z0,z1)) ustar_wat = sqrt(g * z0 / charnock) wind10m = wspd*log(10./1e-4)/log(z1/1e-4) @@ -2776,8 +2804,8 @@ SUBROUTINE GFS_zt_wat(ztmax,z0rl_wat,restar,WSPD,z1,sfc_z0_type) ! rat = rat / (1. + (bb2 + cc2*restar) * restar)) ! rat taken from zeng, zhao and dickinson 1997 - rat = min(7.0, 2.67 * sqrt(sqrt(restar)) - 2.57) - ztmax = max(z0max * exp(-rat), 1.0e-6) + rat = min(7.0_kind_phys, 2.67 * sqrt(sqrt(restar)) - 2.57) + ztmax = max(z0max * exp(-rat), 1.0e-6_kind_phys) ! if (sfc_z0_type == 6) then call znot_t_v6(wind10m, ztmax) ! 10-m wind,m/s, ztmax(m) @@ -2785,7 +2813,9 @@ SUBROUTINE GFS_zt_wat(ztmax,z0rl_wat,restar,WSPD,z1,sfc_z0_type) call znot_t_v7(wind10m, ztmax) ! 10-m wind,m/s, ztmax(m) else if (sfc_z0_type > 0) then write(0,*)'no option for sfc_z0_type=',sfc_z0_type - stop + errflg = 1 + errmsg = 'ERROR(GFS_zt_wat): sfc_z0_type not valid.' + return endif END SUBROUTINE GFS_zt_wat @@ -2809,7 +2839,7 @@ SUBROUTINE znot_m_v6(uref, znotm) REAL(kind=kind_phys), INTENT(IN) :: uref REAL(kind=kind_phys), INTENT(OUT):: znotm - real(kind=kind_phys), parameter :: p13 = -1.296521881682694e-02,& + REAL(kind=kind_phys), PARAMETER :: p13 = -1.296521881682694e-02,& & p12 = 2.855780863283819e-01, p11 = -1.597898515251717e+00,& & p10 = -8.396975715683501e+00, & @@ -2848,15 +2878,15 @@ SUBROUTINE znot_t_v6(uref, znott) !> Calculate scalar roughness over water with input 10-m wind !! For low-to-moderate winds, try to match the Ck-U10 relationship from COARE algorithm !! For high winds, try to retain the Ck-U10 relationship of FY2015 HWRF -!! -!!\author Bin Liu, NOAA/NCEP/EMC 2017 -! -! uref(m/s) : wind speed at 10-m height +!! +!!\author Bin Liu, NOAA/NCEP/EMC 2017 +! +! uref(m/s) : wind speed at 10-m height ! znott(meter): scalar roughness scale over water ! - REAL, INTENT(IN) :: uref - REAL, INTENT(OUT):: znott - real, parameter :: p00 = 1.100000000000000e-04,& + REAL(kind=kind_phys), INTENT(IN) :: uref + REAL(kind=kind_phys), INTENT(OUT):: znott + REAL(kind=kind_phys), PARAMETER :: p00 = 1.100000000000000e-04,& & p15 = -9.144581627678278e-10, p14 = 7.020346616456421e-08,& & p13 = -2.155602086883837e-06, p12 = 3.333848806567684e-05,& & p11 = -2.628501274963990e-04, p10 = 8.634221567969181e-04,& @@ -2915,17 +2945,17 @@ SUBROUTINE znot_m_v7(uref, znotm) !! For low-to-moderate winds, try to match the Cd-U10 relationship from COARE V3.5 (Edson et al. 2013) !! For high winds, try to fit available observational data !! Comparing to znot_t_v6, slightly decrease Cd for higher wind speed -!! -!!\author Bin Liu, NOAA/NCEP/EMC 2018 -! +!! +!!\author Bin Liu, NOAA/NCEP/EMC 2018 +! ! uref(m/s) : wind speed at 10-m height ! znotm(meter): areodynamical roughness scale over water ! - REAL, INTENT(IN) :: uref - REAL, INTENT(OUT):: znotm + REAL(kind=kind_phys), INTENT(IN) :: uref + REAL(kind=kind_phys), INTENT(OUT):: znotm - real, parameter :: p13 = -1.296521881682694e-02,& + REAL(kind=kind_phys), PARAMETER :: p13 = -1.296521881682694e-02,& & p12 = 2.855780863283819e-01, p11 = -1.597898515251717e+00,& & p10 = -8.396975715683501e+00,& @@ -2962,19 +2992,19 @@ SUBROUTINE znot_t_v7(uref, znott) IMPLICIT NONE !> Calculate scalar roughness over water with input 10-m wind !! For low-to-moderate winds, try to match the Ck-U10 relationship from COARE algorithm -!! For high winds, try to retain the Ck-U10 relationship of FY2015 HWRF +!! For high winds, try to retain the Ck-U10 relationship of FY2015 HWRF !! To be compatible with the slightly decreased Cd for higher wind speed -!! +!! !!\author Bin Liu, NOAA/NCEP/EMC 2018 ! -! uref(m/s) : wind speed at 10-m height +! uref(m/s) : wind speed at 10-m height ! znott(meter): scalar roughness scale over water ! - REAL, INTENT(IN) :: uref - REAL, INTENT(OUT):: znott + REAL(kind=kind_phys), INTENT(IN) :: uref + REAL(kind=kind_phys), INTENT(OUT):: znott - real, parameter :: p00 = 1.100000000000000e-04, & + REAL(kind=kind_phys), PARAMETER :: p00 = 1.100000000000000e-04,& & p15 = -9.193764479895316e-10, p14 = 7.052217518653943e-08,& & p13 = -2.163419217747114e-06, p12 = 3.342963077911962e-05,& @@ -3024,34 +3054,36 @@ END SUBROUTINE znot_t_v7 !-------------------------------------------------------------------- !>\ingroup mynn_sfc -!> This is taken from Andreas (2002; J. of Hydromet) and +!> This is taken from Andreas (2002; J. of Hydromet) and !! Andreas et al. (2005; BLM). !! !! This should only be used over snow/ice! SUBROUTINE Andreas_2002(Z_0,bvisc,ustar,Zt,Zq) IMPLICIT NONE - REAL, INTENT(IN) :: Z_0, bvisc, ustar - REAL, INTENT(OUT) :: Zt, Zq - REAL :: Ren2, zntsno + REAL(kind=kind_phys), INTENT(IN) :: Z_0, bvisc, ustar + REAL(kind=kind_phys), INTENT(OUT) :: Zt, Zq + REAL(kind=kind_phys) :: Ren2, zntsno - REAL, PARAMETER :: bt0_s=1.25, bt0_t=0.149, bt0_r=0.317, & + REAL(kind=kind_phys), PARAMETER :: & + bt0_s=1.25, bt0_t=0.149, bt0_r=0.317, & bt1_s=0.0, bt1_t=-0.55, bt1_r=-0.565, & bt2_s=0.0, bt2_t=0.0, bt2_r=-0.183 - REAL, PARAMETER :: bq0_s=1.61, bq0_t=0.351, bq0_r=0.396, & + REAL(kind=kind_phys), PARAMETER :: & + bq0_s=1.61, bq0_t=0.351, bq0_r=0.396, & bq1_s=0.0, bq1_t=-0.628, bq1_r=-0.512, & bq2_s=0.0, bq2_t=0.0, bq2_r=-0.180 - !Calculate zo for snow (Andreas et al. 2005, BLM) + !Calculate zo for snow (Andreas et al. 2005, BLM) zntsno = 0.135*bvisc/ustar + & (0.035*(ustar*ustar)/9.8) * & - (5.*exp(-1.*(((ustar - 0.18)/0.1)*((ustar - 0.18)/0.1))) + 1.) + (5.*exp(-1.*(((ustar - 0.18)/0.1)*((ustar - 0.18)/0.1))) + 1.) Ren2 = ustar*zntsno/bvisc ! Make sure that Re is not outside of the range of validity ! for using their equations - IF (Ren2 .gt. 1000.) Ren2 = 1000. + IF (Ren2 .gt. 1000.) Ren2 = 1000. IF (Ren2 .le. 0.135) then @@ -3080,18 +3112,18 @@ END SUBROUTINE Andreas_2002 SUBROUTINE PSI_Hogstrom_1996(psi_m, psi_h, zL, Zt, Z_0, Za) IMPLICIT NONE - REAL, INTENT(IN) :: zL, Zt, Z_0, Za - REAL, INTENT(OUT) :: psi_m, psi_h - REAL :: x, x0, y, y0, zmL, zhL + REAL(kind=kind_phys), INTENT(IN) :: zL, Zt, Z_0, Za + REAL(kind=kind_phys), INTENT(OUT) :: psi_m, psi_h + REAL(kind=kind_phys) :: x, x0, y, y0, zmL, zhL - zmL = Z_0*zL/Za + zmL = Z_0*zL/Za zhL = Zt*zL/Za IF (zL .gt. 0.) THEN !STABLE (not well tested - seem large) psi_m = -5.3*(zL - zmL) psi_h = -8.0*(zL - zhL) - + ELSE !UNSTABLE x = (1.-19.0*zL)**0.25 @@ -3105,7 +3137,7 @@ SUBROUTINE PSI_Hogstrom_1996(psi_m, psi_h, zL, Zt, Z_0, Za) psi_h = 2.*LOG((1.+y)/(1.+y0)) ENDIF - + return END SUBROUTINE PSI_Hogstrom_1996 @@ -3118,9 +3150,9 @@ END SUBROUTINE PSI_Hogstrom_1996 SUBROUTINE PSI_DyerHicks(psi_m, psi_h, zL, Zt, Z_0, Za) IMPLICIT NONE - REAL, INTENT(IN) :: zL, Zt, Z_0, Za - REAL, INTENT(OUT) :: psi_m, psi_h - REAL :: x, x0, y, y0, zmL, zhL + REAL(kind=kind_phys), INTENT(IN) :: zL, Zt, Z_0, Za + REAL(kind=kind_phys), INTENT(OUT) :: psi_m, psi_h + REAL(kind=kind_phys) :: x, x0, y, y0, zmL, zhL zmL = Z_0*zL/Za !Zo/L zhL = Zt*zL/Za !Zt/L @@ -3129,7 +3161,7 @@ SUBROUTINE PSI_DyerHicks(psi_m, psi_h, zL, Zt, Z_0, Za) psi_m = -5.0*(zL - zmL) psi_h = -5.0*(zL - zhL) - + ELSE !UNSTABLE x = (1.-16.*zL)**0.25 @@ -3139,12 +3171,12 @@ SUBROUTINE PSI_DyerHicks(psi_m, psi_h, zL, Zt, Z_0, Za) y0= (1.-16.*zhL)**0.5 psi_m = 2.*LOG((1.+x)/(1.+x0)) + & - &LOG((1.+x**2.)/(1.+x0**2.)) - & + &LOG((1.+x**2.)/(1.+x0**2.)) - & &2.0*ATAN(x) + 2.0*ATAN(x0) psi_h = 2.*LOG((1.+y)/(1.+y0)) ENDIF - + return END SUBROUTINE PSI_DyerHicks @@ -3156,9 +3188,9 @@ END SUBROUTINE PSI_DyerHicks SUBROUTINE PSI_Beljaars_Holtslag_1991(psi_m, psi_h, zL) IMPLICIT NONE - REAL, INTENT(IN) :: zL - REAL, INTENT(OUT) :: psi_m, psi_h - REAL, PARAMETER :: a=1., b=0.666, c=5., d=0.35 + REAL(kind=kind_phys), INTENT(IN) :: zL + REAL(kind=kind_phys), INTENT(OUT) :: psi_m, psi_h + REAL(kind=kind_phys), PARAMETER :: a=1., b=0.666, c=5., d=0.35 IF (zL .lt. 0.) THEN !UNSTABLE @@ -3167,7 +3199,7 @@ SUBROUTINE PSI_Beljaars_Holtslag_1991(psi_m, psi_h, zL) WRITE(*,*)" be used in the stable regime!" psi_m = 0. psi_h = 0. - + ELSE !STABLE psi_m = -(a*zL + b*(zL -(c/d))*exp(-d*zL) + (b*c/d)) @@ -3175,7 +3207,7 @@ SUBROUTINE PSI_Beljaars_Holtslag_1991(psi_m, psi_h, zL) b*(zL - (c/d))*exp(-d*zL) + (b*c/d) -1.) ENDIF - + return END SUBROUTINE PSI_Beljaars_Holtslag_1991 @@ -3188,9 +3220,9 @@ END SUBROUTINE PSI_Beljaars_Holtslag_1991 SUBROUTINE PSI_Zilitinkevich_Esau_2007(psi_m, psi_h, zL) IMPLICIT NONE - REAL, INTENT(IN) :: zL - REAL, INTENT(OUT) :: psi_m, psi_h - REAL, PARAMETER :: Cm=3.0, Ct=2.5 + REAL(kind=kind_phys), INTENT(IN) :: zL + REAL(kind=kind_phys), INTENT(OUT) :: psi_m, psi_h + REAL(kind=kind_phys), PARAMETER :: Cm=3.0, Ct=2.5 IF (zL .lt. 0.) THEN !UNSTABLE @@ -3199,14 +3231,14 @@ SUBROUTINE PSI_Zilitinkevich_Esau_2007(psi_m, psi_h, zL) WRITE(*,*)" be used in the stable regime!" psi_m = 0. psi_h = 0. - + ELSE !STABLE psi_m = -Cm*(zL**(5./6.)) psi_h = -Ct*(zL**(4./5.)) ENDIF - + return END SUBROUTINE PSI_Zilitinkevich_Esau_2007 @@ -3217,10 +3249,10 @@ END SUBROUTINE PSI_Zilitinkevich_Esau_2007 SUBROUTINE PSI_Businger_1971(psi_m, psi_h, zL) IMPLICIT NONE - REAL, INTENT(IN) :: zL - REAL, INTENT(OUT) :: psi_m, psi_h - REAL :: x, y - REAL, PARAMETER :: Pi180 = 3.14159265/180. + REAL(kind=kind_phys), INTENT(IN) :: zL + REAL(kind=kind_phys), INTENT(OUT) :: psi_m, psi_h + REAL(kind=kind_phys) :: x, y + REAL(kind=kind_phys), PARAMETER :: Pi180 = 3.14159265/180. IF (zL .lt. 0.) THEN !UNSTABLE @@ -3238,7 +3270,7 @@ SUBROUTINE PSI_Businger_1971(psi_m, psi_h, zL) psi_h = -(4.7/0.74)*zL ENDIF - + return END SUBROUTINE PSI_Businger_1971 @@ -3253,9 +3285,9 @@ END SUBROUTINE PSI_Businger_1971 SUBROUTINE PSI_Suselj_Sood_2010(psi_m, psi_h, zL) IMPLICIT NONE - REAL, INTENT(IN) :: zL - REAL, INTENT(OUT) :: psi_m, psi_h - REAL, PARAMETER :: Rfc=0.19, Ric=0.183, PHIT=0.8 + REAL(kind=kind_phys), INTENT(IN) :: zL + REAL(kind=kind_phys), INTENT(OUT) :: psi_m, psi_h + REAL(kind=kind_phys), PARAMETER :: Rfc=0.19, Ric=0.183, PHIT=0.8 IF (zL .gt. 0.) THEN !STABLE @@ -3264,14 +3296,14 @@ SUBROUTINE PSI_Suselj_Sood_2010(psi_m, psi_h, zL) !THEIR EQ FOR PSI_H CRASHES THE MODEL AND DOES NOT MATCH !THEIR FIG 1. THIS EQ (BELOW) MATCHES THEIR FIG 1 BETTER: psi_h = -(zL*Ric/((Rfc**2.)*5.) + 7.09*(zL**1.1091)) - + ELSE !UNSTABLE psi_m = 0.9904*LOG(1. - 14.264*zL) psi_h = 1.0103*LOG(1. - 16.3066*zL) ENDIF - + return END SUBROUTINE PSI_Suselj_Sood_2010 @@ -3283,8 +3315,8 @@ END SUBROUTINE PSI_Suselj_Sood_2010 SUBROUTINE PSI_CB2005(psim1,psih1,zL,z0L) IMPLICIT NONE - REAL, INTENT(IN) :: zL,z0L - REAL, INTENT(OUT) :: psim1,psih1 + REAL(kind=kind_phys), INTENT(IN) :: zL,z0L + REAL(kind=kind_phys), INTENT(OUT) :: psim1,psih1 psim1 = -6.1*LOG(zL + (1.+ zL**2.5)**0.4) & -6.1*LOG(z0L + (1.+ z0L**2.5)**0.4) @@ -3302,18 +3334,21 @@ END SUBROUTINE PSI_CB2005 SUBROUTINE Li_etal_2010(zL, Rib, zaz0, z0zt) IMPLICIT NONE - REAL, INTENT(OUT) :: zL - REAL, INTENT(IN) :: Rib, zaz0, z0zt - REAL :: alfa, beta, zaz02, z0zt2 - REAL, PARAMETER :: au11=0.045, bu11=0.003, bu12=0.0059, & - &bu21=-0.0828, bu22=0.8845, bu31=0.1739, & - &bu32=-0.9213, bu33=-0.1057 - REAL, PARAMETER :: aw11=0.5738, aw12=-0.4399, aw21=-4.901,& - &aw22=52.50, bw11=-0.0539, bw12=1.540, & - &bw21=-0.669, bw22=-3.282 - REAL, PARAMETER :: as11=0.7529, as21=14.94, bs11=0.1569,& - &bs21=-0.3091, bs22=-1.303 - + REAL(kind=kind_phys), INTENT(OUT) :: zL + REAL(kind=kind_phys), INTENT(IN) :: Rib, zaz0, z0zt + REAL(kind=kind_phys) :: alfa, beta, zaz02, z0zt2 + REAL(kind=kind_phys), PARAMETER :: & + & au11=0.045, bu11=0.003, bu12=0.0059, & + & bu21=-0.0828, bu22=0.8845, bu31=0.1739, & + & bu32=-0.9213, bu33=-0.1057 + REAL(kind=kind_phys), PARAMETER :: & + & aw11=0.5738, aw12=-0.4399, aw21=-4.901, & + & aw22=52.50, bw11=-0.0539, bw12=1.540, & + & bw21=-0.669, bw22=-3.282 + REAL(kind=kind_phys), PARAMETER :: & + & as11=0.7529, as21=14.94, bs11=0.1569, & + & bs21=-0.3091, bs22=-1.303 + !set limits according to Li et al (2010), p 157. zaz02=zaz0 IF (zaz0 .lt. 100.0) zaz02=100. @@ -3333,23 +3368,23 @@ SUBROUTINE Li_etal_2010(zL, Rib, zaz0, z0zt) & (bu21*beta + bu22)*alfa + & & (bu31*beta**2 + bu32*beta + bu33))*Rib !if(zL .LT. -15 .OR. zl .GT. 0.)print*,"VIOLATION Rib<0:",zL - zL = MAX(zL,-15.) !LIMITS SET ACCORDING TO Li et al (2010) - zL = MIN(zL,0.) !Figure 1. + zL = MAX(zL,-15._kind_phys) !LIMITS SET ACCORDING TO Li et al (2010) + zL = MIN(zL,0._kind_phys) !Figure 1. ELSEIF (Rib .gt. 0.0 .AND. Rib .le. 0.2) THEN zL = ((aw11*beta + aw12)*alfa + & & (aw21*beta + aw22))*Rib**2 + & & ((bw11*beta + bw12)*alfa + & & (bw21*beta + bw22))*Rib !if(zL .LT. 0 .OR. zl .GT. 4)print*,"VIOLATION 00.2:",zL - zL = MIN(zL,20.) !LIMITS ACCORDING TO Li et al (2010), THIER + zL = MIN(zL,20._kind_phys) !LIMITS ACCORDING TO Li et al (2010), THIER !FIGUE 1C. - zL = MAX(zL,1.) + zL = MAX(zL,1._kind_phys) ENDIF return @@ -3357,21 +3392,21 @@ SUBROUTINE Li_etal_2010(zL, Rib, zaz0, z0zt) END SUBROUTINE Li_etal_2010 !------------------------------------------------------------------- !>\ingroup mynn_sfc - REAL function zolri(ri,za,z0,zt,zol1,psi_opt) + REAL(kind=kind_phys) function zolri(ri,za,z0,zt,zol1,psi_opt) - !> This iterative algorithm was taken from the revised surface layer - !! scheme in WRF-ARW, written by Pedro Jimenez and Jimy Dudhia and + !> This iterative algorithm was taken from the revised surface layer + !! scheme in WRF-ARW, written by Pedro Jimenez and Jimy Dudhia and !! summarized in Jimenez et al. (2012, MWR). This function was adapted !! to input the thermal roughness length, zt, (as well as z0) and use initial !! estimate of z/L. IMPLICIT NONE - REAL, INTENT(IN) :: ri,za,z0,zt,zol1 + REAL(kind=kind_phys), INTENT(IN) :: ri,za,z0,zt,zol1 INTEGER, INTENT(IN) :: psi_opt - REAL :: x1,x2,fx1,fx2 + REAL(kind=kind_phys) :: x1,x2,fx1,fx2 INTEGER :: n INTEGER, PARAMETER :: nmax = 20 - !REAL, DIMENSION(nmax):: zLhux + !REAL(kind=kind_phys), DIMENSION(nmax):: zLhux if (ri.lt.0.)then x1=zol1 - 0.02 !-5. @@ -3412,7 +3447,7 @@ REAL function zolri(ri,za,z0,zt,zol1,psi_opt) return end function !------------------------------------------------------------------- - REAL function zolri2(zol2,ri2,za,z0,zt,psi_opt) + REAL(kind=kind_phys) function zolri2(zol2,ri2,za,z0,zt,psi_opt) ! INPUT: ================================= ! zol2 - estimated z/L @@ -3425,9 +3460,9 @@ REAL function zolri2(zol2,ri2,za,z0,zt,psi_opt) IMPLICIT NONE INTEGER, INTENT(IN) :: psi_opt - REAL, INTENT(IN) :: ri2,za,z0,zt - REAL, INTENT(INOUT) :: zol2 - REAL :: zol20,zol3,psim1,psih1,psix2,psit2,zolt + REAL(kind=kind_phys), INTENT(IN) :: ri2,za,z0,zt + REAL(kind=kind_phys), INTENT(INOUT) :: zol2 + REAL(kind=kind_phys) :: zol20,zol3,psim1,psih1,psix2,psit2,zolt if(zol2*ri2 .lt. 0.)zol2=0. ! limit zol2 - must be same sign as ri2 @@ -3438,13 +3473,13 @@ REAL function zolri2(zol2,ri2,za,z0,zt,psi_opt) if (ri2.lt.0) then !psix2=log((za+z0)/z0)-(psim_unstable(zol3)-psim_unstable(zol20)) !psit2=log((za+zt)/zt)-(psih_unstable(zol3)-psih_unstable(zol20)) - psit2=MAX(log((za+z0)/zt)-(psih_unstable(zol3,psi_opt)-psih_unstable(zolt,psi_opt)), 1.0) - psix2=MAX(log((za+z0)/z0)-(psim_unstable(zol3,psi_opt)-psim_unstable(zol20,psi_opt)),1.0) + psit2=MAX(log((za+z0)/zt)-(psih_unstable(zol3,psi_opt)-psih_unstable(zolt,psi_opt)), 1.0_kind_phys) + psix2=MAX(log((za+z0)/z0)-(psim_unstable(zol3,psi_opt)-psim_unstable(zol20,psi_opt)), 1.0_kind_phys) else !psix2=log((za+z0)/z0)-(psim_stable(zol3)-psim_stable(zol20)) !psit2=log((za+zt)/zt)-(psih_stable(zol3)-psih_stable(zol20)) - psit2=MAX(log((za+z0)/zt)-(psih_stable(zol3,psi_opt)-psih_stable(zolt,psi_opt)), 1.0) - psix2=MAX(log((za+z0)/z0)-(psim_stable(zol3,psi_opt)-psim_stable(zol20,psi_opt)),1.0) + psit2=MAX(log((za+z0)/zt)-(psih_stable(zol3,psi_opt)-psih_stable(zolt,psi_opt)), 1.0_kind_phys) + psix2=MAX(log((za+z0)/z0)-(psim_stable(zol3,psi_opt)-psim_stable(zol20,psi_opt)),1.0_kind_phys) endif zolri2=zol2*psit2/psix2**2 - ri2 @@ -3454,19 +3489,19 @@ REAL function zolri2(zol2,ri2,za,z0,zt,psi_opt) end function !==================================================================== - REAL function zolrib(ri,za,z0,zt,logz0,logzt,zol1,psi_opt) + REAL(kind=kind_phys) function zolrib(ri,za,z0,zt,logz0,logzt,zol1,psi_opt) ! This iterative algorithm to compute z/L from bulk-Ri IMPLICIT NONE - REAL, INTENT(IN) :: ri,za,z0,zt,logz0,logzt + REAL(kind=kind_phys), INTENT(IN) :: ri,za,z0,zt,logz0,logzt INTEGER, INTENT(IN) :: psi_opt - REAL, INTENT(INOUT) :: zol1 - REAL :: zol20,zol3,zolt,zolold + REAL(kind=kind_phys), INTENT(INOUT) :: zol1 + REAL(kind=kind_phys) :: zol20,zol3,zolt,zolold INTEGER :: n INTEGER, PARAMETER :: nmax = 20 - REAL, DIMENSION(nmax):: zLhux - REAL :: psit2,psix2 + REAL(kind=kind_phys), DIMENSION(nmax):: zLhux + REAL(kind=kind_phys) :: psit2,psix2 !print*,"+++++++INCOMING: z/L=",zol1," ri=",ri if (zol1*ri .lt. 0.) THEN @@ -3497,13 +3532,13 @@ REAL function zolrib(ri,za,z0,zt,logz0,logzt,zol1,psi_opt) if (ri.lt.0) then !psit2=log((za+zt)/zt)-(psih_unstable(zol3)-psih_unstable(zol20)) !psit2=log((za+z0)/zt)-(psih_unstable(zol3)-psih_unstable(zol20)) - psit2=MAX(logzt-(psih_unstable(zol3,psi_opt)-psih_unstable(zolt,psi_opt)), 1.0) - psix2=MAX(logz0-(psim_unstable(zol3,psi_opt)-psim_unstable(zol20,psi_opt)), 1.0) + psit2=MAX(logzt-(psih_unstable(zol3,psi_opt)-psih_unstable(zolt,psi_opt)), 1.0_kind_phys) + psix2=MAX(logz0-(psim_unstable(zol3,psi_opt)-psim_unstable(zol20,psi_opt)), 1.0_kind_phys) else !psit2=log((za+zt)/zt)-(psih_stable(zol3)-psih_stable(zol20)) !psit2=log((za+z0)/zt)-(psih_stable(zol3)-psih_stable(zol20)) - psit2=MAX(logzt-(psih_stable(zol3,psi_opt)-psih_stable(zolt,psi_opt)), 1.0) - psix2=MAX(logz0-(psim_stable(zol3,psi_opt)-psim_stable(zol20,psi_opt)), 1.0) + psit2=MAX(logzt-(psih_stable(zol3,psi_opt)-psih_stable(zolt,psi_opt)), 1.0_kind_phys) + psix2=MAX(logz0-(psim_stable(zol3,psi_opt)-psim_stable(zol20,psi_opt)), 1.0_kind_phys) endif !print*,"n=",n," psit2=",psit2," psix2=",psix2 zolrib=ri*psix2**2/psit2 @@ -3534,7 +3569,7 @@ REAL function zolrib(ri,za,z0,zt,logz0,logzt,zol1,psi_opt) SUBROUTINE psi_init(psi_opt,errmsg,errflg) integer :: N,psi_opt - real :: zolf + real(kind=kind_phys) :: zolf character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -3565,7 +3600,7 @@ SUBROUTINE psi_init(psi_opt,errmsg,errflg) endif !Simple test to see if initialization worked: - if (psim_stab(1) < 0. .AND. psih_stab(1) < 0. .AND. & + if (psim_stab(1) < 0. .AND. psih_stab(1) < 0. .AND. & psim_unstab(1) > 0. .AND. psih_unstab(1) > 0.) then errmsg = 'In MYNN SFC, Psi tables have been initialized' errflg = 0 @@ -3579,18 +3614,18 @@ END SUBROUTINE psi_init ! ... integrated similarity functions from MYNN... ! !>\ingroup mynn_sfc - REAL function psim_stable_full(zolf) - REAL :: zolf + REAL(kind=kind_phys) function psim_stable_full(zolf) + REAL(kind=kind_phys) :: zolf !psim_stable_full=-6.1*log(zolf+(1+zolf**2.5)**(1./2.5)) - psim_stable_full=-6.1*log(zolf+(1+zolf**2.5)**0.4) + psim_stable_full=-6.1*log(zolf+(1+zolf**2.5)**0.4) return end function !>\ingroup mynn_sfc - REAL function psih_stable_full(zolf) - REAL :: zolf + REAL(kind=kind_phys) function psih_stable_full(zolf) + REAL(kind=kind_phys) :: zolf !psih_stable_full=-5.3*log(zolf+(1+zolf**1.1)**(1./1.1)) psih_stable_full=-5.3*log(zolf+(1+zolf**1.1)**0.9090909090909090909) @@ -3599,12 +3634,13 @@ REAL function psih_stable_full(zolf) end function !>\ingroup mynn_sfc - REAL function psim_unstable_full(zolf) - REAL :: zolf,x,ym,psimc,psimk + REAL(kind=kind_phys) function psim_unstable_full(zolf) + REAL(kind=kind_phys) :: zolf,x,ym,psimc,psimk x=(1.-16.*zolf)**.25 !psimk=2*ALOG(0.5*(1+X))+ALOG(0.5*(1+X*X))-2.*ATAN(X)+2.*ATAN(1.) - psimk=2.*ALOG(0.5*(1+X))+ALOG(0.5*(1+X*X))-2.*ATAN(X)+2.*atan1 + !psimk=2.*ALOG(0.5*(1+X))+ALOG(0.5*(1+X*X))-2.*ATAN(X)+2.*atan1 + psimk=2.*LOG(0.5*(1+X))+LOG(0.5*(1+X*X))-2.*ATAN(X)+2.*atan1 ym=(1.-10.*zolf)**onethird !psimc=(3./2.)*log((ym**2.+ym+1.)/3.)-sqrt(3.)*ATAN((2.*ym+1)/sqrt(3.))+4.*ATAN(1.)/sqrt(3.) @@ -3616,8 +3652,8 @@ REAL function psim_unstable_full(zolf) end function !>\ingroup mynn_sfc - REAL function psih_unstable_full(zolf) - REAL :: zolf,y,yh,psihc,psihk + REAL(kind=kind_phys) function psih_unstable_full(zolf) + REAL(kind=kind_phys) :: zolf,y,yh,psihc,psihk y=(1.-16.*zolf)**.5 !psihk=2.*log((1+y)/2.) @@ -3637,10 +3673,10 @@ REAL function psih_unstable_full(zolf) ! !>\ingroup mynn_sfc !! - REAL function psim_stable_full_gfs(zolf) - REAL :: zolf - REAL, PARAMETER :: alpha4 = 20. - REAL :: aa + REAL(kind=kind_phys) function psim_stable_full_gfs(zolf) + REAL(kind=kind_phys) :: zolf + REAL(kind=kind_phys), PARAMETER :: alpha4 = 20. + REAL(kind=kind_phys) :: aa aa = sqrt(1. + alpha4 * zolf) psim_stable_full_gfs = -1.*aa + log(aa + 1.) @@ -3650,10 +3686,10 @@ REAL function psim_stable_full_gfs(zolf) !>\ingroup mynn_sfc !! - REAL function psih_stable_full_gfs(zolf) - REAL :: zolf - REAL, PARAMETER :: alpha4 = 20. - REAL :: bb + REAL(kind=kind_phys) function psih_stable_full_gfs(zolf) + REAL(kind=kind_phys) :: zolf + REAL(kind=kind_phys), PARAMETER :: alpha4 = 20. + REAL(kind=kind_phys) :: bb bb = sqrt(1. + alpha4 * zolf) psih_stable_full_gfs = -1.*bb + log(bb + 1.) @@ -3663,10 +3699,10 @@ REAL function psih_stable_full_gfs(zolf) !>\ingroup mynn_sfc !! - REAL function psim_unstable_full_gfs(zolf) - REAL :: zolf - REAL :: hl1,tem1 - REAL, PARAMETER :: a0=-3.975, a1=12.32, & + REAL(kind=kind_phys) function psim_unstable_full_gfs(zolf) + REAL(kind=kind_phys) :: zolf + REAL(kind=kind_phys) :: hl1,tem1 + REAL(kind=kind_phys), PARAMETER :: a0=-3.975, a1=12.32, & b1=-7.755, b2=6.041 if (zolf .ge. -0.5) then @@ -3683,10 +3719,10 @@ REAL function psim_unstable_full_gfs(zolf) !>\ingroup mynn_sfc !! - REAL function psih_unstable_full_gfs(zolf) - REAL :: zolf - REAL :: hl1,tem1 - REAL, PARAMETER :: a0p=-7.941, a1p=24.75, & + REAL(kind=kind_phys) function psih_unstable_full_gfs(zolf) + REAL(kind=kind_phys) :: zolf + REAL(kind=kind_phys) :: hl1,tem1 + REAL(kind=kind_phys), PARAMETER :: a0p=-7.941, a1p=24.75, & b1p=-8.705, b2p=7.899 if (zolf .ge. -0.5) then @@ -3703,9 +3739,9 @@ REAL function psih_unstable_full_gfs(zolf) !>\ingroup mynn_sfc !! look-up table functions - or, if beyond -10 < z/L < 10, recalculate - REAL function psim_stable(zolf,psi_opt) + REAL(kind=kind_phys) function psim_stable(zolf,psi_opt) integer :: nzol,psi_opt - real :: rzol,zolf + real(kind=kind_phys) :: rzol,zolf nzol = int(zolf*100.) rzol = zolf*100. - nzol @@ -3723,9 +3759,9 @@ REAL function psim_stable(zolf,psi_opt) end function !>\ingroup mynn_sfc - REAL function psih_stable(zolf,psi_opt) + REAL(kind=kind_phys) function psih_stable(zolf,psi_opt) integer :: nzol,psi_opt - real :: rzol,zolf + real(kind=kind_phys) :: rzol,zolf nzol = int(zolf*100.) rzol = zolf*100. - nzol @@ -3743,9 +3779,9 @@ REAL function psih_stable(zolf,psi_opt) end function !>\ingroup mynn_sfc - REAL function psim_unstable(zolf,psi_opt) + REAL(kind=kind_phys) function psim_unstable(zolf,psi_opt) integer :: nzol,psi_opt - real :: rzol,zolf + real(kind=kind_phys) :: rzol,zolf nzol = int(-zolf*100.) rzol = -zolf*100. - nzol @@ -3763,9 +3799,9 @@ REAL function psim_unstable(zolf,psi_opt) end function !>\ingroup mynn_sfc - REAL function psih_unstable(zolf,psi_opt) + REAL(kind=kind_phys) function psih_unstable(zolf,psi_opt) integer :: nzol,psi_opt - real :: rzol,zolf + real(kind=kind_phys) :: rzol,zolf nzol = int(-zolf*100.) rzol = -zolf*100. - nzol diff --git a/physics/module_sf_noahmp_glacier.f90 b/physics/module_sf_noahmp_glacier.F90 similarity index 99% rename from physics/module_sf_noahmp_glacier.f90 rename to physics/module_sf_noahmp_glacier.F90 index 738a40b5c..bd6b016f1 100644 --- a/physics/module_sf_noahmp_glacier.f90 +++ b/physics/module_sf_noahmp_glacier.F90 @@ -1,5 +1,5 @@ #define CCPP -!> \file module_sf_noahmp_glacier.f90 +!> \file module_sf_noahmp_glacier.F90 !! This file contains the NoahMP Glacier scheme. !>\ingroup NoahMP_LSM diff --git a/physics/module_sf_noahmplsm.f90 b/physics/module_sf_noahmplsm.F90 similarity index 99% rename from physics/module_sf_noahmplsm.f90 rename to physics/module_sf_noahmplsm.F90 index 1da30f156..7807ee475 100644 --- a/physics/module_sf_noahmplsm.f90 +++ b/physics/module_sf_noahmplsm.F90 @@ -1,5 +1,5 @@ #define CCPP -!> \file module_sf_noahmplsm.f90 +!> \file module_sf_noahmplsm.F90 !! This file contains the NoahMP land surface model. !>\ingroup NoahMP_LSM @@ -218,6 +218,7 @@ module module_sf_noahmplsm real (kind=kind_phys) :: saim(12) !< monthly stem area index, one-sided real (kind=kind_phys) :: laim(12) !< monthly leaf area index, one-sided real (kind=kind_phys) :: sla !< single-side leaf area per kg [m2/kg] + real (kind=kind_phys) :: prcpiceden !< precipitation ice density [kg/m^3] real (kind=kind_phys) :: dilefc !< coeficient for leaf stress death [1/s] real (kind=kind_phys) :: dilefw !< coeficient for leaf stress death [1/s] real (kind=kind_phys) :: fragr !< fraction of growth respiration !original was 0.3 @@ -1068,13 +1069,14 @@ subroutine atm (parameters,sfcprs ,sfctmp ,q2 , ! fresh snow density bdfall = min(120.,67.92+51.25*exp((sfctmp-tfrz)/2.59)) !mb/an: change to min - if(opt_snf == 4) then + if(opt_snf == 4 .or. opt_snf == 5) then prcp_frozen = prcpsnow + prcpgrpl + prcphail if(prcpnonc > 0. .and. prcp_frozen > 0.) then fpice = min(1.0,prcp_frozen/prcpnonc) fpice = max(0.0,fpice) - bdfall = bdfall*(prcpsnow/prcp_frozen) + rho_grpl*(prcpgrpl/prcp_frozen) + & - rho_hail*(prcphail/prcp_frozen) + if(opt_snf==4) bdfall = bdfall*(prcpsnow/prcp_frozen) + rho_grpl*(prcpgrpl/prcp_frozen) + & + rho_hail*(prcphail/prcp_frozen) + if(opt_snf==5) bdfall = parameters%prcpiceden else fpice = 0.0 endif diff --git a/physics/module_sf_ruclsm.F90 b/physics/module_sf_ruclsm.F90 index 9a6363c08..3090c0c11 100644 --- a/physics/module_sf_ruclsm.F90 +++ b/physics/module_sf_ruclsm.F90 @@ -54,11 +54,11 @@ SUBROUTINE LSMRUC( & DT,init,lsm_cold_start,KTAU,iter,NSL, & graupelncv,snowncv,rainncv,raincv, & ZS,RAINBL,SNOW,SNOWH,SNOWC,FRZFRAC,frpcpn, & - rhosnf,precipfr, & + rhosnf,precipfr,exticeden, & Z3D,P8W,T3D,QV3D,QC3D,RHO3D,EMISBCK, & GLW,GSWdn,GSW,EMISS,CHKLOWQ, CHS, & - FLQC,FLHC,MAVAIL,CANWAT,VEGFRA,ALB,ZNT, & - Z0,SNOALB,ALBBCK,LAI, & + FLQC,FLHC,rhonewsn_ex,MAVAIL,CANWAT,VEGFRA, & + ALB, ZNT,Z0,SNOALB,ALBBCK,LAI, & landusef, nlcat, & ! mosaic_lu, mosaic_soil, & soilctop, nscat, & QSFC,QSG,QVG,QCG,DEW,SOILT1,TSNAV, & @@ -72,7 +72,8 @@ SUBROUTINE LSMRUC( & SMFR3D,KEEPFR3DFLAG, & myj,shdmin,shdmax,rdlai2d, & ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) + its,ite, jts,jte, kts,kte, & + errmsg, errflg) !----------------------------------------------------------------- IMPLICIT NONE !----------------------------------------------------------------- @@ -157,7 +158,7 @@ SUBROUTINE LSMRUC( & ! INTEGER, PARAMETER :: nddzs=2*(nzss-2) REAL, INTENT(IN ) :: DT - LOGICAL, INTENT(IN ) :: myj,frpcpn,init,lsm_cold_start + LOGICAL, INTENT(IN ) :: myj,frpcpn,init,lsm_cold_start,exticeden INTEGER, INTENT(IN ) :: NLCAT, NSCAT ! , mosaic_lu, mosaic_soil INTEGER, INTENT(IN ) :: ktau, iter, nsl, isice, iswater, & ims,ime, jms,jme, kms,kme, & @@ -191,7 +192,8 @@ SUBROUTINE LSMRUC( & INTENT(IN ) :: GRAUPELNCV, & SNOWNCV, & RAINCV, & - RAINNCV + RAINNCV, & + RHONEWSN_ex !externally-calculated srf frz precip density ! REAL, DIMENSION( ims:ime , jms:jme ), & ! INTENT(IN ) :: lakemask ! INTEGER, INTENT(IN ) :: LakeModel @@ -325,7 +327,6 @@ SUBROUTINE LSMRUC( & KICE, & KWT - REAL, DIMENSION(1:NSL) :: ZSMAIN, & ZSHALF, & DTDZS2 @@ -381,9 +382,14 @@ SUBROUTINE LSMRUC( & INTEGER :: I,J,K,NZS,NZS1,NDDZS INTEGER :: k1,k2 logical :: debug_print - + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg !----------------------------------------------------------------- ! + ! Initialize error-handling + errflg = 0 + errmsg = '' + debug_print = .false. ! rovcp = rd/cp @@ -704,7 +710,7 @@ SUBROUTINE LSMRUC( & soilfrac,nscat,shdmin(i,j),shdmax(i,j),mosaic_lu, mosaic_soil,& NLCAT,ILAND,ISOIL,iswater,MYJ,IFOREST,lufrac,VEGFRA(I,J), & EMISSL(I,J),PC(I,J),ZNT(I,J),LAI(I,J),RDLAI2D, & - QWRTZ,RHOCS,BCLH,DQM,KSAT,PSIS,QMIN,REF,WILT,i,j ) + QWRTZ,RHOCS,BCLH,DQM,KSAT,PSIS,QMIN,REF,WILT,i,j,errmsg, errflg) !-- update background emissivity for land points, can have vegetation mosaic effect EMISBCK(I,J) = EMISSL(I,J) @@ -895,8 +901,8 @@ SUBROUTINE LSMRUC( & nzs,nddzs,nroot,meltfactor, & !added meltfactor iland,isoil,ivgtyp(i,j),isltyp(i,j), & PRCPMS, NEWSNMS,SNWE,SNHEI,SNOWFRAC, & - RHOSN,RHONEWSN,RHOSNFALL, & - snowrat,grauprat,icerat,curat, & + exticeden,RHOSN,RHONEWSN_ex(I,J),RHONEWSN, & + RHOSNFALL,snowrat,grauprat,icerat,curat, & PATM,TABS,QVATM,QCATM,RHO, & GLW(I,J),GSWdn(i,j),GSW(I,J), & EMISSL(I,J),EMISBCK(I,J), & @@ -1162,7 +1168,7 @@ SUBROUTINE SFCTMP (debug_print, delt,ktau,conflx,i,j, & !--- input varia nzs,nddzs,nroot,meltfactor, & ILAND,ISOIL,IVGTYP,ISLTYP,PRCPMS, & NEWSNMS,SNWE,SNHEI,SNOWFRAC, & - RHOSN,RHONEWSN,RHOSNFALL, & + exticeden,RHOSN,RHONEWSN_ex,RHONEWSN,RHOSNFALL, & snowrat,grauprat,icerat,curat, & PATM,TABS,QVATM,QCATM,rho, & GLW,GSWdn,GSW,EMISS,EMISBCK,QKMS,TKMS,PC, & @@ -1190,8 +1196,8 @@ SUBROUTINE SFCTMP (debug_print, delt,ktau,conflx,i,j, & !--- input varia nddzs !nddzs=2*(nzs-2) REAL, INTENT(IN ) :: DELT,CONFLX,meltfactor - REAL, INTENT(IN ) :: C1SN,C2SN - LOGICAL, INTENT(IN ) :: myj, debug_print + REAL, INTENT(IN ) :: C1SN,C2SN,RHONEWSN_ex + LOGICAL, INTENT(IN ) :: myj, debug_print, exticeden !--- 3-D Atmospheric variables REAL , & INTENT(IN ) :: PATM, & @@ -1281,9 +1287,9 @@ SUBROUTINE SFCTMP (debug_print, delt,ktau,conflx,i,j, & !--- input varia EETA, & EVAPL, & INFILTR, & - RHOSN, & + RHOSN, & RHONEWSN, & - rhosnfall, & + rhosnfall, & snowrat, & grauprat, & icerat, & @@ -1494,19 +1500,22 @@ SUBROUTINE SFCTMP (debug_print, delt,ktau,conflx,i,j, & !--- input varia !--- 27 Feb 2014 - empirical formulations from John M. Brown ! rhonewsn=min(250.,rhowater/max(4.179,(13.*tanh((274.15-Tabs)*0.3333)))) !--- 13 Mar 2018 - formulation from Trevor Elcott + if (exticeden) then + rhonewsn = rhonewsn_ex + else rhonewsn=min(125.,1000.0/max(8.,(17.*tanh((276.65-Tabs)*0.15)))) rhonewgr=min(500.,rhowater/max(2.,(3.5*tanh((274.15-Tabs)*0.3333)))) rhonewice=rhonewsn - !--- compute density of "snowfall" from weighted contribution ! of snow, graupel and ice fractions - rhosnfall = min(500.,max(58.8,(rhonewsn*snowrat + & + rhosnfall = min(500.,max(58.8,(rhonewsn*snowrat + & !13mar18 rhosnfall = min(500.,max(76.9,(rhonewsn*snowrat + & rhonewgr*grauprat + rhonewice*icerat + rhonewgr*curat))) ! from now on rhonewsn is the density of falling frozen precipitation - rhonewsn=rhosnfall + rhonewsn=rhosnfall + end if !*** Define average snow density of the snow pack considering !*** the amount of fresh snow (eq. 9 in Koren et al.(1999) @@ -6547,7 +6556,8 @@ SUBROUTINE SOILVEGIN ( debug_print, & mosaic_lu, mosaic_soil, & NLCAT,IVGTYP,ISLTYP,iswater,MYJ, & IFOREST,lufrac,vegfrac,EMISS,PC,ZNT,LAI,RDLAI2D,& - QWRTZ,RHOCS,BCLH,DQM,KSAT,PSIS,QMIN,REF,WILT,I,J) + QWRTZ,RHOCS,BCLH,DQM,KSAT,PSIS,QMIN,REF,WILT,I,J,& + errmsg, errflg) !************************************************************************ ! Set-up soil and vegetation Parameters in the case when @@ -6809,7 +6819,8 @@ SUBROUTINE SOILVEGIN ( debug_print, & REF, & WILT INTEGER, INTENT ( OUT) :: iforest - + character(len=*),intent(out) :: errmsg + integer, intent(out) :: errflg ! INTEGER, DIMENSION( 1:(lucats) ) , & ! INTENT ( OUT) :: iforest @@ -6830,7 +6841,11 @@ SUBROUTINE SOILVEGIN ( debug_print, & ! iforest(k)=if1(k) ! enddo - iforest = IFORTBL(IVGTYP) + ! Initialize error-handling + errflg = 0 + errmsg = '' + + iforest = IFORTBL(IVGTYP) IF (debug_print ) THEN print *,'ifortbl(ivgtyp),ivgtyp,laitbl(ivgtyp),z0tbl(ivgtyp)', & @@ -6904,7 +6919,9 @@ SUBROUTINE SOILVEGIN ( debug_print, & if (area.gt.1.) area=1. if (area <= 0.) then print *,'Bad area of grid box', area - stop + errflg = 1 + errmsg = 'ERROR(SOILVEGIN): Bad area of grid box' + return endif IF (debug_print ) THEN diff --git a/physics/mp_nssl.F90 b/physics/mp_nssl.F90 index d6de5a0a0..4e0e323ce 100644 --- a/physics/mp_nssl.F90 +++ b/physics/mp_nssl.F90 @@ -31,6 +31,7 @@ subroutine mp_nssl_init(ncol, nlev, errflg, errmsg, threads, restart, & con_t0c, con_cliq, con_csol, con_eps, & imp_physics, imp_physics_nssl, & nssl_cccn, nssl_alphah, nssl_alphahl, & + nssl_alphar, nssl_ehw0_in, nssl_ehlw0_in, & nssl_ccn_on, nssl_hail_on, nssl_invertccn ) @@ -52,6 +53,7 @@ subroutine mp_nssl_init(ncol, nlev, errflg, errmsg, threads, restart, & integer, intent(in) :: imp_physics integer, intent(in) :: imp_physics_nssl real(kind_phys), intent(in) :: nssl_cccn, nssl_alphah, nssl_alphahl + real(kind_phys), intent(in) :: nssl_alphar, nssl_ehw0_in, nssl_ehlw0_in logical, intent(in) :: nssl_ccn_on, nssl_hail_on, nssl_invertccn ! Local variables: dimensions used in nssl_init @@ -115,6 +117,7 @@ subroutine mp_nssl_init(ncol, nlev, errflg, errmsg, threads, restart, & nssl_params(11) = 0 ! nssl_ipelec_tmp nssl_params(12) = 11 ! nssl_isaund nssl_params(13) = 0 ! 1= turn on cccna; 0 = turn off + nssl_params(14) = nssl_alphar nssl_qccn = nssl_cccn/1.225 ! if (mpirank==mpiroot) then @@ -129,7 +132,7 @@ subroutine mp_nssl_init(ncol, nlev, errflg, errmsg, threads, restart, & ! write(0,*) 'call nssl_2mom_init' CALL nssl_2mom_init(ims,ime, jms,jme, kms,kme,nssl_params,ipctmp=5,mixphase=0, & - ihvol=ihailv,errmsg=errmsg,errflg=errflg,myrank=mpirank,mpiroot=mpiroot) + ihvol=ihailv,nssl_ehw0=nssl_ehw0_in,nssl_ehlw0=nssl_ehlw0_in,errmsg=errmsg,errflg=errflg,myrank=mpirank,mpiroot=mpiroot) ! For restart runs, the init is done here if (restart) then diff --git a/physics/mp_nssl.meta b/physics/mp_nssl.meta index 9b913da2b..c7e398f0a 100644 --- a/physics/mp_nssl.meta +++ b/physics/mp_nssl.meta @@ -151,7 +151,7 @@ intent = in [nssl_alphah] standard_name = nssl_alpha_graupel - long_name = graupel PSD shape parameter in NSSL micro + long_name = graupel particle size distribution(PSD) shape parameter in NSSL microphysics scheme units = none dimensions = () type = real @@ -159,7 +159,31 @@ intent = in [nssl_alphahl] standard_name = nssl_alpha_hail - long_name = hail PSD shape parameter in NSSL micro + long_name = hail particle size distribution(PSD) shape parameter in NSSL microphysics scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[nssl_alphar] + standard_name = nssl_alpha_rain + long_name = rain particle size distribution(PSD) shape parameter in NSSL microphysics scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[nssl_ehw0_in] + standard_name = nssl_graupel_collection_efficiency + long_name = graupel droplet collection efficiency in NSSL microphysics scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[nssl_ehlw0_in] + standard_name = nssl_hail_collection_efficiency + long_name = hail droplet collection efficiency in NSSL microphysics scheme units = none dimensions = () type = real @@ -167,21 +191,21 @@ intent = in [nssl_ccn_on] standard_name = nssl_ccn_on - long_name = CCN activation flag in NSSL micro + long_name = CCN activation flag in NSSL microphysics scheme units = flag dimensions = () type = logical intent = in [nssl_hail_on] standard_name = nssl_hail_on - long_name = hail activation flag in NSSL micro + long_name = hail activation flag in NSSL microphysics scheme units = flag dimensions = () type = logical intent = in [nssl_invertccn] standard_name = nssl_invertccn - long_name = flag to invert CCN in NSSL micro + long_name = flag to invert CCN in NSSL microphysics scheme units = flag dimensions = () type = logical @@ -571,21 +595,21 @@ intent = in [nssl_ccn_on] standard_name = nssl_ccn_on - long_name = CCN activation flag in NSSL micro + long_name = CCN activation flag in NSSL microphysics scheme units = flag dimensions = () type = logical intent = in [nssl_hail_on] standard_name = nssl_hail_on - long_name = hail activation flag in NSSL micro + long_name = hail activation flag in NSSL microphysics scheme units = flag dimensions = () type = logical intent = in [nssl_invertccn] standard_name = nssl_invertccn - long_name = flag to invert CCN in NSSL micro + long_name = flag to invert CCN in NSSL microphysics scheme units = flag dimensions = () type = logical diff --git a/physics/mp_thompson.F90 b/physics/mp_thompson.F90 index 727098a05..e62e8a596 100644 --- a/physics/mp_thompson.F90 +++ b/physics/mp_thompson.F90 @@ -326,8 +326,8 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & dt_inner, & first_time_step, istep, nsteps, & prcp, rain, graupel, ice, snow, sr, & - refl_10cm, reset_dBZ, do_radar_ref, & - aerfld, & + refl_10cm, fullradar_diag, & + do_radar_ref, aerfld, & mpicomm, mpirank, mpiroot, blkno, & ext_diag, diag3d, reset_diag3d, & spp_wts_mp, spp_mp, n_var_spp, & @@ -357,7 +357,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & real(kind_phys), intent(inout) :: ni(:,:) real(kind_phys), intent(inout) :: nr(:,:) ! Aerosols - logical, intent(in) :: is_aerosol_aware, reset_dBZ + logical, intent(in) :: is_aerosol_aware, fullradar_diag logical, intent(in) :: merra2_aerosol_aware real(kind_phys), optional, intent(inout) :: nc(:,:) real(kind_phys), optional, intent(inout) :: nwfa(:,:) @@ -705,7 +705,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & ids=ids, ide=ide, jds=jds, jde=jde, kds=kds, kde=kde, & ims=ims, ime=ime, jms=jms, jme=jme, kms=kms, kme=kme, & its=its, ite=ite, jts=jts, jte=jte, kts=kts, kte=kte, & - reset_dBZ=reset_dBZ, istep=istep, nsteps=nsteps, & + fullradar_diag=fullradar_diag, istep=istep, nsteps=nsteps, & first_time_step=first_time_step, errmsg=errmsg, errflg=errflg, & ! Extended diagnostics ext_diag=ext_diag, & @@ -744,7 +744,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & ids=ids, ide=ide, jds=jds, jde=jde, kds=kds, kde=kde, & ims=ims, ime=ime, jms=jms, jme=jme, kms=kms, kme=kme, & its=its, ite=ite, jts=jts, jte=jte, kts=kts, kte=kte, & - reset_dBZ=reset_dBZ, istep=istep, nsteps=nsteps, & + fullradar_diag=fullradar_diag, istep=istep, nsteps=nsteps, & first_time_step=first_time_step, errmsg=errmsg, errflg=errflg, & ! Extended diagnostics ext_diag=ext_diag, & diff --git a/physics/mp_thompson.meta b/physics/mp_thompson.meta index 1f459bb88..691698281 100644 --- a/physics/mp_thompson.meta +++ b/physics/mp_thompson.meta @@ -610,9 +610,9 @@ type = real kind = kind_phys intent = out -[reset_dBZ] - standard_name = flag_for_resetting_radar_reflectivity_calculation - long_name = flag for resetting radar reflectivity calculation +[fullradar_diag] + standard_name = do_full_radar_reflectivity + long_name = flag for computing full radar reflectivity units = flag dimensions = () type = logical diff --git a/physics/myjsfc_wrapper.F90 b/physics/myjsfc_wrapper.F90 index 81cb36765..cebd2a9f1 100644 --- a/physics/myjsfc_wrapper.F90 +++ b/physics/myjsfc_wrapper.F90 @@ -334,7 +334,7 @@ SUBROUTINE myjsfc_wrapper_run( & & ,phy_f2d_myj(1:im,13) & & ,1,im,1,1,1,levs & & ,1,im,1,1,1,levs & - & ,1,im,1,1,1,levs) + & ,1,im,1,1,1,levs, errmsg, errflg) do i = 1, im if(flag_iter(i))then diff --git a/physics/mynnedmf_wrapper.F90 b/physics/mynnedmf_wrapper.F90 index 08a28f2bd..83a73e6b3 100644 --- a/physics/mynnedmf_wrapper.F90 +++ b/physics/mynnedmf_wrapper.F90 @@ -17,33 +17,32 @@ subroutine mynnedmf_wrapper_init ( & & con_cpv, con_cliq, con_cice, con_rcp, & & con_XLV, con_XLF, con_p608, con_ep2, & & con_karman, con_t0c, & - & do_mynnedmf, lheatstrg, & + & do_mynnedmf, & & errmsg, errflg ) use machine, only : kind_phys use bl_mynn_common implicit none - - logical, intent(in) :: do_mynnedmf - logical, intent(in) :: lheatstrg - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - real(kind=kind_phys),intent(in) :: con_xlv - real(kind=kind_phys),intent(in) :: con_xlf - real(kind=kind_phys),intent(in) :: con_rv - real(kind=kind_phys),intent(in) :: con_rd - real(kind=kind_phys),intent(in) :: con_ep2 - real(kind=kind_phys),intent(in) :: con_grav - real(kind=kind_phys),intent(in) :: con_cp - real(kind=kind_phys),intent(in) :: con_cpv - real(kind=kind_phys),intent(in) :: con_rcp - real(kind=kind_phys),intent(in) :: con_p608 - real(kind=kind_phys),intent(in) :: con_cliq - real(kind=kind_phys),intent(in) :: con_cice - real(kind=kind_phys),intent(in) :: con_karman - real(kind=kind_phys),intent(in) :: con_t0c + + logical, intent(in) :: do_mynnedmf + character(len=*),intent(out):: errmsg + integer, intent(out) :: errflg + + real(kind_phys),intent(in) :: con_xlv + real(kind_phys),intent(in) :: con_xlf + real(kind_phys),intent(in) :: con_rv + real(kind_phys),intent(in) :: con_rd + real(kind_phys),intent(in) :: con_ep2 + real(kind_phys),intent(in) :: con_grav + real(kind_phys),intent(in) :: con_cp + real(kind_phys),intent(in) :: con_cpv + real(kind_phys),intent(in) :: con_rcp + real(kind_phys),intent(in) :: con_p608 + real(kind_phys),intent(in) :: con_cliq + real(kind_phys),intent(in) :: con_cice + real(kind_phys),intent(in) :: con_karman + real(kind_phys),intent(in) :: con_t0c ! Initialize CCPP error handling variables errmsg = '' @@ -82,12 +81,6 @@ subroutine mynnedmf_wrapper_init ( & return end if - if (lheatstrg) then - errmsg = 'Logic error: lheatstrg not implemented for MYNN PBL' - errflg = 1 - return - end if - end subroutine mynnedmf_wrapper_init !>\defgroup gp_mynnedmf MYNN-EDMF PBL and Shallow Convection Module @@ -104,14 +97,15 @@ SUBROUTINE mynnedmf_wrapper_run( & & phii,u,v,omega,t3d, & & qgrs_water_vapor, & & qgrs_liquid_cloud, & - & qgrs_ice_cloud, & + & qgrs_ice, & + & qgrs_snow, & & qgrs_cloud_droplet_num_conc, & & qgrs_cloud_ice_num_conc, & & qgrs_ozone, & & qgrs_water_aer_num_conc, & & qgrs_ice_aer_num_conc, & & qgrs_cccn, & - & prsl,exner, & + & prsl,prsi,exner, & & slmsk,tsurf,qsfc,ps, & & ust,ch,hflx,qflx,wspd,rb, & & dtsfc1,dqsfc1, & @@ -140,16 +134,18 @@ SUBROUTINE mynnedmf_wrapper_run( & & nupdraft,maxMF,ktop_plume, & & dudt, dvdt, dtdt, & & dqdt_water_vapor, dqdt_liquid_cloud, & ! <=== ntqv, ntcw - & dqdt_ice_cloud, dqdt_ozone, & ! <=== ntiw, ntoz + & dqdt_ice, dqdt_snow, & ! <=== ntiw, ntsw + & dqdt_ozone, & ! <=== ntoz & dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc, & ! <=== ntlnc, ntinc & dqdt_water_aer_num_conc, dqdt_ice_aer_num_conc,& ! <=== ntwa, ntia & dqdt_cccn, & ! <=== ntccn & flag_for_pbl_generic_tend, & & dtend, dtidx, index_of_temperature, & & index_of_x_wind, index_of_y_wind, ntke, & - & ntqv, ntcw, ntiw, ntoz, ntlnc, ntinc, ntwa, ntia, & + & ntqv, ntcw, ntiw, ntsw, & + & ntoz, ntlnc, ntinc, ntwa, ntia, & & index_of_process_pbl, htrsw, htrlw, xmu, & - & bl_mynn_tkebudget, bl_mynn_tkeadvect, & + & tke_budget, bl_mynn_tkeadvect, & & bl_mynn_cloudpdf, bl_mynn_mixlength, & & bl_mynn_edmf, & & bl_mynn_edmf_mom, bl_mynn_edmf_tke, & @@ -158,21 +154,24 @@ SUBROUTINE mynnedmf_wrapper_run( & & icloud_bl, do_mynnsfclay, & & imp_physics, imp_physics_gfdl, & & imp_physics_thompson, imp_physics_wsm6, & - & chem3d, frp, mix_chem, rrfs_smoke, fire_turb, nchem, ndvel, & + & imp_physics_fa, & + & chem3d, frp, mix_chem, rrfs_sd, enh_mix, & + & nchem, ndvel, vdep, smoke_dbg, & & imp_physics_nssl, nssl_ccn_on, & - & ltaerosol, mraerosol, spp_wts_pbl, spp_pbl, lprnt, huge, errmsg, errflg ) + & ltaerosol, mraerosol, spp_wts_pbl, spp_pbl, & + & lprnt, huge, errmsg, errflg ) ! should be moved to inside the mynn: use machine, only: kind_phys use bl_mynn_common, only: cp, r_d, grav, g_inv, zero, & - xlv, xlvcp, xlscp + xlv, xlvcp, xlscp, p608 use module_bl_mynn, only: mynn_bl_driver !------------------------------------------------------------------- implicit none !------------------------------------------------------------------- - real(kind=kind_phys) :: huge + real(kind_phys) :: huge character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -182,12 +181,13 @@ SUBROUTINE mynnedmf_wrapper_run( & !smoke/chem integer, intent(in) :: nchem, ndvel integer, parameter :: kdvel=1 + logical, intent(in) :: smoke_dbg ! NAMELIST OPTIONS (INPUT): logical, intent(in) :: & & bl_mynn_tkeadvect, & - & bl_mynn_tkebudget, & - & ltaerosol, mraerosol, & + & ltaerosol, & + & mraerosol, & & lprnt, & & do_mynnsfclay, & & flag_for_pbl_generic_tend, & @@ -204,100 +204,100 @@ SUBROUTINE mynnedmf_wrapper_run( & & bl_mynn_output, & & imp_physics, imp_physics_wsm6, & & imp_physics_thompson, imp_physics_gfdl, & - & imp_physics_nssl, & - & spp_pbl - real, intent(in) :: & + & imp_physics_nssl, imp_physics_fa, & + & spp_pbl, & + & tke_budget + real(kind_phys), intent(in) :: & & bl_mynn_closure !TENDENCY DIAGNOSTICS - real(kind=kind_phys), intent(inout), optional :: dtend(:,:,:) + real(kind_phys), intent(inout), optional :: dtend(:,:,:) integer, intent(in) :: dtidx(:,:) integer, intent(in) :: index_of_temperature, index_of_x_wind integer, intent(in) :: index_of_y_wind, index_of_process_pbl - integer, intent(in) :: ntoz, ntqv, ntcw, ntiw, ntlnc + integer, intent(in) :: ntoz, ntqv, ntcw, ntiw, ntsw, ntlnc integer, intent(in) :: ntinc, ntwa, ntia, ntke !MISC CONFIGURATION OPTIONS - INTEGER, PARAMETER :: & + INTEGER, PARAMETER :: & & bl_mynn_mixscalars=1 - LOGICAL :: & - & FLAG_QI, FLAG_QNI, FLAG_QC, FLAG_QNC, & - & FLAG_QNWFA, FLAG_QNIFA, FLAG_OZONE + LOGICAL :: & + & FLAG_QI, FLAG_QNI, FLAG_QC, FLAG_QS, FLAG_QNC, & + & FLAG_QNWFA, FLAG_QNIFA, FLAG_QNBCA, FLAG_OZONE ! Define locally until needed from CCPP LOGICAL, PARAMETER :: cycling = .false. - INTEGER, PARAMETER :: param_first_scalar = 1 - INTEGER :: & - & p_qc, p_qr, p_qi, p_qs, p_qg, p_qnc, p_qni !MYNN-1D - REAL(kind=kind_phys), intent(in) :: delt, dtf + REAL(kind_phys), intent(in) :: delt, dtf INTEGER, intent(in) :: im, levs LOGICAL, intent(in) :: flag_init, flag_restart INTEGER :: initflag, k, i - INTEGER :: IDS,IDE,JDS,JDE,KDS,KDE, & - & IMS,IME,JMS,JME,KMS,KME, & + INTEGER :: IDS,IDE,JDS,JDE,KDS,KDE, & + & IMS,IME,JMS,JME,KMS,KME, & & ITS,ITE,JTS,JTE,KTS,KTE - REAL(kind=kind_phys) :: tem + REAL(kind_phys) :: tem !MYNN-3D - real(kind=kind_phys), dimension(:,:), intent(in) :: phii - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(in) :: phii + real(kind_phys), dimension(:,:), intent(inout) :: & & dtdt, dudt, dvdt, & - & dqdt_water_vapor, dqdt_liquid_cloud, dqdt_ice_cloud, & + & dqdt_water_vapor, dqdt_liquid_cloud, dqdt_ice, & + & dqdt_snow, & & dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc, & & dqdt_ozone, dqdt_water_aer_num_conc, dqdt_ice_aer_num_conc - real(kind=kind_phys), dimension(:,:), intent(inout) ::dqdt_cccn - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) ::dqdt_cccn + real(kind_phys), dimension(:,:), intent(inout) :: & & qke, qke_adv, EL_PBL, Sh3D, Sm3D, & & qc_bl, qi_bl, cldfra_bl !These 10 arrays are only allocated when bl_mynn_output > 0 - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & & edmf_a,edmf_w,edmf_qt, & & edmf_thl,edmf_ent,edmf_qc, & & sub_thl,sub_sqv,det_thl,det_sqv - real(kind=kind_phys), dimension(:,:), intent(inout) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & & dqke,qWT,qSHEAR,qBUOY,qDISS - real(kind=kind_phys), dimension(:,:), intent(inout) :: & - & t3d,qgrs_water_vapor,qgrs_liquid_cloud,qgrs_ice_cloud - real(kind=kind_phys), dimension(:,:), intent(in) :: & + real(kind_phys), dimension(:,:), intent(inout) :: & + & t3d,qgrs_water_vapor,qgrs_liquid_cloud,qgrs_ice, & + & qgrs_snow + real(kind_phys), dimension(:,:), intent(in) :: & & u,v,omega, & - & exner,prsl, & + & exner,prsl,prsi, & & qgrs_cloud_droplet_num_conc, & & qgrs_cloud_ice_num_conc, & & qgrs_ozone, & & qgrs_water_aer_num_conc, & & qgrs_ice_aer_num_conc - real(kind=kind_phys), dimension(:,:), intent(in) ::qgrs_cccn - real(kind=kind_phys), dimension(:,:), intent(out) :: & + real(kind_phys), dimension(:,:), intent(in) ::qgrs_cccn + real(kind_phys), dimension(:,:), intent(out) :: & & Tsq, Qsq, Cov, exch_h, exch_m - real(kind=kind_phys), dimension(:), intent(in) :: xmu - real(kind=kind_phys), dimension(:,:), intent(in) :: htrsw, htrlw + real(kind_phys), dimension(:), intent(in) :: xmu + real(kind_phys), dimension(:,:), intent(in) :: htrsw, htrlw ! spp_wts_pbl only allocated if spp_pbl == 1 real(kind_phys), dimension(:,:), intent(in) :: spp_wts_pbl !LOCAL - real(kind=kind_phys), dimension(im,levs) :: & - & sqv,sqc,sqi,qnc,qni,ozone,qnwfa,qnifa, & + real(kind_phys), dimension(im,levs) :: & + & sqv,sqc,sqi,sqs,qnc,qni,ozone,qnwfa,qnifa,qnbca, & & dz, w, p, rho, th, qv, delp, & & RUBLTEN, RVBLTEN, RTHBLTEN, RQVBLTEN, & - & RQCBLTEN, RQNCBLTEN, RQIBLTEN, RQNIBLTEN, & - & RQNWFABLTEN, RQNIFABLTEN - real(kind=kind_phys), allocatable :: old_ozone(:,:) + & RQCBLTEN, RQNCBLTEN, RQIBLTEN, RQNIBLTEN, RQSBLTEN, & + & RQNWFABLTEN, RQNIFABLTEN, RQNBCABLTEN + real(kind_phys), allocatable :: old_ozone(:,:) !smoke/chem arrays real(kind_phys), dimension(:), intent(inout) :: frp - logical, intent(in) :: mix_chem, fire_turb, rrfs_smoke - real(kind=kind_phys), dimension(:,:,:), intent(inout) :: chem3d - real(kind=kind_phys), dimension(im) :: emis_ant_no - real(kind=kind_phys), dimension(im,ndvel) :: vdep + logical, intent(in) :: mix_chem, enh_mix, rrfs_sd + real(kind_phys), dimension(:,:,:), intent(inout) :: chem3d + real(kind_phys), dimension(:,: ), intent(inout) :: vdep + real(kind_phys), dimension(im) :: emis_ant_no !MYNN-2D - real(kind=kind_phys), dimension(:), intent(in) :: & + real(kind_phys), dimension(:), intent(in) :: & & dx,zorl,slmsk,tsurf,qsfc,ps, & & hflx,qflx,ust,wspd,rb,recmol - real(kind=kind_phys), dimension(:), intent(in) :: & + real(kind_phys), dimension(:), intent(in) :: & & dusfc_cice,dvsfc_cice,dtsfc_cice,dqsfc_cice, & & stress_wat,hflx_wat,qflx_wat, & & oceanfrac,fice @@ -305,26 +305,26 @@ SUBROUTINE mynnedmf_wrapper_run( & logical, dimension(:), intent(in) :: & & wet, dry, icy - real(kind=kind_phys), dimension(:), intent(inout) :: & + real(kind_phys), dimension(:), intent(inout) :: & & pblh,dusfc_diag,dvsfc_diag,dtsfc_diag,dqsfc_diag - real(kind=kind_phys), dimension(:), intent(out) :: & + real(kind_phys), dimension(:), intent(out) :: & & ch,dtsfc1,dqsfc1,dusfc1,dvsfc1, & & dtsfci_diag,dqsfci_diag,dusfci_diag,dvsfci_diag, & & maxMF integer, dimension(:), intent(inout) :: & & kpbl,nupdraft,ktop_plume - real(kind=kind_phys), dimension(:), intent(inout) :: & + real(kind_phys), dimension(:), intent(inout) :: & & dusfc_cpl,dvsfc_cpl,dtsfc_cpl,dqsfc_cpl - real(kind=kind_phys), dimension(:), intent(inout) :: & + real(kind_phys), dimension(:), intent(inout) :: & & dusfci_cpl,dvsfci_cpl,dtsfci_cpl,dqsfci_cpl !LOCAL - real, dimension(im) :: & - & hfx,qfx,rmol,xland,uoce,voce,vdfg,znt,ts + real(kind_phys), dimension(im) :: & + & hfx,qfx,rmol,xland,uoce,voce,znt,ts integer :: idtend - real, dimension(im) :: dusfci1,dvsfci1,dtsfci1,dqsfci1 - real(kind=kind_phys), allocatable :: save_qke_adv(:,:) + real(kind_phys), dimension(im) :: dusfci1,dvsfci1,dtsfci1,dqsfci1 + real(kind_phys), allocatable :: save_qke_adv(:,:) ! Initialize CCPP error handling variables errmsg = '' @@ -357,63 +357,32 @@ SUBROUTINE mynnedmf_wrapper_run( & !initialize arrays for test EMIS_ANT_NO = 0. - vdep = 0. ! hli for chem dry deposition, 0 temporarily - - ! Check incoming moist species to ensure non-negative values - ! First, create height (dz) and pressure differences (delp) - ! across model layers - do k=1,levs - do i=1,im - dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv - enddo - enddo - - do i=1,im - delp(i,1) = ps(i) - (prsl(i,2)*dz(i,1) + prsl(i,1)*dz(i,2))/(dz(i,1)+dz(i,2)) - do k=2,levs-1 - delp(i,k) = (prsl(i,k)*dz(i,k-1) + prsl(i,k-1)*dz(i,k))/(dz(i,k)+dz(i,k-1)) - & - (prsl(i,k+1)*dz(i,k) + prsl(i,k)*dz(i,k+1))/(dz(i,k)+dz(i,k+1)) - enddo - delp(i,levs) = delp(i,levs-1) - enddo - - do i=1,im - call moisture_check2(levs, delt, & - delp(i,:), exner(i,:), & - qgrs_water_vapor(i,:), & - qgrs_liquid_cloud(i,:),& - qgrs_ice_cloud(i,:), & - t3d(i,:) ) - enddo FLAG_OZONE = ntoz>0 ! Assign variables for each microphysics scheme - if (imp_physics == imp_physics_wsm6) then - ! WSM6 + if (imp_physics == imp_physics_wsm6 .or. imp_physics == imp_physics_fa) then + ! WSM6 or Ferrier-Aligo FLAG_QI = .true. FLAG_QNI= .false. FLAG_QC = .true. FLAG_QNC= .false. + FLAG_QS = .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = 0. qni(i,k) = 0. qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo elseif (imp_physics == imp_physics_nssl ) then @@ -422,21 +391,16 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .true. FLAG_QC = .true. FLAG_QNC= .true. + FLAG_QS = .false. !.true. FLAG_QNWFA= nssl_ccn_on ! ERM: Perhaps could use this field for CCN field? FLAG_QNIFA= .false. - ! p_q vars not used? - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im - sqv(i,k) = qgrs_water_vapor(i,k) - sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqv(i,k) = qgrs_water_vapor(i,k) + sqc(i,k) = qgrs_liquid_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = 0.0 !qgrs_snow(i,k) ozone(i,k) = qgrs_ozone(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) @@ -445,6 +409,7 @@ SUBROUTINE mynnedmf_wrapper_run( & qnwfa(i,k) = qgrs_cccn(i,k) ENDIF qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo elseif (imp_physics == imp_physics_thompson) then @@ -453,78 +418,69 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QI = .true. FLAG_QNI= .true. FLAG_QC = .true. + FLAG_QS = .true. FLAG_QNC= .true. FLAG_QNWFA= .true. FLAG_QNIFA= .true. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = qgrs_snow(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) qnwfa(i,k) = qgrs_water_aer_num_conc(i,k) qnifa(i,k) = qgrs_ice_aer_num_conc(i,k) + qnbca(i,k) = 0. enddo enddo else if(mraerosol) then FLAG_QI = .true. FLAG_QNI= .true. FLAG_QC = .true. + FLAG_QS = .true. FLAG_QNC= .true. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = qgrs_snow(i,k) qnc(i,k) = qgrs_cloud_droplet_num_conc(i,k) qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo else FLAG_QI = .true. FLAG_QNI= .true. FLAG_QC = .true. + FLAG_QS = .true. FLAG_QNC= .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) + sqs(i,k) = qgrs_snow(i,k) qnc(i,k) = 0. qni(i,k) = qgrs_cloud_ice_num_conc(i,k) ozone(i,k) = qgrs_ozone(i,k) qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. enddo enddo endif @@ -534,24 +490,21 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .false. FLAG_QC = .true. FLAG_QNC= .false. + FLAG_QS = .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 2 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) - sqi(i,k) = qgrs_ice_cloud(i,k) + sqi(i,k) = qgrs_ice(i,k) qnc(i,k) = 0. qni(i,k) = 0. + sqs(i,k) = 0. qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) enddo enddo @@ -562,24 +515,21 @@ SUBROUTINE mynnedmf_wrapper_run( & FLAG_QNI= .false. FLAG_QC = .true. FLAG_QNC= .false. + FLAG_QS = .false. FLAG_QNWFA= .false. FLAG_QNIFA= .false. - p_qc = 2 - p_qr = 0 - p_qi = 0 - p_qs = 0 - p_qg = 0 - p_qnc= 0 - p_qni= 0 + FLAG_QNBCA= .false. do k=1,levs do i=1,im sqv(i,k) = qgrs_water_vapor(i,k) sqc(i,k) = qgrs_liquid_cloud(i,k) sqi(i,k) = 0. + sqs(i,k) = 0. qnc(i,k) = 0. qni(i,k) = 0. qnwfa(i,k) = 0. qnifa(i,k) = 0. + qnbca(i,k) = 0. ozone(i,k) = qgrs_ozone(i,k) enddo enddo @@ -588,21 +538,38 @@ SUBROUTINE mynnedmf_wrapper_run( & allocate(old_ozone(im,levs)) old_ozone = ozone endif - if (lprnt)write(0,*)"prepping MYNN-EDMF variables..." do k=1,levs do i=1,im - ! dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv th(i,k)=t3d(i,k)/exner(i,k) - ! keep as specific humidity - ! qv(i,k)=qvsh(i,k)/(1.0 - qvsh(i,k)) - ! qc(i,k)=qc(i,k)/(1.0 - qvsh(i,k)) - ! qi(i,k)=qi(i,k)/(1.0 - qvsh(i,k)) - rho(i,k)=prsl(i,k)/(r_d*t3d(i,k)) + rho(i,k)=prsl(i,k)/(r_d*t3d(i,k)*(1.+p608*max(sqv(i,k),1e-8))) w(i,k) = -omega(i,k)/(rho(i,k)*grav) + enddo + enddo + + ! Check incoming moist species to ensure non-negative values + ! First, create height difference (dz) + do k=1,levs + do i=1,im + dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv enddo enddo + do i=1,im + do k=1,levs + delp(i,k) = prsi(i,k) - prsi(i,k+1) + enddo + enddo + + do i=1,im + call moisture_check2(levs, delt, & + delp(i,:), exner(i,:), & + sqv(i,:), sqc(i,:), & + sqi(i,:), sqs(i,:), & + t3d(i,:) ) + enddo + + !intialize more variables do i=1,im if (slmsk(i)==1. .or. slmsk(i)==2.) then !sea/land/ice mask (=0/1/2) in FV3 xland(i)=1.0 !but land/water = (1/2) in SFCLAY_mynn @@ -611,11 +578,15 @@ SUBROUTINE mynnedmf_wrapper_run( & endif uoce(i)=0.0 voce(i)=0.0 - vdfg(i)=0.0 !ust(i) = sqrt(stress(i)) ch(i)=0.0 hfx(i)=hflx(i)*rho(i,1)*cp qfx(i)=qflx(i)*rho(i,1) + !filter bad incoming fluxes + if (hfx(i) > 1200.)hfx(i) = 1200. + if (hfx(i) < -500.)hfx(i) = -500. + if (qfx(i) > .0005)qfx(i) = 0.0005 + if (qfx(i) < -.0002)qfx(i) = -0.0002 dtsfc1(i) = hfx(i) dqsfc1(i) = qfx(i)*XLV @@ -690,7 +661,7 @@ SUBROUTINE mynnedmf_wrapper_run( & if (lprnt) then print* write(0,*)"===CALLING mynn_bl_driver; input:" - print*,"bl_mynn_tkebudget=",bl_mynn_tkebudget," bl_mynn_tkeadvect=",bl_mynn_tkeadvect + print*,"tke_budget=",tke_budget," bl_mynn_tkeadvect=",bl_mynn_tkeadvect print*,"bl_mynn_cloudpdf=",bl_mynn_cloudpdf," bl_mynn_mixlength=",bl_mynn_mixlength print*,"bl_mynn_edmf=",bl_mynn_edmf," bl_mynn_edmf_mom=",bl_mynn_edmf_mom print*,"bl_mynn_edmf_tke=",bl_mynn_edmf_tke @@ -716,7 +687,7 @@ SUBROUTINE mynnedmf_wrapper_run( & print*,"znt:",znt(1)," delt=",delt print*,"im=",im," levs=",levs print*,"PBLH=",pblh(1)," KPBL=",KPBL(1)," xland=",xland(1) - print*,"vdfg=",vdfg(1)," ch=",ch(1) + print*,"ch=",ch(1) !print*,"TKE:",TKE_PBL(1,1),TKE_PBL(1,2),TKE_PBL(1,levs) print*,"qke:",qke(1,1),qke(1,2),qke(1,levs) print*,"el_pbl:",el_pbl(1,1),el_pbl(1,2),el_pbl(1,levs) @@ -732,34 +703,36 @@ SUBROUTINE mynnedmf_wrapper_run( & & cycling=cycling, & & delt=delt,dz=dz,dx=dx,znt=znt, & & u=u,v=v,w=w,th=th,sqv3D=sqv,sqc3D=sqc, & - & sqi3D=sqi,qnc=qnc,qni=qni, & - & qnwfa=qnwfa,qnifa=qnifa,ozone=ozone, & + & sqi3D=sqi,sqs3D=sqs,qnc=qnc,qni=qni, & + & qnwfa=qnwfa,qnifa=qnifa,qnbca=qnbca,ozone=ozone, & & p=prsl,exner=exner,rho=rho,T3D=t3d, & & xland=xland,ts=ts,qsfc=qsfc,ps=ps, & & ust=ust,ch=ch,hfx=hfx,qfx=qfx,rmol=rmol, & - & wspd=wspd,uoce=uoce,voce=voce,vdfg=vdfg, & !input + & wspd=wspd,uoce=uoce,voce=voce, & !input & qke=QKE,qke_adv=qke_adv, & !output & sh3d=Sh3d,sm3d=Sm3d, & !chem/smoke & nchem=nchem,kdvel=kdvel,ndvel=ndvel, & - & Chem3d=chem3d,Vdep=vdep, & + & Chem3d=chem3d,Vdep=vdep,smoke_dbg=smoke_dbg, & & FRP=frp,EMIS_ANT_NO=emis_ant_no, & - & mix_chem=mix_chem,fire_turb=fire_turb, & - & rrfs_smoke=rrfs_smoke, & + & mix_chem=mix_chem,enh_mix=enh_mix, & + & rrfs_sd=rrfs_sd, & !----- & Tsq=tsq,Qsq=qsq,Cov=cov, & !output & RUBLTEN=RUBLTEN,RVBLTEN=RVBLTEN,RTHBLTEN=RTHBLTEN, & !output & RQVBLTEN=RQVBLTEN,RQCBLTEN=rqcblten, & & RQIBLTEN=rqiblten,RQNCBLTEN=rqncblten, & !output + & RQSBLTEN=rqsblten, & !output & RQNIBLTEN=rqniblten,RQNWFABLTEN=RQNWFABLTEN, & !output - & RQNIFABLTEN=RQNIFABLTEN,dozone=dqdt_ozone, & !output + & RQNIFABLTEN=RQNIFABLTEN,RQNBCABLTEN=RQNBCABLTEN, & !output + & dozone=dqdt_ozone, & !output & EXCH_H=exch_h,EXCH_M=exch_m, & !output & pblh=pblh,KPBL=KPBL, & !output & el_pbl=el_pbl, & !output & dqke=dqke, & !output & qWT=qWT,qSHEAR=qSHEAR,qBUOY=qBUOY,qDISS=qDISS, & !output & bl_mynn_tkeadvect=bl_mynn_tkeadvect, & - & bl_mynn_tkebudget=bl_mynn_tkebudget, & !input parameter + & tke_budget=tke_budget, & !input parameter & bl_mynn_cloudpdf=bl_mynn_cloudpdf, & !input parameter & bl_mynn_mixlength=bl_mynn_mixlength, & !input parameter & icloud_bl=icloud_bl, & !input parameter @@ -772,7 +745,7 @@ SUBROUTINE mynnedmf_wrapper_run( & & bl_mynn_cloudmix=bl_mynn_cloudmix, & !input parameter & bl_mynn_mixqt=bl_mynn_mixqt, & !input parameter & edmf_a=edmf_a,edmf_w=edmf_w,edmf_qt=edmf_qt, & !output - & edmf_thl=edmf_thl,edmf_ent=edmf_ent,edmf_qc=edmf_qc,&!output + & edmf_thl=edmf_thl,edmf_ent=edmf_ent,edmf_qc=edmf_qc,& !output & sub_thl3D=sub_thl,sub_sqv3D=sub_sqv, & & det_thl3D=det_thl,det_sqv3D=det_sqv, & & nupdraft=nupdraft,maxMF=maxMF, & !output @@ -780,12 +753,12 @@ SUBROUTINE mynnedmf_wrapper_run( & & spp_pbl=spp_pbl,pattern_spp_pbl=spp_wts_pbl, & !input & RTHRATEN=htrlw, & !input & FLAG_QI=flag_qi,FLAG_QNI=flag_qni, & !input - & FLAG_QC=flag_qc,FLAG_QNC=flag_qnc, & !input + & FLAG_QC=flag_qc,FLAG_QNC=flag_qnc,FLAG_QS=flag_qs, & !input & FLAG_QNWFA=FLAG_QNWFA,FLAG_QNIFA=FLAG_QNIFA, & !input - & FLAG_OZONE=FLAG_OZONE, & !input + & FLAG_QNBCA=FLAG_QNBCA,FLAG_OZONE=FLAG_OZONE, & !input & IDS=1,IDE=im,JDS=1,JDE=1,KDS=1,KDE=levs, & !input & IMS=1,IME=im,JMS=1,JME=1,KMS=1,KME=levs, & !input - & ITS=1,ITE=im,JTS=1,JTE=1,KTS=1,KTE=levs) !input + & ITS=1,ITE=im,JTS=1,JTE=1,KTS=1,KTE=levs ) !input ! POST MYNN (INTERSTITIAL) WORK: @@ -826,13 +799,14 @@ SUBROUTINE mynnedmf_wrapper_run( & !enddo !DO moist/scalar/tracer tendencies: - if (imp_physics == imp_physics_wsm6) then + if (imp_physics == imp_physics_wsm6 .or. imp_physics == imp_physics_fa) then ! WSM6 do k=1,levs do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 enddo enddo @@ -846,7 +820,7 @@ SUBROUTINE mynnedmf_wrapper_run( & ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 ! enddo !enddo @@ -858,8 +832,9 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 dqdt_water_aer_num_conc(i,k) = RQNWFABLTEN(i,k) dqdt_ice_aer_num_conc(i,k) = RQNIFABLTEN(i,k) @@ -878,7 +853,7 @@ SUBROUTINE mynnedmf_wrapper_run( & ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! qgrs_cloud_droplet_num_conc(i,k) = qgrs_cloud_droplet_num_conc(i,k) + RQNCBLTEN(i,k)*delt ! qgrs_cloud_ice_num_conc(i,k) = qgrs_cloud_ice_num_conc(i,k) + RQNIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 @@ -892,8 +867,9 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) enddo enddo if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then @@ -909,8 +885,9 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_ozone(i,k) = 0.0 enddo enddo @@ -919,12 +896,13 @@ SUBROUTINE mynnedmf_wrapper_run( & call dtend_helper(100+ntcw,RQCBLTEN) call dtend_helper(100+ntiw,RQIBLTEN) call dtend_helper(100+ntinc,RQNIBLTEN) + call dtend_helper(100+ntsw,RQSBLTEN) endif !do k=1,levs ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! qgrs_cloud_ice_num_conc(i,k) = qgrs_cloud_ice_num_conc(i,k) + RQNIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 ! enddo @@ -937,8 +915,9 @@ SUBROUTINE mynnedmf_wrapper_run( & dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_cloud_droplet_num_conc(i,k) = RQNCBLTEN(i,k) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_ice_num_conc(i,k) = RQNIBLTEN(i,k) + !dqdt_snow(i,k) = RQSBLTEN(i,k) !/(1.0 + qv(i,k)) IF ( nssl_ccn_on ) THEN ! dqdt_cccn(i,k) = RQNWFABLTEN(i,k) ENDIF @@ -951,7 +930,7 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) + dqdt_ice(i,k) = RQIBLTEN(i,k) !/(1.0 + qv(i,k)) !dqdt_rain(i,k) = 0.0 !dqdt_snow(i,k) = 0.0 !dqdt_graupel(i,k) = 0.0 @@ -967,7 +946,7 @@ SUBROUTINE mynnedmf_wrapper_run( & ! do i=1,im ! qgrs_water_vapor(i,k) = qgrs_water_vapor(i,k) + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt ! qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt - ! qgrs_ice_cloud(i,k) = qgrs_ice_cloud(i,k) + RQIBLTEN(i,k)*delt + ! qgrs_ice(i,k) = qgrs_ice(i,k) + RQIBLTEN(i,k)*delt ! !dqdt_ozone(i,k) = 0.0 ! enddo !enddo @@ -977,7 +956,7 @@ SUBROUTINE mynnedmf_wrapper_run( & do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k)) - dqdt_ice_cloud(i,k) = 0.0 + dqdt_ice(i,k) = 0.0 !dqdt_rain(i,k) = 0.0 !dqdt_snow(i,k) = 0.0 !dqdt_graupel(i,k) = 0.0 @@ -1014,8 +993,7 @@ SUBROUTINE mynnedmf_wrapper_run( & print*,"znt:",znt(1)," delt=",delt print*,"im=",im," levs=",levs print*,"PBLH=",pblh(1)," KPBL=",KPBL(1)," xland=",xland(1) - print*,"vdfg=",vdfg(1)," ch=",ch(1) - !print*,"TKE:",TKE_PBL(1,1),TKE_PBL(1,2),TKE_PBL(1,levs) + print*,"ch=",ch(1) print*,"qke:",qke(1,1),qke(1,2),qke(1,levs) print*,"el_pbl:",el_pbl(1,1),el_pbl(1,2),el_pbl(1,levs) print*,"Sh3d:",Sh3d(1,1),sh3d(1,2),sh3d(1,levs) @@ -1045,8 +1023,8 @@ SUBROUTINE mynnedmf_wrapper_run( & CONTAINS SUBROUTINE dtend_helper(itracer,field,mult) - real(kind=kind_phys), intent(in) :: field(im,levs) - real(kind=kind_phys), intent(in), optional :: mult(im,levs) + real(kind_phys), intent(in) :: field(im,levs) + real(kind_phys), intent(in), optional :: mult(im,levs) integer, intent(in) :: itracer integer :: idtend @@ -1062,7 +1040,7 @@ END SUBROUTINE dtend_helper ! ================================================================== SUBROUTINE moisture_check2(kte, delt, dp, exner, & - qv, qc, qi, th ) + qv, qc, qi, qs, th ) ! ! If qc < qcmin, qi < qimin, or qv < qvmin happens in any layer, ! force them to be larger than minimum value by (1) condensating @@ -1076,11 +1054,11 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & implicit none integer, intent(in) :: kte - real, intent(in) :: delt - real, dimension(kte), intent(in) :: dp, exner - real, dimension(kte), intent(inout) :: qv, qc, qi, th + real(kind_phys), intent(in) :: delt + real(kind_phys), dimension(kte), intent(in) :: dp, exner + real(kind_phys), dimension(kte), intent(inout) :: qv, qc, qi, qs, th integer k - real :: dqc2, dqi2, dqv2, sum, aa, dum + real :: dqc2, dqi2, dqs2, dqv2, sum, aa, dum real, parameter :: qvmin1= 1e-8, & !min at k=1 qvmin = 1e-20, & !min above k=1 qcmin = 0.0, & @@ -1089,17 +1067,19 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & do k = kte, 1, -1 ! From the top to the surface dqc2 = max(0.0, qcmin-qc(k)) !qc deficit (>=0) dqi2 = max(0.0, qimin-qi(k)) !qi deficit (>=0) + dqs2 = max(0.0, qimin-qs(k)) !qs deficit (>=0) !update species qc(k) = qc(k) + dqc2 qi(k) = qi(k) + dqi2 - qv(k) = qv(k) - dqc2 - dqi2 + qs(k) = qs(k) + dqs2 + qv(k) = qv(k) - dqc2 - dqi2 - dqs2 !for theta !th(k) = th(k) + xlvcp/exner(k)*dqc2 + & ! xlscp/exner(k)*dqi2 !for temperature th(k) = th(k) + xlvcp*dqc2 + & - xlscp*dqi2 + xlscp*(dqi2+dqs2) !then fix qv if lending qv made it negative if (k .eq. 1) then @@ -1115,6 +1095,7 @@ SUBROUTINE moisture_check2(kte, delt, dp, exner, & endif qc(k) = max(qc(k),qcmin) qi(k) = max(qi(k),qimin) + qs(k) = max(qs(k),qimin) end do ! Extra moisture used to satisfy 'qv(1)>=qvmin' is proportionally diff --git a/physics/mynnedmf_wrapper.meta b/physics/mynnedmf_wrapper.meta index a44a13f1b..ec4706aba 100644 --- a/physics/mynnedmf_wrapper.meta +++ b/physics/mynnedmf_wrapper.meta @@ -125,13 +125,6 @@ dimensions = () type = logical intent = in -[lheatstrg] - standard_name = flag_for_canopy_heat_storage_in_land_surface_scheme - long_name = flag for canopy heat storage parameterization - units = flag - dimensions = () - type = logical - intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -303,7 +296,7 @@ type = real kind = kind_phys intent = inout -[qgrs_ice_cloud] +[qgrs_ice] standard_name = cloud_ice_mixing_ratio long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) units = kg kg-1 @@ -311,6 +304,14 @@ type = real kind = kind_phys intent = inout +[qgrs_snow] + standard_name = snow_mixing_ratio + long_name = ratio of mass of snow water to mass of dry air plus vapor (without condensates) + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [qgrs_cloud_droplet_num_conc] standard_name = mass_number_concentration_of_cloud_liquid_water_particles_in_air long_name = number concentration of cloud droplets (liquid) @@ -367,6 +368,14 @@ type = real kind = kind_phys intent = in +[prsi] + standard_name = air_pressure_at_interface + long_name = air pressure at model layer interfaces + units = Pa + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in [exner] standard_name = dimensionless_exner_function long_name = Exner function at layers @@ -1017,7 +1026,7 @@ type = real kind = kind_phys intent = inout -[dqdt_ice_cloud] +[dqdt_ice] standard_name = process_split_cumulative_tendency_of_cloud_ice_mixing_ratio long_name = cloud condensed water mixing ratio tendency due to model physics units = kg kg-1 s-1 @@ -1025,6 +1034,14 @@ type = real kind = kind_phys intent = inout +[dqdt_snow] + standard_name = process_split_cumulative_tendency_of_snow_mixing_ratio + long_name = ratio of mass of snow water tendency to mass of dry air plus vapor (without condensates) due to model physics + units = kg kg-1 s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [dqdt_ozone] standard_name = process_split_cumulative_tendency_of_ozone_mixing_ratio long_name = ozone mixing ratio tendency due to model physics @@ -1151,6 +1168,13 @@ dimensions = () type = integer intent = in +[ntsw] + standard_name = index_of_snow_mixing_ratio_in_tracer_concentration_array + long_name = tracer index for snow water + units = index + dimensions = () + type = integer + intent = in [ntlnc] standard_name = index_of_mass_number_concentration_of_cloud_droplets_in_tracer_concentration_array long_name = tracer index for liquid number concentration @@ -1210,12 +1234,12 @@ type = real kind = kind_phys intent = in -[bl_mynn_tkebudget] +[tke_budget] standard_name = control_for_tke_budget_output long_name = flag for activating TKE budget units = flag dimensions = () - type = logical + type = integer intent = in [bl_mynn_tkeadvect] standard_name = flag_for_tke_advection @@ -1329,6 +1353,13 @@ dimensions = () type = integer intent = in +[imp_physics_fa] + standard_name = identifier_for_fer_hires_microphysics_scheme + long_name = choice of Ferrier-Aligo microphysics scheme + units = flag + dimensions = () + type = integer + intent = in [imp_physics_nssl] standard_name = identifier_for_nssl_microphysics_scheme long_name = choice of NSSL 2-moment microphysics scheme @@ -1347,7 +1378,7 @@ standard_name = chem3d_mynn_pbl_transport long_name = mynn pbl transport of smoke and dust units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension,2) + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_chemical_species_vertically_mixed) type = real kind = kind_phys intent = inout @@ -1359,9 +1390,9 @@ type = real kind = kind_phys intent = inout -[rrfs_smoke] +[rrfs_sd] standard_name = do_smoke_coupling - long_name = flag controlling rrfs_smoke collection (default off) + long_name = flag controlling rrfs_sd collection (default off) units = flag dimensions = () type = logical @@ -1373,7 +1404,7 @@ dimensions = () type = logical intent = in -[fire_turb] +[enh_mix] standard_name = do_planetary_boundary_layer_fire_enhancement long_name = flag for rrfs smoke mynn enh vermix units = flag @@ -1394,6 +1425,21 @@ dimensions = () type = integer intent = in +[vdep] + standard_name = dry_deposition_velocity_mynn_pbl_transport + long_name = dry deposition velocity by mynn pbl transport + units = m s-1 + dimensions = (horizontal_loop_extent,number_of_chemical_species_deposited) + type = real + kind = kind_phys + intent = in +[smoke_dbg] + standard_name = do_smoke_debug + long_name = flag for rrfs smoke plumerise debug + units = flag + dimensions = () + type = logical + intent = in [ltaerosol] standard_name = flag_for_aerosol_physics long_name = flag for aerosol physics diff --git a/physics/mynnsfc_wrapper.F90 b/physics/mynnsfc_wrapper.F90 index fab1b05d7..4be912ab7 100644 --- a/physics/mynnsfc_wrapper.F90 +++ b/physics/mynnsfc_wrapper.F90 @@ -1,5 +1,5 @@ !> \file mynnsfc_wrapper.F90 -!! Contains all of the code related to running the MYNN surface layer scheme +!! Contains all of the code related to running the MYNN surface layer scheme MODULE mynnsfc_wrapper @@ -97,8 +97,8 @@ SUBROUTINE mynnsfc_wrapper_run( & ! should be moved to inside the mynn: use machine , only : kind_phys -! USE module_sf_mynn, only : SFCLAY_mynn -!tgs - info on iterations: +! USE module_sf_mynn, only : SFCLAY_mynn +!tgs - info on iterations: ! flag_iter- logical, execution or not (im) ! when iter = 1, flag_iter = .true. for all grids im ! ! when iter = 2, flag_iter = .true. when wind < 2 im ! @@ -108,9 +108,9 @@ SUBROUTINE mynnsfc_wrapper_run( & ! when iter = 2, flag_guess = .false. for all grids im ! -!------------------------------------------------------------------- +!------------------------------------------------------------------- implicit none -!------------------------------------------------------------------- +!------------------------------------------------------------------- ! --- constant parameters: ! real(kind=kind_phys), parameter :: rvovrd = r_v/r_d real(kind=kind_phys), parameter :: karman = 0.4 @@ -121,8 +121,8 @@ SUBROUTINE mynnsfc_wrapper_run( & real(kind=kind_phys), parameter :: SVP3 = 29.65 real(kind=kind_phys), parameter :: SVPT0 = 273.15 - REAL, PARAMETER :: xlvcp=xlv/cp, xlscp=(xlv+xlf)/cp, ev=xlv, rd=r_d, & - &rk=cp/rd, svp11=svp1*1.e3, p608=ep_1, ep_3=1.-ep_2, g_inv=1./g + REAL(kind=kind_phys), PARAMETER :: xlvcp=xlv/cp, xlscp=(xlv+xlf)/cp, ev=xlv,& + &rd=r_d, rk=cp/rd, svp11=svp1*1.e3, p608=ep_1, ep_3=1.-ep_2, g_inv=1./g character(len=*), intent(out) :: errmsg @@ -145,9 +145,10 @@ SUBROUTINE mynnsfc_wrapper_run( & !Input data integer, dimension(:), intent(in) :: vegtype - real(kind=kind_phys), dimension(:), intent(in) :: & + real(kind=kind_phys), dimension(:), intent(in) :: & & sigmaf,shdmax,z0pert,ztpert - real(kind_phys), dimension(:,:), intent(in) :: spp_wts_sfc + real(kind=kind_phys), dimension(:,:), intent(in) :: & + & spp_wts_sfc real(kind=kind_phys), dimension(:,:), & & intent(in) :: phii @@ -278,8 +279,8 @@ SUBROUTINE mynnsfc_wrapper_run( & ! write(0,*)"qsfc:",qsfc(1)," ps:",ps(1) ! write(0,*)"wspd:",wspd(1),"rb=",rb_wat(1) ! write(0,*)"delt=",delt," im=",im," levs=",levs -! write(0,*)"flag_init=",flag_init -! write(0,*)"flag_restart=",flag_restart +! write(0,*)"flag_init=",flag_init +! write(0,*)"flag_restart=",flag_restart ! write(0,*)"iter=",iter ! write(0,*)"zlvl(1)=",dz(1,1)*0.5 ! write(0,*)"PBLH=",pblh(1)," xland=",xland(1) @@ -368,7 +369,7 @@ SUBROUTINE mynnsfc_wrapper_run( & ! write(0,*)"cm:",cm_lnd(1),cm_wat(1),cm_ice(1) ! write(0,*)"ch:",ch_lnd(1),ch_wat(1),ch_ice(1) ! write(0,*)"fm:",fm_lnd(1),fm_wat(1),fm_ice(1) -! write(0,*)"fh:",fh_lnd(1),fh_wat(1),fh_ice(1) +! write(0,*)"fh:",fh_lnd(1),fh_wat(1),fh_ice(1) ! write(0,*)"rb:",rb_lnd(1),rb_wat(1),rb_ice(1) ! write(0,*)"xland=",xland(1)," wstar:",wstar(1) ! write(0,*)"HFX:",hfx(1)," qfx:",qfx(1) diff --git a/physics/noahmpdrv.F90 b/physics/noahmpdrv.F90 index fed823ead..771cfa0f6 100644 --- a/physics/noahmpdrv.F90 +++ b/physics/noahmpdrv.F90 @@ -77,13 +77,6 @@ subroutine noahmpdrv_init(lsm, lsm_noahmp, me, isot, ivegsrc, & return end if - if (.not. do_mynnsfclay .and. do_mynnedmf) then - errmsg = 'Problem : do_mynnsfclay = .false.' // & - 'but mynnpbl is .true.. Exiting ...' - errflg = 1 - return - end if - if ( do_mynnsfclay .and. .not. do_mynnedmf) then errmsg = 'Problem : do_mynnsfclay = .true.' // & 'but mynnpbl is .false.. Exiting ...' @@ -93,7 +86,7 @@ subroutine noahmpdrv_init(lsm, lsm_noahmp, me, isot, ivegsrc, & !--- initialize soil vegetation - call set_soilveg(me, isot, ivegsrc, nlunit) + call set_soilveg(me, isot, ivegsrc, nlunit, errmsg, errflg) ! initialize psih and psim @@ -138,7 +131,7 @@ subroutine noahmpdrv_run & idveg, iopt_crs, iopt_btr, iopt_run, iopt_sfc, iopt_frz, & iopt_inf, iopt_rad, iopt_alb, iopt_snf, iopt_tbot, & iopt_stc, iopt_trs,xlatin, xcoszin, iyrlen, julian, garea, & - rainn_mp, rainc_mp, snow_mp, graupel_mp, ice_mp, & + rainn_mp, rainc_mp, snow_mp, graupel_mp, ice_mp, rhonewsn1,& con_hvap, con_cp, con_jcal, rhoh2o, con_eps, con_epsm1, & con_fvirt, con_rd, con_hfus, thsfc_loc, & @@ -262,6 +255,7 @@ subroutine noahmpdrv_run & real(kind=kind_phys), dimension(:) , intent(in) :: snow_mp ! microphysics snow [mm] real(kind=kind_phys), dimension(:) , intent(in) :: graupel_mp ! microphysics graupel [mm] real(kind=kind_phys), dimension(:) , intent(in) :: ice_mp ! microphysics ice/hail [mm] + real(kind=kind_phys), dimension(:) , intent(in) :: rhonewsn1 ! precipitation ice density (kg/m^3) real(kind=kind_phys) , intent(in) :: con_hvap ! latent heat condensation [J/kg] real(kind=kind_phys) , intent(in) :: con_cp ! specific heat air [J/kg/K] real(kind=kind_phys) , intent(in) :: con_jcal ! joules per calorie (not used) @@ -757,7 +751,7 @@ subroutine noahmpdrv_run & call transfer_mp_parameters(vegetation_category, soil_category, & slope_category, soil_color_category, crop_type,parameters) - + parameters%prcpiceden = rhonewsn1(i) call noahmp_options(idveg ,iopt_crs, iopt_btr , iopt_run, iopt_sfc, & iopt_frz, iopt_inf , iopt_rad, iopt_alb, & iopt_snf, iopt_tbot, iopt_stc, iopt_rsf, & diff --git a/physics/noahmpdrv.meta b/physics/noahmpdrv.meta index 3235b7c90..633205de2 100644 --- a/physics/noahmpdrv.meta +++ b/physics/noahmpdrv.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = noahmpdrv type = scheme - dependencies = funcphys.f90,machine.F,sfc_diff.f,module_sf_noahmp_glacier.f90,module_sf_noahmplsm.f90,noahmp_tables.f90,set_soilveg.f + dependencies = funcphys.f90,machine.F,sfc_diff.f,module_sf_noahmp_glacier.F90,module_sf_noahmplsm.F90,noahmp_tables.f90,set_soilveg.f ######################################################################## [ccpp-arg-table] @@ -532,6 +532,14 @@ type = real kind = kind_phys intent = in +[rhonewsn1] + standard_name = surface_frozen_precipitation_density + long_name = density of precipitation ice + units = kg m-3 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in [con_hvap] standard_name = latent_heat_of_vaporization_of_water_at_0C long_name = latent heat of evaporation/sublimation diff --git a/physics/physcons.F90 b/physics/physcons.F90 index 41d37491a..7b7a71c98 100644 --- a/physics/physcons.F90 +++ b/physics/physcons.F90 @@ -53,8 +53,8 @@ module physcons real(kind=kind_phys),parameter:: con_omega =7.2921e-5_kind_phys !< ang vel of earth (\f$s^{-1}\f$) real(kind=kind_phys),parameter:: con_p0 =1.01325e5_kind_phys !< standard atmospheric pressure (\f$Pa\f$) ! real(kind=kind_phys),parameter:: con_solr =1.36822e+3_kind_phys ! solar constant (W/m2)-aer(2001) - real(kind=kind_phys),parameter:: con_solr_old =1.3660e+3_kind_phys !< solar constant (\f$W/m^{2}\f$)-Liu(2002) - real(kind=kind_phys),parameter:: con_solr =1.3608e+3_kind_phys !< solar constant (\f$W/m^{2}\f$)-nasa-sorce Tim(2008) + real(kind=kind_phys),parameter:: con_solr_2002 =1.3660e+3_kind_phys !< solar constant (\f$W/m^{2}\f$)-Liu(2002) + real(kind=kind_phys),parameter:: con_solr_2008 =1.3608e+3_kind_phys !< solar constant (\f$W/m^{2}\f$)-nasa-sorce Tim(2008) ! real(kind=kind_phys),parameter:: con_solr =1.36742732e+3_kind_phys ! solar constant (W/m2)-gfdl(1989) - OPR as of Jan 2006 ! Selected geophysics/astronomy constants with kind=kind_dyn real(kind=kind_dyn), parameter:: con_g_dyn =9.80665e+0_kind_dyn !< gravity (\f$m/s^{2}\f$) diff --git a/physics/physparam.f b/physics/physparam.f deleted file mode 100644 index 5518c6163..000000000 --- a/physics/physparam.f +++ /dev/null @@ -1,300 +0,0 @@ -!> \file physparam.f -!! This file contains module physparam. - -! ========================================================== !!!!! -! module physparam description !!!!! -! ========================================================== !!!!! -! ! -! This module defines commonly used control variables/parameters ! -! in physics related programs. ! -! ! -! Section 1 contains control variables defined in the form of ! -! parameter. They are pre-determined choices and not adjustable ! -! during model's run-time. ! -! ! -! Section 2 contains control variables defined as module variables.! -! They are more flexible to be changed during run-time by either ! -! through input namelist, or through model environment condition. ! -! They are preassigned here as the default values. ! -! ! -!!!!! ========================================================== !!!!! - -!> \defgroup phy_sparam GFS Physics Parameter Module -!! Those variables are grouped together in accordance with functionaity -!! and are given brief descriptions and value specifications. There are -!! two types of attributes (parameters vs. save) designated for the -!! control variables. Those with a "parameter" attribute are prescribed -!! with a preferred option value, while the ones with a "save" attribute -!! are given a default value but could be changed at the model's -!! execution-time (usually through an input of name-list file or through -!! run scripts). - -!> This module defines commonly used control variables and parameters -!! in physics related programs. - module physparam -! -! implicit none - -! --- ... define kind parameters here - -! ** if already exist, use the module containing kind definitions - use machine - -! ** otherwise, define kind parameter here -! implicit none -! integer, public, parameter :: kind_io4 = 4 -! integer, public, parameter :: kind_io8 = 8 -! integer, public, parameter :: kind_phys= selected_real_kind(13,60) ! the '60' maps to 64-bit real -! ..... - -! implicit none -! - public - -!================================================================================== -! Section - 1 - -! control flags are pre-set as run-time non-adjuztable parameters. -!================================================================================== - -! ............................................. ! -!> \name 1.1 Control flags for SW radiation -! ............................................. ! - -!> SW heating rate unit control flag: =1:k/day; =2:k/second. - integer,parameter :: iswrate = 2 - -!> SW minor gases effect control flag (CH4 and O2): =0:no; =1:yes. -!!\n =0: minor gases' effects are not included in calculations -!!\n =1: minor gases' effects are included in calculations - integer,parameter :: iswrgas = 1 - -!> SW optical property for liquid clouds -!!\n =0:input cld opt depth, ignoring iswcice setting -!!\n =1:cloud optical property scheme based on Hu and Stamnes(1993) \cite hu_and_stamnes_1993 method -!!\n =2:cloud optical property scheme based on Hu and Stamnes(1993) -updated - integer,save :: iswcliq = 1 - -!> SW optical property for ice clouds (only iswcliq>0) -!!\n =1:optical property scheme based on Ebert and Curry (1992) -!! \cite ebert_and_curry_1992 method -!!\n =2:optical property scheme based on Streamer v3.0 -!! \cite key_2002 method -!!\n =3:optical property scheme based on Fu's method (1996) -!! \cite fu_1996 method - integer,save :: iswcice = 3 - -!> SW control flag for scattering process approximation -!!\n =1:two-stream delta-eddington (Joseph et al. 1976 -!! \cite joseph_et_al_1976) -!!\n =2:two-stream PIFM (Zdunkowski et al. 1980 -!! \cite zdunkowski_et_al_1980) -!!\n =3:discrete ordinates (Liou, 1973 -!! \cite liou_1973) - integer,parameter :: iswmode = 2 - -! ............................................. ! -!> \name 1.2 Control flags for LW radiation -! ............................................. ! - -!> LW heating rate unit: =1:k/day; =2:k/second. - integer,parameter :: ilwrate = 2 - -!> LW minor gases effect control flag (CH4,N2O,O2,and some CFCs): -!!\n =0: minor gases' effects are not included in calculations -!!\n =1: minor gases' effects are included in calculations - integer,parameter :: ilwrgas = 1 - -!> LW optical property scheme for liquid clouds -!!\n =0:input cloud optical properties directly, not computed within -!!\n =1:input cwp,rew, use Hu and Stamnes(1993) -!! \cite hu_and_stamnes_1993 method - integer,save :: ilwcliq = 1 - -!> LW optical property scheme for ice clouds (only ilwcliq>0) -!!\n =1:optical property scheme based on Ebert and Curry (1992) -!! \cite ebert_and_curry_1992 method -!!\n =2:optical property scheme based on Streamer v3 -!! \cite key_2002 method -!!\n =3:optical property scheme use Fu's method (1998) -!! \cite fu_et_al_1998 method - integer,save :: ilwcice = 3 - -! ............................................. ! -!>\name 1.3 Control flag for LW aerosol property - -!> selects 1 band or multi bands for LW aerosol properties -!!\n =.true.:aerosol properties calculated in 1 broad LW band -!!\n =.false.:aerosol properties calculated in all LW bands -!!\n variable names diff in Opr CFS - logical,parameter :: lalw1bd =.false. - -!================================================================================== -! Section - 2 - -! values of control flags might be re-set in initialization subroutines -! (may be adjusted at run time based on namelist input or run condition) -!================================================================================== - -! ............................................. ! -!>\name 2.1 For module radiation_astronomy -! ............................................. ! - -!> solar constant scheme control flag -!!\n =0:fixed value=1366.0\f$W/m^2\f$(old standard) -!!\n =10:fixed value=1360.8\f$W/m^2\f$(new standard) -!!\n =1:NOAA ABS-scale TSI table (yearly) w 11-yr cycle approx -!!\n =2:NOAA TIM-scale TSI table (yearly) w 11-yr cycle approx -!!\n =3:CMIP5 TIM-scale TSI table (yearly) w 11-yr cycle approx -!!\n =4:CMIP5 TIM-scale TSI table (monthly) w 11-yr cycle approx -!!\n see ISOL in run scripts: Opr GFS=2; Opr CFS=1 - integer, save :: isolar = 0 - -!> external solar constant data table,solarconstant_noaa_a0.txt - character, save :: solar_file*26 -! data solar_file / 'solarconstantdata.txt ' / - data solar_file / 'solarconstant_noaa_a0.txt ' / - -! ............................................. ! -!> \name 2.2 For module radiation_aerosols -! ............................................. ! - -!> aerosol model scheme control flag -!!\n =0:seasonal global distributed OPAC aerosol climatology -!!\n =1:monthly global distributed GOCART aerosol climatology -!!\n =2: GOCART prognostic aerosol model -!!\n =5: OPAC climatoloy with new band mapping -!!\n Opr GFS=0; Opr CFS=n/a - integer, save :: iaermdl = 0 - -!> aerosol effect control flag -!!\n 3-digit flag 'abc': -!!\n a-stratospheric volcanic aerols -!!\n b-tropospheric aerosols for LW -!!\n c-tropospheric aerosols for SW -!!\n =0:aerosol effect is not included; =1:aerosol effect is included -!!\n Opr GFS/CFS =111; see IAER in run scripts - integer, save :: iaerflg = 0 - -!> external aerosols data file: aerosol.dat - character, save :: aeros_file*26 -! data aeros_file / 'climaeropac_global.txt ' / - data aeros_file / 'aerosol.dat ' / - -! ............................................. ! -!> \name 2.3 For module radiation_gases -! ............................................. ! - -!> co2 data source control flag -!!\n =0:prescribed value(380 ppmv) -!!\n =1:yearly global averaged annual mean from observations -!!\n =2:monthly 15 degree horizontal resolution from observations -!!\n Opr GFS/CFS=2; see ICO2 in run scripts - integer, save :: ico2flg = 0 - -!> controls external data at initial time and data usage during -!! forecast time -!!\n =-2:as in 0,but superimpose with seasonal climatology cycle -!!\n =-1:use user data,no extrapolation in overtime -!!\n =0:use IC time to select data,no extrapolation in overtime -!!\n =1:use forecast time to select data,extrapolate when necessary -!!\n =yyyy0:use yyyy year of data, no extrapolation -!!\n =yyyy1:use yyyy year of data, extrapolate when necessary -!!\n Opr GFS/CFS=1; see ICTM in run scripts - integer, save :: ictmflg = 0 - -!> ozone data source control flag -!!\n =0:use seasonal climatology ozone data -!!\n >0:use prognostic ozone scheme (also depend on other model control -!! variable at initial time) - integer, save :: ioznflg = 1 - -!> external co2 2d monthly obsv data table: co2historicaldata_2004.txt - character, save :: co2dat_file*26 -!> external co2 global annual mean data tb: co2historicaldata_glob.txt - character, save :: co2gbl_file*26 -!> external co2 user defined data table: co2userdata.txt - character, save :: co2usr_file*26 -!> external co2 clim monthly cycle data tb: co2monthlycyc.txt - character, save :: co2cyc_file*26 - data co2dat_file / 'co2historicaldata_2004.txt' / !year is run-time selected - data co2gbl_file / 'co2historicaldata_glob.txt' / - data co2usr_file / 'co2userdata.txt ' / - data co2cyc_file / 'co2monthlycyc.txt ' / - -! ............................................. ! -!>\name 2.4 For module radiation_clouds -! ............................................. ! - -!> cloud optical property scheme control flag -!!\n =0:use diagnostic cloud scheme for cloud cover and mean optical properties -!!\n =1:use prognostic cloud scheme for cloud cover and cloud properties - integer, save :: icldflg = 1 - -!> cloud overlapping control flag for Radiation -!!\n =0:use random cloud overlapping method -!!\n =1:use maximum-random cloud overlapping method -!!\n =2:use maximum cloud overlapping method -!!\n =3:use decorrelation length overlapping method -!!\n =4:use exponential overlapping method -!!\n =5:use exponential-random overlapping method -!!\n Opr GFS/CFS=1; see IOVR in run scripts - integer, save :: iovr = 1 -!!\n Decorrelation length type for iovr = 4 or 5 -!!\n =0:use constant decorrelation length defined by decorr_con (in module physcons) -!!\n =1:use day-of-year and latitude-varying decorrelation length - integer, save :: idcor = 1 - -!> sub-column cloud approx flag in SW radiation -!!\n =0:no McICA approximation in SW radiation -!!\n =1:use McICA with precribed permutation seeds (test mode) -!!\n =2:use McICA with randomly generated permutation seeds -!!\n Opr GFS/CFS=2; see ISUBC_SW in run scripts - integer, save :: isubcsw = 0 -!> sub-column cloud approx flag in LW radiation -!!\n =0:no McICA approximation in LW radiation -!!\n =1:use McICA with prescribed permutation seeds (test mode) -!!\n =2:use McICA with randomly generatedo -!!\n Opr GFS/CFS=2; see ISUBC_LW in run scripts - integer, save :: isubclw = 0 - -!> eliminating CRICK control flag - logical, save :: lcrick =.false. -!> in-cld condensate control flag - logical, save :: lcnorm =.false. -!> precip effect on radiation flag (Ferrier microphysics) - logical, save :: lnoprec =.false. -!> shallow convetion flag - logical, save :: lsashal =.false. - -! ............................................. ! -!>\name 2.5 For module radiation_surface -! ............................................. ! - -!> surface albedo scheme control flag -!!\n =0:vegetation type based climatological albedo scheme -!!\n =1:seasonal albedo derived from MODIS measurements - integer, save :: ialbflg = 0 - -!> surface emissivity scheme control flag -!!\n =0:black-body surface emissivity(=1.0) -!!\n =1:vegetation type based climatology emissivity(<1.0) -!!\n Opr GFS/CFS=1; see IEMS in run scripts - integer, save :: iemsflg = 0 - -!> external sfc emissivity data table: sfc_emissivity_idx.txt - character, save :: semis_file*26 - data semis_file / 'sfc_emissivity_idx.txt ' / - -! ............................................. ! -!> \name 2.6 general purpose -! ............................................. ! - -!> vertical profile indexing flag - integer, save :: ivflip = 1 - -!> initial permutaion seed for mcica radiation - integer, save :: ipsd0 = 0 - integer, save :: ipsdlim = 1e8 -! -!...................................! - end module physparam ! -!===================================! diff --git a/physics/progsigma_calc.f90 b/physics/progsigma_calc.f90 index 0b37c30c9..eaa1d3fda 100644 --- a/physics/progsigma_calc.f90 +++ b/physics/progsigma_calc.f90 @@ -54,7 +54,7 @@ subroutine progsigma_calc (im,km,flag_init,flag_restart, & epsilon=1.E-11 km1=km-1 betadcu = 2.0 - betascu = 3.6 + betascu = 8.0 invdelt = 1./delt !Initialization 2D @@ -210,17 +210,18 @@ subroutine progsigma_calc (im,km,flag_init,flag_restart, & enddo !Reduce area fraction before coupling back to mass-flux computation. - !This tuning could be addressed in updraft velocity equation instead. if(flag_shallow)then do i= 1, im if(cnvflg(i)) then sigmab(i)=sigmab(i)/betascu + sigmab(i)=MAX(0.03,sigmab(i)) endif enddo else do i= 1, im if(cnvflg(i)) then sigmab(i)=sigmab(i)/betadcu + sigmab(i)=MAX(0.01,sigmab(i)) endif enddo endif diff --git a/physics/radiation_aerosols.f b/physics/radiation_aerosols.f index 8f4562847..bbd2f25cb 100644 --- a/physics/radiation_aerosols.f +++ b/physics/radiation_aerosols.f @@ -15,25 +15,23 @@ ! inputs: ! ! ( NLAY, me ) ! ! outputs: ! -! ( none ) ! +! ( errflg, errmsg ) ! ! ! ! 'aer_update' -- updating aerosol data ! ! inputs: ! ! ( iyear, imon, me ) ! ! outputs: ! -! ( none ) ! +! ( errflg, errmsg ) ! ! ! ! 'setaer' -- mapping aeros profile, compute aeros opticals ! ! inputs: ! ! (prsi,prsl,prslk,tvly,rhlay,slmsk,tracer,aerfld,xlon,xlat, ! ! IMAX,NLAY,NLP1, lsswr,lslwr, ! ! outputs: ! -! (aerosw,aerolw,aerodp) ! +! (aerosw,aerolw,aerodp,errmsg,errflg) ! ! ! ! ! ! external modules referenced: ! -! 'module physparam' in 'physparam.f' ! -! 'module physcons' in 'physcons.f' ! ! 'module module_radsw_parameters' in 'radsw_xxxx#_param.f' ! ! 'module module_radlw_parameters' in 'radlw_xxxx#_param.f' ! ! 'module module_radlw_cntr_para' in 'radsw_xxxx#_param.f' ! @@ -128,11 +126,7 @@ module module_radiation_aerosols ! !........................................! ! - use physparam,only : iaermdl, iaerflg, lalw1bd, aeros_file, & - & ivflip, kind_phys, kind_io4, kind_io8 - use physcons, only : con_pi, con_rd, con_g, con_t0c, con_c, & - & con_boltz, con_plnk, con_amd - + use machine, only : kind_phys, kind_io4, kind_io8 use module_iounitdef, only : NIAERCM use module_radsw_parameters, only : NBDSW, wvnsw1=>wvnum1, & & NSWSTR, wvnsw2=>wvnum2 @@ -499,8 +493,8 @@ module module_radiation_aerosols ! !>\section gen_al General Algorithm !----------------------------------- subroutine aer_init & - & ( NLAY, me ) ! --- inputs -! --- outputs: ( to module variables ) + & ( NLAY, me, iaermdl, iaerflg, lalw1bd, aeros_file, con_pi, & + & con_t0c, con_c, con_boltz, con_plnk, errflg, errmsg) ! ================================================================== ! ! ! @@ -510,24 +504,26 @@ subroutine aer_init & ! inputs: ! ! NLAY - number of model vertical layers (not used) ! ! me - print message control flag ! -! ! -! outputs: (to module variables) ! -! ! -! external module variables: (in physparam) ! ! iaermdl - tropospheric aerosol model scheme flag ! ! =0 opac-clim; =1 gocart-clim, =2 gocart-prognostic ! ! =5 opac-clim new spectral mapping ! +! lalw1bd = logical lw aeros propty 1 band vs multi-band cntl flag ! +! =t use 1 broad band optical property ! +! =f use multi bands optical property ! +! ! +! outputs: (CCPP error handling) ! +! errmsg - CCPP error message ! +! errflg - CCPP error flag ! +! ! +! internal module variables: ! ! lalwflg - logical lw aerosols effect control flag ! ! =t compute lw aerosol optical prop ! ! laswflg - logical sw aerosols effect control flag ! ! =t compute sw aerosol optical prop ! ! lavoflg - logical stratosphere volcanic aerosol control flag ! ! =t include volcanic aerosol effect ! -! lalw1bd = logical lw aeros propty 1 band vs multi-band cntl flag ! -! =t use 1 broad band optical property ! -! =f use multi bands optical property ! ! ! -! module constants: ! +! internal module constants: ! ! NWVSOL - num of wvnum regions where solar flux is constant ! ! NWVTOT - total num of wave numbers used in sw spectrum ! ! NWVTIR - total num of wave numbers used in the ir region ! @@ -542,9 +538,14 @@ subroutine aer_init & ! ================================================================== ! ! --- inputs: - integer, intent(in) :: NLAY, me - -! --- output: ( none ) + integer, intent(in) :: NLAY, me, iaermdl, iaerflg + logical, intent(in) :: lalw1bd + character(len=26),intent(in) :: aeros_file + real(kind_phys), intent(in) :: con_pi,con_t0c, con_c, con_boltz, & + & con_plnk +! --- output: + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), dimension(NWVTOT) :: solfwv ! one wvn sol flux @@ -552,6 +553,11 @@ subroutine aer_init & ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + kyrstr = 1 kyrend = 1 kyrsav = 1 @@ -565,9 +571,9 @@ subroutine aer_init & if ( me == 0 ) then - call wrt_aerlog ! write aerosol param info to log file + call wrt_aerlog(iaermdl, iaerflg, lalw1bd, errflg, errmsg) ! write aerosol param info to log file ! --- inputs: (in scope variables) -! --- outputs: ( none ) +! --- outputs: (CCPP error handling) endif @@ -617,33 +623,36 @@ subroutine aer_init & !> -# Call set_spectrum to set up spectral one wavenumber solar/IR !! fluxes. - call set_spectrum + call set_spectrum(con_pi, con_t0c, con_c, con_boltz, con_plnk, & + & errflg, errmsg) ! --- inputs: (module constants) -! --- outputs: (in-scope variables) +! --- outputs: (ccpp error handling) !> -# Call clim_aerinit() to invoke tropospheric aerosol initialization. if ( iaermdl==0 .or. iaermdl==5 ) then ! opac-climatology scheme - call clim_aerinit & ! --- inputs: - & ( solfwv, eirfwv, me & + & ( solfwv, eirfwv, me, aeros_file, & ! --- outputs: - & ) + & errflg, errmsg) elseif ( iaermdl==1 .or. iaermdl==2 ) then ! gocart clim/prog scheme call gocart_aerinit & ! --- inputs: - & ( solfwv, eirfwv, me & + & ( solfwv, eirfwv, me, & ! --- outputs: - & ) + & errflg, errmsg) else if ( me == 0 ) then print *,' !!! ERROR in aerosol model scheme selection', & & ' iaermdl =',iaermdl - stop + errflg = 1 + errmsg = 'ERROR(aer_init): aerosol model scheme selected'// & + & 'is invalid' + return endif endif @@ -654,9 +663,9 @@ subroutine aer_init & if ( lavoflg ) then - call set_volcaer + call set_volcaer(errflg, errmsg) ! --- inputs: (module variables) -! --- outputs: (module variables) +! --- outputs: (module variables: ccpp error handling) endif ! end if_lavoflg_block @@ -667,11 +676,7 @@ subroutine aer_init & !> This subroutine writes aerosol parameter configuration to run log file. !-------------------------------- - subroutine wrt_aerlog -!................................ -! --- inputs: (in scope variables) -! --- outputs: ( none ) - + subroutine wrt_aerlog(iaermdl, iaerflg, lalw1bd, errflg, errmsg) ! ================================================================== ! ! ! ! subprogram : wrt_aerlog ! @@ -680,15 +685,18 @@ subroutine wrt_aerlog ! ! ! ==================== defination of variables =================== ! ! ! -! external module variables: (in physparam) ! -! iaermdl - aerosol scheme flag: 0:opac-clm; 1:gocart-clim; ! -! 2:gocart-prog; 5:opac-clim+new mapping ! -! iaerflg - aerosol effect control flag: 3-digits (volc,lw,sw) ! +! internal module variables: ! ! lalwflg - toposphere lw aerosol effect: =f:no; =t:yes ! ! laswflg - toposphere sw aerosol effect: =f:no; =t:yes ! -! lavoflg - stratospherer volcanic aeros effect: =f:no; =t:yes ! +! lavoflg - stratosphere volcanic aeros effect: =f:no; =t:yes ! +! ! +! inputs: ! +! iaerflg - aerosol effect control flag: 3-digits (volc,lw,sw) ! +! iaermdl - tropospheric aerosol model scheme flag ! ! ! -! outputs: ( none ) ! +! outputs: ! +! errmsg - CCPP error message ! +! errflg - CCPP error flag ! ! ! ! subroutines called: none ! ! ! @@ -696,13 +704,22 @@ subroutine wrt_aerlog ! ! ! ================================================================== ! -! --- inputs: ( none ) -! --- output: ( none ) +! --- inputs: () + integer, intent(in) :: iaermdl, iaerflg + logical, intent(in) :: lalw1bd +! --- output: (CCPP error handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + print *, VTAGAER ! print out version tag if ( iaermdl==0 .or. iaermdl==5 ) then @@ -717,7 +734,10 @@ subroutine wrt_aerlog else print *,' !!! ERROR in selection of aerosol model scheme', & & ' IAER_MDL =',iaermdl - stop + errflg = 1 + errmsg = 'ERROR(wrt_aerlog): Selected aerosol model scheme is'//& + & 'is invalid' + return endif ! end_if_iaermdl_block print *,' IAER=',iaerflg,' LW-trop-aer=',lalwflg, & @@ -764,10 +784,8 @@ end subroutine wrt_aerlog !> This subroutine defines the one wavenumber solar fluxes based on toa !! solar spectral distribution, and define the one wavenumber IR fluxes !! based on black-body emission distribution at a predefined temperature. - subroutine set_spectrum -!................................ -! --- inputs: (module constants) -! --- outputs: (in-scope variables) + subroutine set_spectrum(con_pi, con_t0c, con_c, con_boltz, & + & con_plnk, errflg, errmsg) ! ================================================================== ! ! ! @@ -779,7 +797,14 @@ subroutine set_spectrum ! ! ! ==================== defination of variables =================== ! ! ! -!> - inputs: (module constants) +!> - inputs: (CCPP Interstitials) +!! - con_pi: Physical constant (pi) +!! - con_t0c: Physical constant (temperature kelvin at zero celcius) +!! - con_c: Physical constant (speed of light) +!! - con_boltz: Physical constant (Boltzmann constant) +!! - con_plnk: Physical constant (Planck constant) +!! +!> - inputs: (in-scope variables) !! - NWVTOT: total num of wave numbers used in sw spectrum !! - NWVTIR: total num of wave numbers used in the ir region !! @@ -788,6 +813,10 @@ subroutine set_spectrum !! (\f$W/m^2\f$) !! - eirfwv(NWVTIR): ir flux(273k) for each individual wavenumber !! (\f$W/m^2\f$) +!! +!> - outputs: (CCPP error-handling) +!! - errflg: CCPP error flag +!! - errmsg: CCPP error message ! ! ! subroutines called: none ! ! ! @@ -797,15 +826,24 @@ subroutine set_spectrum ! --- inputs: (module constants) ! integer :: NWVTOT, NWVTIR +! --- inputs: (CCPP Interstitials) + real(kind_phys),intent(in) :: con_pi, con_t0c, con_c, con_boltz, & + & con_plnk ! --- output: (in-scope variables) ! real (kind=kind_phys), dimension(NWVTOT) :: solfwv ! one wvn sol flux ! real (kind=kind_phys), dimension(NWVTIR) :: eirfwv ! one wvn ir flux - +! --- output: (CCPP error-handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys) :: soltot, tmp1, tmp2, tmp3 integer :: nb, nw, nw1, nw2, nmax, nmin + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 ! !===> ... begin here ! @@ -857,11 +895,12 @@ end subroutine set_spectrum !> The initialization program for stratospheric volcanic aerosols. !----------------------------- - subroutine set_volcaer + subroutine set_volcaer(errflg, errmsg) !............................. -! --- inputs: ( none ) -! --- outputs: (module variables) - +! --- inputs: ( none ) ! +! outputs: (CCPP error handling) ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ================================================================== ! ! ! ! subprogram : set_volcaer ! @@ -877,13 +916,19 @@ subroutine set_volcaer ! --- inputs: (none) -! --- output: (module variables) +! --- output: (CCPP error handling) ! integer :: ivolae(:,:,:) - + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! --- allocate data space if ( .not. allocated(ivolae) ) then @@ -910,8 +955,8 @@ end subroutine aer_init !! !!\section gen_clim_aerinit General Algorithm subroutine clim_aerinit & - & ( solfwv, eirfwv, me & ! --- inputs - & ) ! --- outputs + & ( solfwv, eirfwv, me, aeros_file, & ! --- inputs + & errflg, errmsg) ! --- outputs ! ================================================================== ! ! ! @@ -922,24 +967,17 @@ subroutine clim_aerinit & ! solfwv(NWVTOT) - solar flux for each individual wavenumber (w/m2)! ! eirfwv(NWVTIR) - ir flux(273k) for each individual wavenum (w/m2)! ! me - print message control flag ! +! aeros_file - external aerosol data file name ! ! ! -! outputs: (to module variables) ! +! outputs: (CCPP error handling) ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ! -! external module variables: (in physparam) ! -! iaerflg - abc 3-digit integer aerosol flag (abc:volc,lw,sw) ! -! a: =0 use background stratospheric aerosol ! -! =1 incl stratospheric vocanic aeros (MINVYR-MAXVYR) ! -! b: =0 no topospheric aerosol in lw radiation ! -! =1 include tropspheric aerosols for lw radiation ! -! c: =0 no topospheric aerosol in sw radiation ! -! =1 include tropspheric aerosols for sw radiation ! +! internal module variables: ! ! lalwflg - logical lw aerosols effect control flag ! ! =t compute lw aerosol optical prop ! ! laswflg - logical sw aerosols effect control flag ! ! =t compute sw aerosol optical prop ! -! lalw1bd = logical lw aeros propty 1 band vs multi-band cntl flag ! -! =t use 1 broad band optical property ! -! =f use multi bands optical property ! ! ! ! module constants: ! ! NWVSOL - num of wvnum regions where solar flux is constant ! @@ -960,10 +998,11 @@ subroutine clim_aerinit & ! --- inputs: real (kind=kind_phys), dimension(:) :: solfwv ! one wvn sol flux real (kind=kind_phys), dimension(:) :: eirfwv ! one wvn ir flux - integer, intent(in) :: me - -! --- output: ( none ) + character(len=26), intent(in) :: aeros_file +! --- output: (CCPP error handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), dimension(NAERBND,NCM1) :: & @@ -982,10 +1021,14 @@ subroutine clim_aerinit & ! !===> ... begin here ! +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! --- ... invoke tropospheric aerosol initialization !> - call set_aercoef() to invoke tropospheric aerosol initialization. - call set_aercoef + call set_aercoef(aeros_file, errflg, errmsg) ! --- inputs: (in-scope variables, module constants) ! --- outputs: (module variables) @@ -999,10 +1042,10 @@ subroutine clim_aerinit & !! corresponding SW radiation spectral bands. !!\section det_set_aercoef General Algorithm !-------------------------------- - subroutine set_aercoef + subroutine set_aercoef(aeros_file,errflg, errmsg) !................................ ! --- inputs: (in-scope variables, module constants) -! --- outputs: (module variables) +! --- outputs: (CCPP error handling) ! ================================================================== ! ! ! @@ -1021,8 +1064,11 @@ subroutine set_aercoef ! me - integer, select cpu number as print control flag ! ! ! ! outputs: (to the module variables) ! +! outputs: (CCPP error handling) ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ! -! external module variables: (in physparam) ! +! external module variables: ! ! lalwflg - module control flag for lw trop-aer: =f:no; =t:yes ! ! laswflg - module control flag for sw trop-aer: =f:no; =t:yes ! ! aeros_file- external aerosol data file name ! @@ -1076,7 +1122,10 @@ subroutine set_aercoef ! ================================================================== ! ! ! --- inputs: ( none ) -! --- output: ( none ) + character(len=26),intent(in) :: aeros_file +! --- output: (CCPP error handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: integer, dimension(NAERBND) :: iendwv @@ -1090,6 +1139,11 @@ subroutine set_aercoef ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + !> -# Reading climatological aerosols optical data from aeros_file, !! including: @@ -1104,7 +1158,10 @@ subroutine set_aercoef print *,' Requested aerosol data file "',aeros_file, & & '" not found!' print *,' *** Stopped in subroutine aero_init !!' - stop + errflg = 1 + errmsg = 'ERROR(set_aercoef): Requested aerosol data file '// & + & aeros_file//' not found' + return endif ! end if_file_exist_block ! --- ... skip monthly global distribution @@ -1470,7 +1527,7 @@ subroutine optavg ! NSWBND - total number of sw spectral bands ! ! NLWBND - total number of lw spectral bands ! ! ! -! external module variables: (in physparam) ! +! external module variables: ! ! laswflg - control flag for sw spectral region ! ! lalwflg - control flag for lw spectral region ! ! ! @@ -1705,22 +1762,25 @@ end subroutine clim_aerinit !>\section gen_aer_upd General Algorithm !----------------------------------- subroutine aer_update & - & ( iyear, imon, me ) ! --- inputs: -! --- outputs: ( to module variables ) + & ( iyear, imon, me, iaermdl, aeros_file, errflg, errmsg ) ! ================================================================== ! ! ! ! aer_update checks and update time varying climatology aerosol ! ! data sets. ! ! ! -! inputs: size ! -! iyear - 4-digit calender year 1 ! -! imon - month of the year 1 ! -! me - print message control flag 1 ! +! inputs: size ! +! iyear - 4-digit calender year 1 ! +! imon - month of the year 1 ! +! me - print message control flag 1 ! +! iaermdl - tropospheric aerosol model scheme flag 1 ! +! aeros_file - external aerosol data file name len=26 ! ! ! -! outputs: ( none ) ! +! outputs: (CCPP error handling) len=* ! +! errmsg - CCPP error message 1 ! +! errflg - CCPP error flag ! ! ! -! external module variables: (in physparam) ! +! internal module variables: ! ! lalwflg - control flag for tropospheric lw aerosol ! ! laswflg - control flag for tropospheric sw aerosol ! ! lavoflg - control flag for stratospheric volcanic aerosol ! @@ -1732,33 +1792,41 @@ subroutine aer_update & ! ================================================================== ! ! --- inputs: - integer, intent(in) :: iyear, imon, me - -! --- output: ( none ) - + integer, intent(in) :: iyear, imon, me, iaermdl + character(len=26),intent(in) :: aeros_file +! --- output: (CCPP error-handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: ( none ) ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + if ( imon < 1 .or. imon > 12 ) then print *,' ***** ERROR in specifying requested month !!! ', & & 'imon=', imon print *,' ***** STOPPED in subroutinte aer_update !!!' - stop + errflg = 1 + errmsg = 'ERROR(aer_update): Requested month not valid' + return endif !> -# Call trop_update() to update monthly tropospheric aerosol data. if ( lalwflg .or. laswflg ) then if ( iaermdl == 0 .or. iaermdl==5 ) then ! opac-climatology scheme - call trop_update + call trop_update(aeros_file, errflg, errmsg) endif endif !> -# Call volc_update() to update yearly stratospheric volcanic aerosol data. if ( lavoflg ) then - call volc_update + call volc_update(errflg, errmsg) endif @@ -1769,10 +1837,7 @@ subroutine aer_update & !> This subroutine updates the monthly global distribution of aerosol !! profiles in five degree horizontal resolution. !-------------------------------- - subroutine trop_update -!................................ -! --- inputs: (in scope variables, module variables) -! --- outputs: (module variables) + subroutine trop_update(aeros_file, errflg, errmsg) ! ================================================================== ! ! ! @@ -1786,11 +1851,14 @@ subroutine trop_update ! inputs: (in-scope variables, module constants) ! ! imon - integer, month of the year ! ! me - integer, print message control flag ! +! inputs: (CCPP Interstitials) ! +! aeros_file - external aerosol data file name ! ! ! ! outputs: (module variables) ! -! ! -! external module variables: (in physparam) ! -! aeros_file - external aerosol data file name ! +! +! outputs: (CCPP error-handling) ! +! errmsg - Error message ! +! errflg - Error flag ! ! ! ! internal module variables: ! ! kprfg ( IMXAE*JMXAE) - aeros profile index ! @@ -1806,8 +1874,11 @@ subroutine trop_update ! ! ! ================================================================== ! -! --- inputs: ( none ) -! --- output: ( none ) +! --- inputs: (CCPP Interstitials) + character(len=26),intent(in) :: aeros_file +! --- output: (CCPP error handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: ! real (kind=kind_io8) :: cmix(NXC), denn, tem @@ -1821,6 +1892,11 @@ subroutine trop_update ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! --- ... reading climatological aerosols data inquire (file=aeros_file, exist=file_exist) @@ -1838,7 +1914,10 @@ subroutine trop_update print *,' Requested aerosol data file "',aeros_file, & & '" not found!' print *,' *** Stopped in subroutine trop_update !!' - stop + errflg = 1 + errmsg = 'ERROR(trop_update):Requested aerosol data file '// & + & aeros_file // ' not found.' + return endif ! end if_file_exist_block !$omp parallel do private(i,j,m) @@ -1930,10 +2009,10 @@ end subroutine trop_update !> This subroutine searches historical volcanic data sets to find and !! read in monthly 45-degree lat-zone band of optical depth. !-------------------------------- - subroutine volc_update + subroutine volc_update(errflg, errmsg) !................................ ! --- inputs: (in scope variables, module variables) -! --- outputs: (module variables) +! --- outputs: (CCPP error handling) ! ================================================================== ! ! ! @@ -1957,6 +2036,10 @@ subroutine volc_update ! kyrsav - integer, the year of data in use in the input file ! ! kmonsav - integer, the month of data in use in the input file ! ! ! +! outputs: (CCPP error-handling) ! +! errmsg - Error message ! +! errflg - Error flag ! +! ! ! subroutines called: none ! ! ! ! usage: call volc_aerinit ! @@ -1968,6 +2051,9 @@ subroutine volc_update ! --- output: (module variables) ! integer :: ivolae(:,:,:), kyrstr, kyrend, kyrsav, kmonsav +! --- output: (CCPP error-handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: integer :: i, j, k @@ -1978,6 +2064,11 @@ subroutine volc_update ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + kmonsav = imon if ( kyrstr<=iyear .and. iyear<=kyrend ) then ! use previously input data @@ -2032,7 +2123,10 @@ subroutine volc_update print *,' Requested volcanic data file "', & & volcano_file,'" not found!' print *,' *** Stopped in subroutine VOLC_AERINIT !!' - stop + errflg = 1 + errmsg = 'ERROR(volc_update): Requested volcanic data '// & + & 'file '//volcano_file//' not found!' + return endif ! end if_file_exist_block endif ! end if_iyear_block @@ -2083,9 +2177,9 @@ end subroutine aer_update !----------------------------------- subroutine setaer & & ( prsi,prsl,prslk,tvly,rhlay,slmsk,tracer,aerfld,xlon,xlat, & ! --- inputs - & IMAX,NLAY,NLP1, lsswr,lslwr, & - & aerosw,aerolw & ! --- outputs - &, aerodp & + & IMAX,NLAY,NLP1, lsswr,lslwr,iaermdl,iaerflg,top_at_1, & + & con_pi,con_rd,con_g,aerosw,aerolw, & ! --- outputs + & aerodp, ext550, errflg, errmsg & & ) ! ================================================================== ! @@ -2109,6 +2203,12 @@ subroutine setaer & ! NLAY,NLP1-vertical dimensions of arrays 1 ! ! lsswr,lslwr ! ! - logical flags for sw/lw radiation calls 1 ! +! con_pi - Physical constant (pi) ! +! con_t0c - Physical constant (temperature kelvin at zero celcius) ! +! con_c - Physical constant (speed of light) ! +! iaermdl - tropospheric aerosol model scheme flag ! +! iaerflg - aerosol effect control flag ! +! top_at_1 - Vertical ordering convection flag ! ! ! ! outputs: ! ! aerosw - aeros opt properties for sw IMAX*NLAY*NBDSW*NF_AESW! @@ -2122,18 +2222,16 @@ subroutine setaer & ! tau_gocart - 550nm aeros opt depth IMAX*NLAY*MAX_NUM_GRIDCOMP! !! aerodp - vertically integrated optical depth IMAX*NSPC1 ! ! ! -! external module variable: (in physparam) ! -! iaerflg - aerosol effect control flag (volc,lw,sw, 3-dig) ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! +! ! +! internal module variable: ! ! laswflg - tropospheric aerosol control flag for sw radiation ! ! =f: no sw aeros calc. =t: do sw aeros calc. ! ! lalwflg - tropospheric aerosol control flag for lw radiation ! ! =f: no lw aeros calc. =t: do lw aeros calc. ! ! lavoflg - control flag for stratospheric vocanic aerosols ! ! =t: add volcanic aerosols to the background aerosols ! -! ivflip - control flag for direction of vertical index ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! ! internal module variable: (set by subroutine aer_init) ! ! ivolae - stratosphere volcanic aerosol optical depth (fac 1.e4) ! ! 12*4*10 ! @@ -2144,8 +2242,8 @@ subroutine setaer & ! ================================================================== ! ! --- inputs: - integer, intent(in) :: IMAX, NLAY, NLP1 - + integer, intent(in) :: IMAX, NLAY, NLP1, iaermdl, iaerflg + real (kind=kind_phys), intent(in) :: con_pi, con_rd, con_g real (kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, & & prslk, tvly, rhlay real (kind=kind_phys), dimension(:), intent(in) :: xlon, xlat, & @@ -2153,7 +2251,7 @@ subroutine setaer & real (kind=kind_phys), dimension(:,:,:),intent(in):: tracer real (kind=kind_phys), dimension(:,:,:),intent(in):: aerfld - logical, intent(in) :: lsswr, lslwr + logical, intent(in) :: lsswr, lslwr, top_at_1 ! --- outputs: @@ -2161,6 +2259,9 @@ subroutine setaer & & aerosw, aerolw real (kind=kind_phys), dimension(:,:) , intent(out) :: aerodp + real (kind=kind_phys), dimension(:,:) , intent(out) :: ext550 + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), parameter :: psrfh = 5.0 ! ref press (mb) for upper bound @@ -2177,10 +2278,16 @@ subroutine setaer & logical :: laddlw=.false., laerlw=.false. ! --- conversion constants - real (kind=kind_phys), parameter :: rdg = 180.0 / con_pi - real (kind=kind_phys), parameter :: rovg = 0.001 * con_rd / con_g + real (kind=kind_phys) :: rdg + real (kind=kind_phys) :: rovg !===> ... begin here + rdg = 180._kind_phys / con_pi + rovg = 0.001_kind_phys * con_rd / con_g + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 do m = 1, NF_AESW do j = 1, NBDSW @@ -2208,6 +2315,7 @@ subroutine setaer & aerodp(i,k) = f_zero enddo enddo + ext550(:,:) = f_zero if ( .not. (lsswr .or. lslwr) ) then return @@ -2235,7 +2343,7 @@ subroutine setaer & lab_do_IMAX : do i = 1, IMAX - lab_if_flip : if (ivflip == 1) then ! input from sfc to toa + lab_if_flip : if (.not. top_at_1) then ! input from sfc to toa do k = 1, NLAY prsln(k) = log(prsi(i,k)) @@ -2290,10 +2398,10 @@ subroutine setaer & ! --- inputs: & ( prsi,prsl,prslk,tvly,rhlay,dz,hz,tracer, & & alon,alat,slmsk, laersw,laerlw, & - & IMAX,NLAY,NLP1, & + & IMAX,NLAY,NLP1,top_at_1, & ! & IMAX,NLAY,NLP1,NSPC1, & ! --- outputs: - & aerosw,aerolw,aerodp & + & aerosw,aerolw,aerodp,errflg,errmsg & & ) ! @@ -2302,10 +2410,10 @@ subroutine setaer & call aer_property_gocart & ! --- inputs: & ( prsi,prsl,prslk,tvly,rhlay,dz,hz,tracer,aerfld, & - & alon,alat,slmsk,laersw,laerlw, & + & alon,alat,slmsk,laersw,laerlw,con_rd, & & IMAX,NLAY,NLP1, & ! --- outputs: - & aerosw,aerolw,aerodp & + & aerosw,aerolw,aerodp,ext550,errflg,errmsg & & ) endif ! end if_iaerflg_block @@ -2392,7 +2500,7 @@ subroutine setaer & endif enddo - if ( ivflip == 0 ) then ! input data from toa to sfc + if (top_at_1) then ! input data from toa to sfc ! --- find lower boundary of stratosphere @@ -2627,7 +2735,7 @@ subroutine setaer & endif ! end if_NLWBND_block endif ! end if_laddlw_block - endif ! end if_ivflip_block + endif ! end if_top_at_1_block endif ! end if_lavoflg_block ! @@ -2667,8 +2775,8 @@ end subroutine setaer subroutine aer_property & & ( prsi,prsl,prslk,tvly,rhlay,dz,hz,tracer, & ! --- inputs: & alon,alat,slmsk, laersw,laerlw, & - & IMAX,NLAY,NLP1, & - & aerosw,aerolw,aerodp & ! --- outputs: + & IMAX,NLAY,NLP1,top_at_1, & + & aerosw,aerolw,aerodp,errflg,errmsg & ! --- outputs: & ) ! ================================================================== ! @@ -2694,6 +2802,7 @@ subroutine aer_property & ! IMAX - horizontal dimension of arrays 1 ! ! NLAY,NLP1-vertical dimensions of arrays 1 ! !! NSPC - num of species for optional aod output fields 1 ! +! top_at_1 - vertical ordering flag ! ! ! ! outputs: ! ! aerosw - aeros opt properties for sw IMAX*NLAY*NBDSW*NF_AESW! @@ -2706,16 +2815,14 @@ subroutine aer_property & ! (:,:,:,3): asymmetry parameter ! !! aerodp - vertically integrated aer-opt-depth IMAX*NSPC+1 ! ! ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! +! ! ! module parameters and constants: ! ! NSWBND - total number of actual sw spectral bands computed ! ! NLWBND - total number of actual lw spectral bands computed ! ! NSWLWBD - total number of sw+lw bands computed ! ! ! -! external module variables: (in physparam) ! -! ivflip - control flag for direction of vertical index ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! ! module variable: (set by subroutine aer_init) ! ! kprfg - aerosols profile index IMXAE*JMXAE ! ! 1:ant 2:arc 3:cnt 4:mar 5:des 6:marme 7:cntme ! @@ -2735,7 +2842,7 @@ subroutine aer_property & ! --- inputs: integer, intent(in) :: IMAX, NLAY, NLP1 ! integer, intent(in) :: IMAX, NLAY, NLP1, NSPC - logical, intent(in) :: laersw, laerlw + logical, intent(in) :: laersw, laerlw, top_at_1 real (kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, & & prslk, tvly, rhlay, dz, hz @@ -2747,6 +2854,8 @@ subroutine aer_property & real (kind=kind_phys), dimension(:,:,:,:), intent(out) :: & & aerosw, aerolw real (kind=kind_phys), dimension(:,:) , intent(out) :: aerodp + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), dimension(NCM) :: cmix @@ -2773,6 +2882,11 @@ subroutine aer_property & ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + !> -# Map aerosol data to model grids !! - Map grid in longitude direction, lon from 0 to 355 deg resolution !! - Map grid in latitude direction, lat from 90n to 90s in 5 deg resolution @@ -2798,7 +2912,9 @@ subroutine aer_property & if ( i3 > IMXAE ) then print *,' ERROR! In setclimaer alon>360. ipt =',i, & & ', dltg,alon,tlon,dlon =',dltg,alon(i),tmp1,dtmp - stop + errflg = 1 + errmsg = 'ERROR(aer_property)' + return endif elseif ( dtmp >= f_zero ) then i1 = i3 @@ -2816,7 +2932,9 @@ subroutine aer_property & if ( i3 < 1 ) then print *,' ERROR! In setclimaer alon< 0. ipt =',i, & & ', dltg,alon,tlon,dlon =',dltg,alon(i),tmp1,dtmp - stop + errflg = 1 + errmsg = 'ERROR(aer_property)' + return endif endif enddo lab_do_IMXAE @@ -2835,7 +2953,9 @@ subroutine aer_property & if ( j3 >= JMXAE ) then print *,' ERROR! In setclimaer alat<-90. ipt =',i, & & ', dltg,alat,tlat,dlat =',dltg,alat(i),tmp2,dtmp - stop + errflg = 1 + errmsg = 'ERROR(aer_property)' + return endif elseif ( dtmp >= f_zero ) then j1 = j3 @@ -2853,7 +2973,9 @@ subroutine aer_property & if ( j3 < 1 ) then print *,' ERROR! In setclimaer alat>90. ipt =',i, & & ', dltg,alat,tlat,dlat =',dltg,alat(i),tmp2,dtmp - stop + errflg = 1 + errmsg = 'ERROR(aer_property)' + return endif endif enddo lab_do_JMXAE @@ -2950,14 +3072,16 @@ subroutine aer_property & dz1(k) = dz (i,k) enddo - lab_if_flip : if (ivflip == 1) then ! input from sfc to toa + lab_if_flip : if (.not. top_at_1) then ! input from sfc to toa if ( prsi(i,1) > 100.0 ) then rps = f_one / prsi(i,1) else print *,' !!! (1) Error in subr radiation_aerosols:', & & ' unrealistic surface pressure =', i,prsi(i,1) - stop + errflg = 1 + errmsg = 'ERROR(aer_property): Unrealistic surface pressure' + return endif ii = 1 @@ -3030,7 +3154,7 @@ subroutine aer_property & !> -# Call radclimaer() to calculate SW/LW aerosol optical properties !! for the corresponding frequency bands. - call radclimaer + call radclimaer(top_at_1) ! --- inputs: (in-scope variables) ! --- outputs: (in-scope variables) @@ -3091,7 +3215,7 @@ subroutine aer_property & !! troposphere, aerosol distribution at each grid point is composed !! from up to six components out of ten different substances. !-------------------------------- - subroutine radclimaer + subroutine radclimaer(top_at_1) !................................ ! --- inputs: (in scope variables) @@ -3127,6 +3251,7 @@ subroutine radclimaer parameter (crt1=30.0, crt2=0.03333) ! --- inputs: + logical, intent(in) :: top_at_1 ! --- outputs: ! --- locals: @@ -3329,7 +3454,7 @@ subroutine radclimaer ! !===> ... smooth profile at domain boundaries ! - if ( ivflip == 0 ) then ! input from toa to sfc + if (top_at_1) then ! input from toa to sfc do ib = 1, NSWLWBD do kk = 2, NLAY @@ -3404,8 +3529,8 @@ end subroutine aer_property !>\section gel_go_ini General Algorithm !----------------------------------- subroutine gocart_aerinit & - & ( solfwv, eirfwv, me & - & ) + & ( solfwv, eirfwv, me, & + & errflg, errmsg) ! ================================================================== ! ! ! @@ -3419,7 +3544,9 @@ subroutine gocart_aerinit & ! eirfwv(NWVTIR) - ir flux(273k) for each individual wavenum (w/m2)! ! me - print message control flag ! ! ! -! outputs: (to module variables) ! +! outputs: (CCPP error handling) ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ! ! module variables: ! ! NWVSOL - num of wvnum regions where solar flux is constant ! @@ -3445,7 +3572,9 @@ subroutine gocart_aerinit & integer, intent(in) :: me -! --- output: ( none ) +! --- output: (CCPP error handling) + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), dimension(kaerbndi,kcm1) :: & @@ -3476,13 +3605,20 @@ subroutine gocart_aerinit & ! !===> ... begin here + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + ! ! --- ... invoke gocart aerosol initialization if (KCM /= ntrcaerm ) then print *, 'ERROR in # of gocart aer species',KCM - stop 3000 + errflg = 1 + errmsg = 'ERROR(gocart_init): Incorrect # of species' + return endif ! --- ... aloocate and input aerosol optical data @@ -3801,7 +3937,9 @@ subroutine rd_gocart_luts else print *,' Requested luts file ',trim(fin),' not found' print *,' ** Stopped in rd_gocart_luts ** ' - stop 1220 + errflg = 1 + errmsg = 'Requested luts file '//trim(fin)//' not found' + return endif ! end if_file_exist_block iradius = 5 @@ -3866,7 +4004,9 @@ subroutine rd_gocart_luts else print *,' Requested luts file ',trim(fin),' not found' print *,' ** Stopped in rd_gocart_luts ** ' - stop 1222 + errflg = 1 + errmsg = 'Requested luts file '//trim(fin)//' not found' + return endif ! end if_file_exist_block ibeg = radius_lower(ib) - kcm1 @@ -3977,7 +4117,7 @@ subroutine optavg_gocart ! nswbnd - total number of sw spectral bands ! ! nlwbnd - total number of lw spectral bands ! ! ! -! external module variables: (in physparam) ! +! external module variables: ! ! laswflg - control flag for sw spectral region ! ! lalwflg - control flag for lw spectral region ! ! ! @@ -4193,10 +4333,10 @@ subroutine aer_property_gocart & ! --- inputs: & ( prsi,prsl,prslk,tvly,rhlay,dz,hz,tracer,aerfld, & - & alon,alat,slmsk, laersw,laerlw, & + & alon,alat,slmsk, laersw,laerlw,con_rd, & & imax,nlay,nlp1, & ! --- outputs: - & aerosw,aerolw,aerodp & + & aerosw,aerolw,aerodp,ext550,errflg,errmsg & & ) ! ================================================================== ! @@ -4222,6 +4362,7 @@ subroutine aer_property_gocart & ! - logical flag for sw/lw aerosol calculations ! ! IMAX - horizontal dimension of arrays 1 ! ! NLAY,NLP1-vertical dimensions of arrays 1 ! +! con_rd - Physical constant (gas constant for dry air) ! ! ! ! outputs: ! ! aerosw - aeros opt properties for sw IMAX*NLAY*NBDSW*NF_AESW! @@ -4233,17 +4374,14 @@ subroutine aer_property_gocart & ! (:,:,:,2): single scattering albedo ! ! (:,:,:,3): asymmetry parameter ! ! aerodp - vertically integrated aer-opt-depth IMAX*NSPC+1 ! +! errflg - CCPP error flag ! +! errmsg - CCPP error message ! ! ! ! module parameters and constants: ! ! NSWBND - total number of actual sw spectral bands computed ! ! NLWBND - total number of actual lw spectral bands computed ! ! NSWLWBD - total number of sw+lw bands computed ! ! ! -! external module variables: (in physparam) ! -! ivflip - control flag for direction of vertical index ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! ! module variable: (set by subroutine aer_init) ! ! ! ! usage: call aer_property_gocart ! @@ -4253,7 +4391,7 @@ subroutine aer_property_gocart & ! --- inputs: integer, intent(in) :: IMAX, NLAY, NLP1 logical, intent(in) :: laersw, laerlw - + real (kind=kind_phys), intent(in) :: con_rd real (kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, & & prslk, tvly, rhlay, dz, hz real (kind=kind_phys), dimension(:), intent(in) :: alon, alat, & @@ -4265,6 +4403,9 @@ subroutine aer_property_gocart & real (kind=kind_phys), dimension(:,:,:,:), intent(out) :: & & aerosw, aerolw real (kind=kind_phys), dimension(:,:) , intent(out) :: aerodp + real (kind=kind_phys), dimension(:,:) , intent(out) :: ext550 + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! --- locals: real (kind=kind_phys), dimension(nlay,nswlwbd):: tauae,ssaae,asyae @@ -4279,6 +4420,11 @@ subroutine aer_property_gocart & ! !===> ... begin here ! + +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + lab_do_IMAXg : do i = 1, IMAX ! --- initialize tauae, ssaae, asyae @@ -4342,6 +4488,7 @@ subroutine aer_property_gocart & ! --- update diagnostic aod arrays do k = 1, NLAY aerodp(i,1) = aerodp(i,1) + tauae_550(k,1) + ext550(i,k) = tauae_550(k,1) do m = 1, NSPC aerodp(i,m+1) = aerodp(i,m+1)+spcodp(k,m) enddo diff --git a/physics/radiation_astronomy.f b/physics/radiation_astronomy.f index 1d60c74ef..b25c89a8c 100644 --- a/physics/radiation_astronomy.f +++ b/physics/radiation_astronomy.f @@ -21,7 +21,7 @@ ! input: ! ! ( jdate,kyear,deltsw,deltim,lsol_chg, me ) ! ! output: ! -! ( slag,sdec,cdec,solcon ) ! +! ( slag,sdec,cdec,solcon,errmsg,errflg) ! ! ! ! 'coszmn' -- compute cosin of zenith angles ! ! input: ! @@ -29,11 +29,6 @@ ! output: ! ! ( coszen,coszdg ) ! ! ! -! ! -! external modules referenced: ! -! 'module physparam' in 'physparam.f' ! -! 'module physcons' in 'physcons.f' ! -! ! ! program history log: ! ! - a collection of programs to track solar-earth position ! ! may 1977 --- ray orzol (gfdl) created program compjd to ! @@ -93,8 +88,7 @@ !> This module sets up astronomy quantities for solar radiation calculations. module module_radiation_astronomy ! - use physparam, only : isolar, solar_file, kind_phys - use physcons, only : con_solr, con_solr_old, con_pi + use machine, only : kind_phys use module_iounitdef, only : NIRADSF ! implicit none @@ -107,17 +101,17 @@ module module_radiation_astronomy ! & VTAGAST='NCEP-Radiation_astronomy v5.1 Nov 2012 ' ! Parameter constants - real (kind=kind_phys), parameter :: degrad = 180.0/con_pi - real (kind=kind_phys), parameter :: tpi = 2.0 * con_pi - real (kind=kind_phys), parameter :: hpi = 0.5 * con_pi + real (kind=kind_phys) :: degrad + real (kind=kind_phys) :: tpi + real (kind=kind_phys) :: hpi + real (kind=kind_phys) :: pid12 real (kind=kind_phys), parameter :: f12 = 12.0 real (kind=kind_phys), parameter :: f3600 = 3600.0 real (kind=kind_phys), parameter :: czlimt = 0.0001 ! ~ cos(89.99427) - real (kind=kind_phys), parameter :: pid12 = con_pi/f12 ! angle per hour ! real (kind=kind_phys), parameter :: pid12 = (2.0*asin(1.0))/f12 ! Module variable (to be set in module_radiation_astronomy::sol_init): - real (kind=kind_phys), public :: solc0 = con_solr + real (kind=kind_phys), public :: solc0 integer :: isolflg = 10 character(26) :: solar_fname = ' ' @@ -133,7 +127,6 @@ module module_radiation_astronomy real (kind=kind_phys) :: anginc=0.0 ! saved monthly solar constants (isolflg=4 only) real (kind=kind_phys) :: smon_sav(12) - data smon_sav(1:12) / 12*con_solr / ! saved year of data used integer :: iyr_sav =0 @@ -152,7 +145,7 @@ module module_radiation_astronomy !!\param me print message control flag !>\section sol_init_gen sol_init General Algorithm subroutine sol_init & - & ( me ) ! --- inputs + & ( me, isolar, solar_file, con_solr, con_solr_old, con_pi ) ! --- inputs ! --- outputs: ( none ) ! =================================================================== ! @@ -161,18 +154,16 @@ subroutine sol_init & ! ! ! inputs: ! ! me - print message control flag ! -! ! -! outputs: (to module variable) ! -! ( none ) ! -! ! -! external module variable: (in physparam) ! -! isolar - = 0: use the old fixed solar constant in "physcon" ! -! =10: use the new fixed solar constant in "physcon" ! +! isolar - = 0: use the old fixed solar constant in "GFS_typedefs" ! +! =10: use the new fixed solar constant in "GFS_typedefs" ! ! = 1: use noaa ann-mean tsi tbl abs-scale with cyc apprx ! ! = 2: use noaa ann-mean tsi tbl tim-scale with cyc apprx ! ! = 3: use cmip5 ann-mean tsi tbl tim-scale with cyc apprx! ! = 4: use cmip5 mon-mean tsi tbl tim-scale with cyc apprx! -! solar_file- external solar constant data table ! +! solar_file - external solar constant data table ! +! ! +! outputs: (to module variable) ! +! ( none ) ! ! ! ! internal module variable: ! ! isolflg - internal solar constant scheme control flag ! @@ -189,23 +180,33 @@ subroutine sol_init & implicit none ! --- input: - integer, intent(in) :: me - + integer, intent(in) :: me, isolar + character(len=26), intent(in) :: solar_file + real(kind=kind_phys), intent(in) :: con_solr, con_solr_old, con_pi ! --- output: ( none ) ! --- local: logical :: file_exist + integer :: imonth ! !===> ... begin here ! if ( me == 0 ) print *, VTAGAST !print out version tag + degrad = 180.0/con_pi + tpi = 2.0 * con_pi + hpi = 0.5 * con_pi + pid12 = con_pi/f12 + ! --- initialization isolflg = isolar solc0 = con_solr solar_fname = solar_file iyr_sav = 0 nstp = 6 + do imonth = 1,12 + smon_sav(imonth) = con_solr + enddo if ( isolar == 0 ) then solc0 = con_solr_old @@ -326,7 +327,7 @@ end subroutine sol_init !----------------------------------- subroutine sol_update & & ( jdate,kyear,deltsw,deltim,lsol_chg, me, & ! --- inputs - & slag, sdec, cdec, solcon & ! --- outputs + & slag, sdec, cdec, solcon, con_pi, errmsg, errflg & ! --- outputs & ) ! =================================================================== ! @@ -348,6 +349,8 @@ subroutine sol_update & ! slag - equation of time in radians ! ! sdec, cdec - sin and cos of the solar declination angle ! ! solcon - sun-earth distance adjusted solar constant (w/m2) ! +! errmsg - CCPP error message ! +! errflg - CCPP error flag ! ! ! ! ! ! module variable: ! @@ -381,10 +384,12 @@ subroutine sol_update & integer, intent(in) :: jdate(:), kyear, me logical, intent(in) :: lsol_chg - real (kind=kind_phys), intent(in) :: deltsw, deltim + real (kind=kind_phys), intent(in) :: deltsw, deltim, con_pi ! --- output: real (kind=kind_phys), intent(out) :: slag, sdec, cdec, solcon + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: real (kind=kind_phys), parameter :: hrday = 1.0/24.0 ! frc day/hour @@ -403,6 +408,10 @@ subroutine sol_update & ! !===> ... begin here ! +! Initialize the CCPP error handling variables + errmsg = '' + errflg = 0 + ! --- ... forecast time iyear = jdate(1) imon = jdate(2) @@ -425,7 +434,10 @@ subroutine sol_update & inquire (file=solar_fname, exist=file_exist) if ( .not. file_exist ) then print *,' !!! ERROR! Can not find solar constant file!!!' - stop + errflg = 1 + errmsg = "ERROR(radiation_astronomy): solar constant file"//& + & " not found" + return else iyr = iyear @@ -580,7 +592,7 @@ subroutine sol_update & !> -# Call solar() call solar & ! --- inputs: - & ( jd, fjd, & + & ( jd, fjd, con_pi, & ! --- outputs: & r1, dlt, alp & & ) @@ -644,7 +656,7 @@ end subroutine sol_update !>\section solar_gen solar General Algorithm !----------------------------------- subroutine solar & - & ( jd, fjd, & ! --- inputs + & ( jd, fjd, con_pi, & ! --- inputs & r1, dlt, alp & ! --- outputs & ) @@ -676,7 +688,7 @@ subroutine solar & implicit none ! --- inputs: - real (kind=kind_phys), intent(in) :: fjd + real (kind=kind_phys), intent(in) :: fjd, con_pi integer, intent(in) :: jd ! --- outputs: diff --git a/physics/radiation_cloud_overlap.F90 b/physics/radiation_cloud_overlap.F90 index d6169b3e5..737b9be61 100644 --- a/physics/radiation_cloud_overlap.F90 +++ b/physics/radiation_cloud_overlap.F90 @@ -4,7 +4,7 @@ !>\defgroup rad_cld_ovr_mod Radiation Cloud Overlap Module !! This module contains the calculation of cloud overlap parameters for both RRTMG and RRTMGP. module module_radiation_cloud_overlap - use physparam, only : kind_phys + use machine, only : kind_phys implicit none public :: cmp_dcorr_lgth diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index bf255ce00..ca9ea6e81 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -16,7 +16,7 @@ ! inputs: ! ! ( si, NLAY, imp_physics, me ) ! ! outputs: ! -! ( none ) ! +! ( errflg, errmsg ) ! ! ! ! 'radiation_clouds_prop' --- radiation cloud properties ! ! obtained from various cloud schemes ! @@ -29,8 +29,8 @@ ! imp_physics, imp_physics_nssl, imp_physics_fer_hires, ! ! imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, ! ! imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, ! -! imp_physics_mg, iovr_rand, iovr_maxrand, iovr_max, ! -! iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, ! +! imp_physics_mg, iovr, iovr_rand, iovr_maxrand, iovr_max, ! +! iovr_dcorr, iovr_exp, iovr_exprand, idcor, idcor_con, ! ! idcor_hogan, idcor_oreopoulos, ! ! imfdeepcnv, imfdeepcnv_gf, do_mynnedmf, lgfdlmprad, ! ! uni_cld, lmfshal, lmfdeep2, cldcov, clouds1, ! @@ -68,12 +68,8 @@ ! ** fu's scheme need to be normalized by snow density (g/m**3/1.0e6)! ! ! ! external modules referenced: ! -! ! -! 'module physparam' in 'physparam.f' ! -! 'module physcons' in 'physcons.f' ! ! 'module module_microphysics' in 'module_bfmicrophysics.f' ! ! ! -! ! ! program history log: ! ! nov 1992, y.h., k.a.c, a.k. - cloud parameterization ! ! 'cldjms' patterned after slingo and slingo's work (jgr, ! @@ -169,13 +165,6 @@ !> This module computes cloud related quantities for radiation computations. module module_radiation_clouds ! - use physparam, only : icldflg, iovr, idcor, & - & lcrick, lcnorm, lnoprec, & - & ivflip - use physcons, only : con_fvirt, con_ttp, con_rocp, & - & con_t0c, con_pi, con_g, con_rd, & - & con_thgni, decorr_con - use module_microphysics, only : rsipath2 use module_iounitdef, only : NICLTUN use module_radiation_cloud_overlap, only: cmp_dcorr_lgth, & & get_alpha_exper @@ -191,9 +180,7 @@ module module_radiation_clouds ! & VTAGCLD='NCEP-Radiation_clouds v5.0 Aug 2012 ' ! --- set constant parameters - real (kind=kind_phys), parameter :: gfac=1.0e5/con_g & - &, gord=con_g/con_rd - + real (kind=kind_phys) :: gfac,gord integer, parameter, public :: NF_CLDS = 9 !< number of fields in cloud array integer, parameter, public :: NK_CLDS = 3 !< number of cloud vertical domains @@ -265,10 +252,7 @@ module module_radiation_clouds !!\param me print control flag !>\section cld_init General Algorithm subroutine cld_init & - & ( si, NLAY, imp_physics, me ) ! --- inputs -! --- outputs: -! ( none ) - + & ( si, NLAY, imp_physics, me, con_g, con_rd, errflg, errmsg ) ! =================================================================== ! ! ! ! abstract: cld_init is an initialization program for cloud-radiation ! @@ -280,31 +264,12 @@ subroutine cld_init & ! NLAY : vertical layer number ! ! imp_physics : MP identifier ! ! me : print control flag ! +! imp_physics : cloud microphysics scheme control flag ! ! ! -! outputs: (none) ! -! to module variables ! +! outputs: ! +! errflg : CCPP error flag ! +! errmsg : CCPP error message ! ! ! -! external module variables: (in physparam) ! -! icldflg : cloud optical property scheme control flag ! -! =0: abort! diagnostic cloud method discontinued ! -! =1: model use prognostic cloud method ! -! imp_physics : cloud microphysics scheme control flag ! -! =99: zhao/carr/sundqvist microphysics cloud ! -! =98: zhao/carr/sundqvist microphysics cloud+pdfcld! -! =11: GFDL microphysics cloud ! -! =8: Thompson microphysics ! -! =6: WSM6 microphysics ! -! =10: MG microphysics ! -! iovr : control flag for cloud overlapping scheme ! -! =0: random overlapping clouds ! -! =1: max/ran overlapping clouds ! -! =2: maximum overlap clouds (mcica only) ! -! =3: decorrelation-length overlap (mcica only) ! -! =4: exponential cloud overlap (AER; mcica only) ! -! =5: exponential-random overlap (AER; mcica only) ! -! ivflip : control flag for direction of vertical index ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! ! usage: call cld_init ! ! ! ! subroutines called: rhtable ! @@ -316,71 +281,51 @@ subroutine cld_init & ! --- inputs: integer, intent(in) :: NLAY, me, imp_physics - real (kind=kind_phys), intent(in) :: si(:) + real (kind=kind_phys), intent(in) :: si(:), con_g, con_rd -! --- outputs: (none) - -! --- locals: - integer :: k, kl, ier +! --- outputs: + integer, intent(out) :: errflg + character(len=*), intent(out) :: errmsg ! !===> ... begin here ! -! --- set up module variables - - if (me == 0) print *, VTAGCLD !print out version tag - - if ( icldflg == 0 ) then - print *,' - Diagnostic Cloud Method has been discontinued' - stop - - else - if (me == 0) then - print *,' - Using Prognostic Cloud Method' - if (imp_physics == 99) then +! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! Initialze module parameters + gfac = 1.0e5/con_g + gord = con_g/con_rd + + if (me == 0) then + print *, VTAGCLD !print out version tag + print *,' - Using Prognostic Cloud Method' + if (imp_physics == 99) then print *,' --- Zhao/Carr/Sundqvist microphysics' - elseif (imp_physics == 98) then + elseif (imp_physics == 98) then print *,' --- zhao/carr/sundqvist + pdf cloud' - elseif (imp_physics == 11) then + elseif (imp_physics == 11) then print *,' --- GFDL Lin cloud microphysics' - elseif (imp_physics == 8) then + elseif (imp_physics == 8) then print *,' --- Thompson cloud microphysics' - elseif (imp_physics == 6) then + elseif (imp_physics == 6) then print *,' --- WSM6 cloud microphysics' - elseif (imp_physics == 10) then + elseif (imp_physics == 10) then print *,' --- MG cloud microphysics' - elseif (imp_physics == 15) then + elseif (imp_physics == 15) then print *,' --- Ferrier-Aligo cloud microphysics' - elseif (imp_physics == 17) then + elseif (imp_physics == 17) then print *,' --- NSSL cloud microphysics' - else + else print *,' !!! ERROR in cloud microphysc specification!!!', & & ' imp_physics (NP3D) =',imp_physics - stop - endif - endif + errflg = 1 + errmsg = 'ERROR(cld_init): cloud mp specification is not'// & + & ' valid' + return + endif endif - -!> - Compute the top of BL cld (llyr), which is the topmost non -!! cld(low) layer for stratiform (at or above lowest 0.1 of the -!! atmosphere). - - if ( ivflip == 0 ) then ! data from toa to sfc - lab_do_k0 : do k = NLAY, 2, -1 - kl = k - if (si(k) < 0.9e0) exit lab_do_k0 - enddo lab_do_k0 - - llyr = kl - else ! data from sfc to top - lab_do_k1 : do k = 2, NLAY - kl = k - if (si(k) < 0.9e0) exit lab_do_k1 - enddo lab_do_k1 - - llyr = kl - 1 - endif ! end_if_ivflip - ! return !................................... @@ -394,20 +339,21 @@ subroutine radiation_clouds_prop & & ( plyr, plvl, tlyr, tvly, qlyr, qstl, rhly, & ! --- inputs: & ccnd, ncndl, cnvw, cnvc, tracer1, & & xlat, xlon, slmsk, dz, delp, IX, LM, NLAY, NLP1, & - & deltaq, sup, me, icloud, kdt, & + & deltaq, sup, dcorr_con, me, icloud, kdt, & & ntrac, ntcw, ntiw, ntrw, ntsw, ntgl, ntclamt, & & imp_physics, imp_physics_nssl, imp_physics_fer_hires, & & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & & imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, & - & imp_physics_mg, iovr_rand, iovr_maxrand, iovr_max, & - & iovr_dcorr, iovr_exp, iovr_exprand, idcor_con, & - & idcor_hogan, idcor_oreopoulos, & + & imp_physics_mg, iovr, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, idcor, idcor_con, & + & idcor_hogan, idcor_oreopoulos, lcrick, lcnorm, & & imfdeepcnv, imfdeepcnv_gf, do_mynnedmf, lgfdlmprad, & & uni_cld, lmfshal, lmfdeep2, cldcov, clouds1, & & effrl, effri, effrr, effrs, effr_in, & & effrl_inout, effri_inout, effrs_inout, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, latdeg, julian, yearlen, gridkm, & + & dzlay, latdeg, julian, yearlen, gridkm, top_at_1, si, & + & con_ttp, con_pi, con_g, con_rd, con_thgni, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, & ! --- outputs: & cld_rwp, cld_rerain, cld_swp, cld_resnow, & & clds, mtop, mbot, de_lgth, alpha & @@ -490,15 +436,17 @@ subroutine radiation_clouds_prop & ! imp_physics_zhao_carr : Zhao-Carr microphysics scheme ! ! imp_physics_zhao_carr_pdf : Zhao-Carr microphysics scheme with PDF clouds ! imp_physics_mg : Morrison-Gettelman microphysics scheme ! -! iovr_rand : choice of cloud-overlap: random (=0) -! iovr_maxrand : choice of cloud-overlap: maximum random (=1) -! iovr_max : choice of cloud-overlap: maximum (=2) -! iovr_dcorr : choice of cloud-overlap: decorrelation length (=3) -! iovr_exp : choice of cloud-overlap: exponential (=4) -! iovr_exprand : choice of cloud-overlap: exponential random (=5) -! idcor_con : choice for decorrelation-length: Use constant value (=0) -! idcor_hogan : choice for decorrelation-length: (=1) -! idcor_oreopoulos: choice for decorrelation-length: (=2) +! iovr : choice of cloud-overlap ! +! iovr_rand : flag of cloud-overlap: random (=0) ! +! iovr_maxrand : flag of cloud-overlap: maximum random (=1) ! +! iovr_max : flag of cloud-overlap: maximum (=2) ! +! iovr_dcorr : flag of cloud-overlap: decorrelation length(=3) ! +! iovr_exp : flag of cloud-overlap: exponential (=4) ! +! iovr_exprand : flag of cloud-overlap: exponential random (=5) ! +! idcor : choice for decorrelation-length ! +! idcor_con : flag for decorrelation-length: Use constant value (=0) +! idcor_hogan : flag for decorrelation-length: (=1) ! +! idcor_oreopoulos: flag for decorrelation-length: (=2) ! ! imfdeepcnv : flag for mass-flux deep convection scheme ! ! imfdeepcnv_gf : flag for scale- & aerosol-aware Grell-Freitas scheme (GSD) ! do_mynnedmf : flag for MYNN-EDMF ! @@ -506,6 +454,7 @@ subroutine radiation_clouds_prop & ! uni_cld : logical - true for cloud fraction from shoc ! ! lmfshal : logical - true for mass flux shallow convection ! ! lmfdeep2 : logical - true for mass flux deep convection ! +! top_at_1 : logical - true if ordered from toa-2-sfc ! ! cldcov : layer cloud fraction (used when uni_cld=.true. ! ! clouds1 : layer total cloud fraction ! effrl, : effective radius for liquid water @@ -524,7 +473,15 @@ subroutine radiation_clouds_prop & ! latdeg(ix) : latitude (in degrees 90 -> -90) ! ! julian : day of the year (fractional julian day) ! ! yearlen : current length of the year (365/366 days) ! -! gridkm : grid length in km +! gridkm : grid length in km ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -542,20 +499,7 @@ subroutine radiation_clouds_prop & ! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! ! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! ! de_lgth(ix) : clouds decorrelation length (km) ! -! alpha(ix,nlay) : alpha decorrelation parameter -! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! +! alpha(ix,nlay) : alpha decorrelation parameter ! ! ! ! ==================== end of description ===================== ! implicit none @@ -577,19 +521,21 @@ subroutine radiation_clouds_prop & & imp_physics_mg ! Flag for MG scheme integer, intent(in) :: & + & iovr, ! & iovr_rand, ! Flag for random cloud overlap method & iovr_maxrand, ! Flag for maximum-random cloud overlap method & iovr_max, ! Flag for maximum cloud overlap method & iovr_dcorr, ! Flag for decorrelation-length cloud overlap method & iovr_exp, ! Flag for exponential cloud overlap method & iovr_exprand, ! Flag for exponential-random cloud overlap method + & idcor, & idcor_con, & idcor_hogan, & idcor_oreopoulos - logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, effr_in - logical, intent(in) :: do_mynnedmf, lgfdlmprad + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, effr_in, & + & do_mynnedmf, lgfdlmprad, top_at_1, lcrick, lcnorm real (kind=kind_phys), dimension(:,:,:), intent(in) :: ccnd, & & tracer1 @@ -597,9 +543,10 @@ subroutine radiation_clouds_prop & & tlyr, tvly, qlyr, qstl, rhly, cnvw, cnvc, cldcov, & & delp, dz, effrl, effri, effrr, effrs, dzlay, clouds1 - real (kind=kind_phys), intent(in) :: sup + real (kind=kind_phys), intent(in) :: sup, dcorr_con, con_ttp, & + & con_pi, con_g, con_rd, con_thgni real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & - & slmsk + & slmsk, si real(kind=kind_phys), dimension(:), intent(in) :: latdeg, gridkm real(kind=kind_phys), intent(in) :: julian @@ -677,7 +624,7 @@ subroutine radiation_clouds_prop & & IX, NLAY, NLP1, cldcov, & & effrl, effri, effrr, effrs, effr_in, & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -688,7 +635,7 @@ subroutine radiation_clouds_prop & & lmfshal, lmfdeep2, & & cldcov, effrl, effri, effrr, effrs, effr_in, & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -700,8 +647,8 @@ subroutine radiation_clouds_prop & & qstl, rhly, ccnd(1:IX,1:NLAY,1), cnvw, cnvc, & & xlat, xlon, slmsk, dz, delp, IX, NLAY, NLP1, & & deltaq, sup, kdt, me, dzlay, & - & cldtot, cldcnv, & ! inout - & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs + & cldtot, cldcnv, lcrick, lcnorm, con_thgni, & ! inout + & con_ttp, cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -712,7 +659,7 @@ subroutine radiation_clouds_prop & & qstl, rhly, ccnd(1:IX,1:NLAY,1), cnvw, cnvc, & & xlat, xlon, slmsk, cldcov, dz, delp, & & IX, NLAY, NLP1, dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -722,7 +669,7 @@ subroutine radiation_clouds_prop & & xlon, slmsk, dz,delp, IX, NLAY, NLP1, cldcov, & & effrl, effri, effrr, effrs, effr_in, & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -744,7 +691,7 @@ subroutine radiation_clouds_prop & & cldcov(:,1:NLAY),effrl_inout(:,:), & & effri_inout(:,:), effrs_inout(:,:), & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcnorm, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -767,7 +714,7 @@ subroutine radiation_clouds_prop & & cld_frac, & & effrl, effri, effrr, effrs, effr_in , & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -776,13 +723,13 @@ subroutine radiation_clouds_prop & call progcld_thompson_wsm6 (plyr,plvl,tlyr,qlyr,qstl, & ! --- inputs & rhly,tracer1,xlat,xlon,slmsk,dz,delp, & & ntrac-1, ntcw-1,ntiw-1,ntrw-1, & - & ntsw-1,ntgl-1, & + & ntsw-1,ntgl-1,con_ttp, & & IX, NLAY, NLP1, uni_cld, lmfshal, lmfdeep2, & & cldcov(:,1:NLAY), cnvw, effrl_inout, & & effri_inout, effrs_inout, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcnorm, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -800,7 +747,7 @@ subroutine radiation_clouds_prop & & IX, LM, NLP1, uni_cld, lmfshal, lmfdeep2, & & cldcov(:,1:LM), effrl, effri, effrs, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, gridkm, & + & dzlay, gridkm, top_at_1, & & cldtot, cldcnv, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & @@ -822,7 +769,7 @@ subroutine radiation_clouds_prop & & cld_frac, & & effrl, effri, effrr, effrs, effr_in , & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcrick, lcnorm, con_ttp, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -839,7 +786,7 @@ subroutine radiation_clouds_prop & & IX, LM, NLP1, uni_cld, lmfshal, lmfdeep2, & & cldcov(:,1:LM), effrl, effri, effrs, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, gridkm, & + & dzlay, gridkm, top_at_1, & & cldtot, cldcnv, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & @@ -849,12 +796,12 @@ subroutine radiation_clouds_prop & call progcld_thompson_wsm6 (plyr,plvl,tlyr,qlyr,qstl, & ! --- inputs & rhly,tracer1,xlat,xlon,slmsk,dz,delp, & & ntrac-1, ntcw-1,ntiw-1,ntrw-1, & - & ntsw-1,ntgl-1, & + & ntsw-1,ntgl-1,con_ttp, & & IX, NLAY, NLP1, uni_cld, lmfshal, lmfdeep2, & & cldcov(:,1:NLAY), cnvw, effrl, effri, effrs, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & & dzlay, & - & cldtot, cldcnv, & ! inout + & cldtot, cldcnv, lcnorm, & ! inout & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, & & cld_resnow) @@ -889,7 +836,7 @@ subroutine radiation_clouds_prop & call cmp_dcorr_lgth(ix, latdeg, julian, yearlen, de_lgth) endif if (idcor == idcor_con) then - de_lgth(:) = decorr_con + de_lgth(:) = dcorr_con endif ! Call subroutine get_alpha_exper to define alpha parameter for exponential cloud overlap options @@ -914,8 +861,8 @@ subroutine radiation_clouds_prop & call gethml & ! --- inputs: & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & - & IX, NLAY, iovr_rand, iovr_maxrand, iovr_max, & - & iovr_dcorr, iovr_exp, iovr_exprand, & + & IX, NLAY, iovr, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, top_at_1, si, & ! --- outputs: & clds, mtop, mbot & & ) @@ -932,7 +879,7 @@ subroutine progcld_zhao_carr & & xlat,xlon,slmsk,dz,delp, IX, NLAY, NLP1, & & uni_cld, lmfshal, lmfdeep2, cldcov, & & effrl,effri,effrr,effrs,effr_in, & - & dzlay, cldtot, cldcnv, & + & dzlay, cldtot, cldcnv, lcrick, lcnorm, con_ttp, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -949,9 +896,7 @@ subroutine progcld_zhao_carr & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld_zhao_carr ! -! ! -! subprograms called: gethml ! +! usage: call progcld_zhao_carr ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -987,6 +932,14 @@ subroutine progcld_zhao_carr & ! effrs : effective radius for snow water ! effr_in : logical, if .true. use input effective radii ! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -1000,19 +953,6 @@ subroutine progcld_zhao_carr & ! *** cld_swp (:,:) - layer snow flake water path not assigned ! ! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none @@ -1020,7 +960,8 @@ subroutine progcld_zhao_carr & ! --- inputs integer, intent(in) :: IX, NLAY, NLP1 - logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, effr_in + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, effr_in, & + & lcrick, lcnorm real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, tvly, qlyr, qstl, rhly, clw, cldcov, delp, dz, & @@ -1028,6 +969,7 @@ subroutine progcld_zhao_carr & real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk + real (kind=kind_phys), intent(in) :: con_ttp ! --- inputs/outputs @@ -1236,7 +1178,7 @@ subroutine progcld_zhao_carr_pdf & & xlat,xlon,slmsk, dz, delp, & & ix, nlay, nlp1, & & deltaq,sup,kdt,me, & - & dzlay, cldtot, cldcnv, & + & dzlay, cldtot, cldcnv, lcrick, lcnorm, con_thgni, con_ttp, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -1253,9 +1195,7 @@ subroutine progcld_zhao_carr_pdf & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld_zhao_carr_pdf ! -! ! -! subprograms called: gethml ! +! usage: call progcld_zhao_carr_pdf ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -1286,6 +1226,12 @@ subroutine progcld_zhao_carr_pdf & ! deltaq(ix,nlay) : half total water distribution width ! ! sup : supersaturation ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! lcrick : control flag for eliminating crick ! +! =t: apply layer smoothing to eliminate crick ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -1299,28 +1245,18 @@ subroutine progcld_zhao_carr_pdf & ! *** cld_swp (:,:) - layer snow flake water path not assigned ! ! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lcrick : control flag for eliminating crick ! -! =t: apply layer smoothing to eliminate crick ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none ! --- inputs integer, intent(in) :: ix, nlay, nlp1,kdt - + logical, intent(in) :: lcrick, lcnorm real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, tvly, qlyr, qstl, rhly, clw, dz, delp, dzlay ! & tlyr, tvly, qlyr, qstl, rhly, clw, cnvw, cnvc ! real (kind=kind_phys), dimension(:,:), intent(in) :: deltaq + real (kind=kind_phys), intent(in) :: con_thgni, con_ttp real (kind=kind_phys), dimension(:,:) :: deltaq, cnvw, cnvc real (kind=kind_phys) qtmp,qsc,rhs real (kind=kind_phys), intent(in) :: sup @@ -1416,7 +1352,7 @@ subroutine progcld_zhao_carr_pdf & do k = 1, nlay do i = 1, ix tem1 = tlyr(i,k) - 273.16 - if(tem1 < con_thgni) then ! for pure ice, has to be consistent with gscond + if(tem1 < (con_thgni - 273.16)) then ! for pure ice, has to be consistent with gscond qsc = sup * qstl(i,k) rhs = sup else @@ -1536,7 +1472,7 @@ subroutine progcld_gfdl_lin & & ( plyr,plvl,tlyr,tvly,qlyr,qstl,rhly,clw,cnvw,cnvc, & ! --- inputs: & xlat,xlon,slmsk,cldtot, dz, delp, & & IX, NLAY, NLP1, & - & dzlay, cldtot1, cldcnv, & + & dzlay, cldtot1, cldcnv, lcrick, lcnorm, con_ttp, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -1553,9 +1489,7 @@ subroutine progcld_gfdl_lin & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld_gfdl_lin ! -! ! -! subprograms called: gethml ! +! usage: call progcld_gfdl_lin ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -1584,6 +1518,12 @@ subroutine progcld_gfdl_lin & ! IX : horizontal dimention ! ! NLAY,NLP1 : vertical layer/level dimensions ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -1597,28 +1537,17 @@ subroutine progcld_gfdl_lin & ! *** cld_swp (:,:) - layer snow flake water path not assigned ! ! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lsashal : control flag for shallow convection ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none ! --- inputs integer, intent(in) :: IX, NLAY, NLP1 - + logical, intent(in) :: lcrick, lcnorm real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, tvly, qlyr, qstl, rhly, clw, cldtot, cnvw, cnvc, & & delp, dz, dzlay + real (kind=kind_phys) :: con_ttp real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk @@ -1786,7 +1715,7 @@ subroutine progcld_fer_hires & & IX, NLAY, NLP1, icloud, & & uni_cld, lmfshal, lmfdeep2, cldcov, & & re_cloud,re_ice,re_snow, & - & dzlay, cldtot, cldcnv, & + & dzlay, cldtot, cldcnv, lcnorm, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -1803,9 +1732,7 @@ subroutine progcld_fer_hires & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld_fer_hires ! -! ! -! subprograms called: gethml ! +! usage: call progcld_fer_hires ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -1837,6 +1764,14 @@ subroutine progcld_fer_hires & ! lmfdeep2 : logical - true for mass flux deep convection ! ! cldcov : layer cloud fraction (used when uni_cld=.true. ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -1850,19 +1785,6 @@ subroutine progcld_fer_hires & ! *** cld_swp (:,:) - layer snow flake water path not assigned ! ! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none @@ -1871,7 +1793,7 @@ subroutine progcld_fer_hires & integer, intent(in) :: IX, NLAY, NLP1, ICLOUD integer, intent(in) :: ntrac, ntcw, ntiw, ntrw - logical, intent(in) :: uni_cld, lmfshal, lmfdeep2 + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, lcnorm real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, tvly, qlyr, qstl, rhly, cldcov, delp, dz, dzlay @@ -2036,12 +1958,12 @@ end subroutine progcld_fer_hires subroutine progcld_thompson_wsm6 & & ( plyr,plvl,tlyr,qlyr,qstl,rhly,clw, & ! --- inputs: & xlat,xlon,slmsk,dz,delp, & - & ntrac,ntcw,ntiw,ntrw,ntsw,ntgl, & + & ntrac,ntcw,ntiw,ntrw,ntsw,ntgl,con_ttp, & & IX, NLAY, NLP1, & & uni_cld, lmfshal, lmfdeep2, cldcov, cnvw, & & re_cloud,re_ice,re_snow, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, cldtot, cldcnv, & + & dzlay, cldtot, cldcnv, lcnorm, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -2059,9 +1981,7 @@ subroutine progcld_thompson_wsm6 & ! top and base. the three vertical cloud domains are set up in the ! ! initial subroutine "cld_init". ! ! ! -! usage: call progcld_thompson_wsm6 ! -! ! -! subprograms called: gethml ! +! usage: call progcld_thompson_wsm6 ! ! ! ! attributes: ! ! language: fortran 90 ! @@ -2092,6 +2012,14 @@ subroutine progcld_thompson_wsm6 & ! lmfshal : logical - true for mass flux shallow convection ! ! lmfdeep2 : logical - true for mass flux deep convection ! ! cldcov : layer cloud fraction (used when uni_cld=.true. ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -2110,19 +2038,6 @@ subroutine progcld_thompson_wsm6 & ! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! ! de_lgth(ix) : clouds decorrelation length (km) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none @@ -2131,7 +2046,7 @@ subroutine progcld_thompson_wsm6 & integer, intent(in) :: IX, NLAY, NLP1 integer, intent(in) :: ntrac, ntcw, ntiw, ntrw, ntsw, ntgl - logical, intent(in) :: uni_cld, lmfshal, lmfdeep2 + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, lcnorm real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, qlyr, qstl, rhly, cldcov, delp, dz, dzlay, & @@ -2143,7 +2058,7 @@ subroutine progcld_thompson_wsm6 & real (kind=kind_phys), dimension(:), intent(in) :: xlat, xlon, & & slmsk - + real (kind=kind_phys), intent(in) :: con_ttp ! --- inputs/outputs real (kind=kind_phys), dimension(:,:), intent(inout) :: & @@ -2212,10 +2127,16 @@ subroutine progcld_thompson_wsm6 & !> The total condensate includes convective condensate. do k = 1, NLAY-1 do i = 1, IX - cwp(i,k) = max(0.0, (clw(i,k,ntcw)+cnvw(i,k)* - & (1.-tem2d(i,k))) * gfac * delp(i,k)) - cip(i,k) = max(0.0, (clw(i,k,ntiw) + cnvw(i,k)* - & tem2d(i,k)) *gfac * delp(i,k)) + tem1 = cnvw(i,k)*(1.-tem2d(i,k)) + cwp(i,k) = max(0.0, (clw(i,k,ntcw)+tem1) * + & gfac * delp(i,k)) + if(tem1 > 1.e-12 .and. clw(i,k,ntcw) < 1.e-12) + & rew(i,k)=reliq_def + tem2 = cnvw(i,k)*tem2d(i,k) + cip(i,k) = max(0.0, (clw(i,k,ntiw) + tem2 ) + & *gfac * delp(i,k)) + if(tem2 > 1.e-12 .and. clw(i,k,ntiw) < 1.e-12) + & rei(i,k)=reice_def crp(i,k) = max(0.0, clw(i,k,ntrw) * gfac * delp(i,k)) csp(i,k) = max(0.0, clw(i,k,ntsw) * gfac * delp(i,k)) enddo @@ -2336,7 +2257,7 @@ subroutine progcld_thompson & & uni_cld, lmfshal, lmfdeep2, cldcov, & & re_cloud,re_ice,re_snow, & & lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - & dzlay, gridkm, cldtot, cldcnv, & + & dzlay, gridkm, top_at_1, cldtot, cldcnv, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -2355,8 +2276,6 @@ subroutine progcld_thompson & ! ! ! usage: call progcld_thompson ! ! ! -! subprograms called: gethml ! -! ! ! attributes: ! ! language: fortran 90 ! ! machine: ibm-sp, sgi ! @@ -2386,7 +2305,16 @@ subroutine progcld_thompson & ! uni_cld : logical - true for cloud fraction from shoc ! ! lmfshal : logical - true for mass flux shallow convection ! ! lmfdeep2 : logical - true for mass flux deep convection ! +! top_at_1 : logical - true if vertical ordereing is toa-2-sfc ! ! cldcov : layer cloud fraction (used when uni_cld=.true. ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -2400,19 +2328,6 @@ subroutine progcld_thompson & ! *** cld_swp (:,:) - layer snow flake water path not assigned ! ! cld_resnow(:,:) - mean eff radius for snow flake (micron) ! ! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! -! ! ! ==================== end of description ===================== ! ! implicit none @@ -2421,7 +2336,7 @@ subroutine progcld_thompson & integer, intent(in) :: IX, NLAY, NLP1 integer, intent(in) :: ntrac, ntcw, ntiw, ntrw, ntsw, ntgl - logical, intent(in) :: uni_cld, lmfshal, lmfdeep2 + logical, intent(in) :: uni_cld, lmfshal, lmfdeep2, top_at_1 real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr, & & tlyr, qlyr, qstl, rhly, cldcov, delp, dz, dzlay, & @@ -2525,7 +2440,7 @@ subroutine progcld_thompson & cldfra1d(:) = 0.0 - if (ivflip .eq. 1) then + if (.not. top_at_1) then do k = 1, NLAY qv1d(k) = qlyr(i,k) qc1d(k) = max(0.0, clw(i,k,ntcw)) @@ -2619,7 +2534,7 @@ subroutine progclduni & & ( plyr,plvl,tlyr,tvly,ccnd,ncnd, & ! --- inputs: & xlat,xlon,slmsk,dz,delp, IX, NLAY, NLP1, cldtot, & & effrl,effri,effrr,effrs,effr_in, & - & dzlay, cldtot1, cldcnv, & + & dzlay, cldtot1, cldcnv, lcrick, lcnorm, con_ttp, & & cld_frac, cld_lwp, cld_reliq, cld_iwp, & ! --- outputs & cld_reice,cld_rwp, cld_rerain,cld_swp, cld_resnow & & ) @@ -2641,8 +2556,6 @@ subroutine progclduni & ! ! ! usage: call progclduni ! ! ! -! subprograms called: gethml ! -! ! ! attributes: ! ! language: fortran 90 ! ! machine: ibm-sp, sgi ! @@ -2673,6 +2586,14 @@ subroutine progclduni & ! dz (ix,nlay) : layer thickness (km) ! ! delp (ix,nlay) : model layer pressure thickness in mb (100Pa) ! ! dzlay(ix,nlay) : thickness between model layer centers (km) ! +! lmfshal : mass-flux shallow conv scheme flag ! +! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! +! lcrick : control flag for eliminating CRICK ! +! =t: apply layer smoothing to eliminate CRICK ! +! =f: do not apply layer smoothing ! +! lcnorm : control flag for in-cld condensate ! +! =t: normalize cloud condensate ! +! =f: not normalize cloud condensate ! ! ! ! output variables: ! ! cloud profiles: ! @@ -2690,20 +2611,7 @@ subroutine progclduni & ! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! ! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! ! de_lgth(ix) : clouds decorrelation length (km) ! -! alpha(ix,nlay) : alpha decorrelation parameter -! ! -! module variables: ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! lmfshal : mass-flux shallow conv scheme flag ! -! lmfdeep2 : scale-aware mass-flux deep conv scheme flag ! -! lcrick : control flag for eliminating CRICK ! -! =t: apply layer smoothing to eliminate CRICK ! -! =f: do not apply layer smoothing ! -! lcnorm : control flag for in-cld condensate ! -! =t: normalize cloud condensate ! -! =f: not normalize cloud condensate ! +! alpha(ix,nlay) : alpha decorrelation parameter ! ! ! ! ==================== end of description ===================== ! ! @@ -2711,8 +2619,9 @@ subroutine progclduni & ! --- inputs integer, intent(in) :: IX, NLAY, NLP1, ncnd - logical, intent(in) :: effr_in + logical, intent(in) :: effr_in, lcrick, lcnorm + real (kind=kind_phys), intent(in) :: con_ttp real (kind=kind_phys), dimension(:,:,:), intent(in) :: ccnd real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, plyr,& & tlyr, tvly, cldtot, effrl, effri, effrr, effrs, dz, delp, & @@ -2930,8 +2839,8 @@ end subroutine progclduni !>\section detail Detailed Algorithm subroutine gethml & & ( plyr, ptop1, cldtot, cldcnv, dz, de_lgth, alpha, & ! --- inputs: - & IX, NLAY, iovr_rand, iovr_maxrand, iovr_max, & - & iovr_dcorr, iovr_exp, iovr_exprand, & + & IX, NLAY, iovr, iovr_rand, iovr_maxrand, iovr_max, & + & iovr_dcorr, iovr_exp, iovr_exprand, top_at_1, si, & & clds, mtop, mbot & ! --- outputs: & ) @@ -2969,13 +2878,7 @@ subroutine gethml & ! output variables: ! ! clds (IX,5) : fraction of clouds for low, mid, hi, tot, bl ! ! mtop (IX,3) : vertical indices for low, mid, hi cloud tops ! -! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! -! ! -! external module variables: (in physparam) ! -! ivflip : control flag of vertical index direction ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! +! mbot (IX,3) : vertical indices for low, mid, hi cloud bases ! ! ! internal module variables: ! ! iovr : control flag for cloud overlap ! ! =0 random overlapping clouds ! @@ -2990,8 +2893,10 @@ subroutine gethml & implicit none! ! --- inputs: + logical, intent(in) :: top_at_1 integer, intent(in) :: IX, NLAY integer, intent(in) :: & + & iovr, ! & iovr_rand, ! Flag for random cloud overlap method & iovr_maxrand, ! Flag for maximum-random cloud overlap method & iovr_max, ! Flag for maximum cloud overlap method @@ -3001,7 +2906,7 @@ subroutine gethml & real (kind=kind_phys), dimension(:,:), intent(in) :: plyr, ptop1, & & cldtot, cldcnv, dz - real (kind=kind_phys), dimension(:), intent(in) :: de_lgth + real (kind=kind_phys), dimension(:), intent(in) :: de_lgth, si real (kind=kind_phys), dimension(:,:), intent(in) :: alpha ! --- outputs @@ -3014,11 +2919,30 @@ subroutine gethml & real (kind=kind_phys) :: pcur, pnxt, ccur, cnxt, alfa integer, dimension(IX):: idom, kbt1, kth1, kbt2, kth2 - integer :: i, k, id, id1, kstr, kend, kinc + integer :: i, k, id, id1, kstr, kend, kinc,kl ! !===> ... begin here ! +!> - Compute the top of BL cld (llyr), which is the topmost non +!! cld(low) layer for stratiform (at or above lowest 0.1 of the +!! atmosphere). + + if (top_at_1) then ! data from toa to sfc + lab_do_k0 : do k = NLAY, 2, -1 + kl = k + if (si(k) < 0.9e0) exit lab_do_k0 + enddo lab_do_k0 + llyr = kl + else ! data from sfc to top + lab_do_k1 : do k = 2, NLAY + kl = k + if (si(k) < 0.9e0) exit lab_do_k1 + enddo lab_do_k1 + + llyr = kl - 1 + endif ! end_if_top_at_1 + clds(:,:) = 0.0 do i = 1, IX @@ -3032,7 +2956,7 @@ subroutine gethml & !> - Calculate total and BL cloud fractions (maximum-random cloud !! overlapping is operational). - if ( ivflip == 0 ) then ! input data from toa to sfc + if (top_at_1) then ! input data from toa to sfc kstr = NLAY kend = 1 kinc = -1 @@ -3040,7 +2964,7 @@ subroutine gethml & kstr = 1 kend = NLAY kinc = 1 - endif ! end_if_ivflip + endif ! end_if_top_at_1 if ( iovr == iovr_rand ) then ! random overlap @@ -3174,7 +3098,7 @@ subroutine gethml & !> - Calculte high, mid, low cloud fractions and vertical indices of !! cloud tops/bases. - if ( ivflip == 0 ) then ! input data from toa to sfc + if (top_at_1) then ! input data from toa to sfc do i = 1, IX cl1 (i) = 0.0 @@ -3338,7 +3262,7 @@ subroutine gethml & enddo ! end_do_i_loop enddo ! end_do_k_loop - endif ! end_if_ivflip + endif ! end_if_top_at_1 ! return diff --git a/physics/radiation_gases.f b/physics/radiation_gases.f index c958fc243..ccc3b598a 100644 --- a/physics/radiation_gases.f +++ b/physics/radiation_gases.f @@ -19,13 +19,13 @@ ! input: ! ! ( me ) ! ! output: ! -! ( none ) ! +! ( errflg, errmsg ) ! ! ! ! 'gas_update' -- read in data and update with time ! ! input: ! ! ( iyear, imon, iday, ihour, loz1st, ldoco2, me ) ! ! output: ! -! ( none ) ! +! ( errflg, errmsg ) ! ! ! ! 'getozn' -- setup climatological ozone profile ! ! input: ! @@ -44,7 +44,6 @@ ! external modules referenced: ! ! 'module machine' in 'machine.f' ! ! 'module funcphys' in 'funcphys.f' ! -! 'module physcons' in 'physcons.f ! ! 'module module_iounitdef' in 'iounitdef.f' ! ! ! ! unit used for radiative active gases: ! @@ -81,7 +80,7 @@ ! nov 2008 - y-t hou fix bugs in superimposing climatology ! ! seasonal cycle calculations ! ! aug 2011 - y-t hou fix a bug in subr getgases doing vertical ! -! co2 mapping. (for iflip=0 case, not affact opr). ! +! co2 mapping. (for top_at_1 case, not affact opr). ! ! aug 2012 - y-t hou modified subr getozn. moved the if-first ! ! block to subr gas_init to ensure threading safe in ! ! climatology ozone applications. (not affect gfs) ! @@ -141,13 +140,8 @@ !> This module sets up ozone climatological profiles and other constant gas !! profiles, such as co2, ch4, n2o, o2, and those of cfc gases. module module_radiation_gases -! - use physparam, only : ico2flg, ictmflg, ioznflg, ivflip, & - & co2dat_file, co2gbl_file, & - & co2usr_file, co2cyc_file, & - & kind_phys, kind_io4 + use machine, only : kind_phys, kind_io4 use funcphys, only : fpkapx - use physcons, only : con_pi use ozne_def, only : JMR => latsozc, LOZ => levozc, & & blte => blatc, dlte=> dphiozc, & & timeozc => timeozc @@ -168,9 +162,9 @@ module module_radiation_gases integer, parameter :: MINYEAR = 1957 ! earlist year 2D CO2 data available real (kind=kind_phys), parameter :: resco2=15.0 ! horizontal resolution in degree - real (kind=kind_phys), parameter :: raddeg=180.0/con_pi ! rad->deg conversion real (kind=kind_phys), parameter :: prsco2=788.0 ! pressure limitation for 2D CO2 (mb) - real (kind=kind_phys), parameter :: hfpi =0.5*con_pi ! half of pi + real (kind=kind_phys) :: raddeg ! rad->deg conversion + real (kind=kind_phys) :: hfpi ! half of pi real (kind=kind_phys), parameter :: co2vmr_def = 350.0e-6 ! parameter constant for CO2 volume mixing ratio real (kind=kind_phys), parameter :: n2ovmr_def = 0.31e-6 ! parameter constant for N2O volume mixing ratio @@ -227,48 +221,54 @@ module module_radiation_gases !> This subroutine sets up ozone, co2, etc. parameters. If climatology !! ozone then read in monthly ozone data. -!!\param me print message control flag +!!\param me print message control flag +!!\param co2usr_file co2 user defined data table +!!\param co2cyc_file co2 climotology monthly cycle data table +!!\param ictmflg data ic time/date control flag +!!\param ico2flg co2 data source control flag +!!\param ioznflg ozone data control flag +!!\param con_pi physical constant Pi +!!\param errflg error flag +!!\param errmsg error message !>\section gas_init_gen gas_init General Algorithm !----------------------------------- - subroutine gas_init & - & ( me )! --- inputs: -! --- outputs: ( none ) + subroutine gas_init( me, co2usr_file, co2cyc_file, ico2flg, & + & ictmflg, ioznflg, con_pi, errflg, errmsg) ! =================================================================== ! ! ! ! gas_init sets up ozone, co2, etc. parameters. if climatology ozone ! ! then read in monthly ozone data. ! ! ! -! inputs: dimemsion ! -! me - print message control flag 1 ! -! ! -! outputs: (to the module variables) ! -! ( none ) ! -! ! -! external module variables: (in physparam) ! -! ico2flg - co2 data source control flag ! +! inputs: ! +! me - print message control flag ! +! ico2flg - co2 data source control flag ! ! =0: use prescribed co2 global mean value ! ! =1: use input global mean co2 value (co2_glb) ! ! =2: use input 2-d monthly co2 value (co2vmr_sav) ! -! ictmflg - =yyyy#, data ic time/date control flag ! -! = -2: same as 0, but superimpose seasonal cycle ! -! from climatology data set. ! -! = -1: use user provided external data for the fcst ! -! time, no extrapolation. ! -! = 0: use data at initial cond time, if not existed! -! then use latest, without extrapolation. ! -! = 1: use data at the forecast time, if not existed! -! then use latest and extrapolate to fcst time.! -! =yyyy0: use yyyy data for the forecast time, no ! -! further data extrapolation. ! -! =yyyy1: use yyyy data for the fcst. if needed, do ! -! extrapolation to match the fcst time. ! -! ioznflg - ozone data control flag ! +! ictmflg - =yyyy#, data ic time/date control flag ! +! =-2: same as 0, but superimpose seasonal cycle ! +! from climatology data set. ! +! =-1: use user provided external data for the fcst ! +! time, no extrapolation. ! +! =0: use data at initial cond time, if not existed ! +! then use latest, without extrapolation. ! +! =1: use data at the forecast time, if not existed ! +! then use latest and extrapolate to fcst time. ! +! =yyyy0: use yyyy data for the forecast time, no ! +! further data extrapolation. ! +! =yyyy1: use yyyy data for the fcst. if needed, do ! +! extrapolation to match the fcst time. ! +! ioznflg - ozone data control flag ! ! =0: use climatological ozone profile ! -! >0: use interactive ozone profile ! -! ivflip - vertical profile indexing flag ! -! co2usr_file- external co2 user defined data table ! -! co2cyc_file- external co2 climotology monthly cycle data table ! +! >0: use interactive ozone profile ! +! co2usr_file - external co2 user defined data table ! +! co2cyc_file - external co2 climotology monthly cycle data table ! +! con_pi - physical constant Pi ! +! ! +! outputs: (CCPP error handling) ! +! errflg - error flag ! +! errmsg - error message ! ! ! ! internal module variables: ! ! pkstr, o3r - arrays for climatology ozone data ! @@ -282,9 +282,12 @@ subroutine gas_init & implicit none ! --- inputs: - integer, intent(in) :: me - -! --- output: ( none ) + integer, intent(in) :: me, ictmflg, ioznflg, ico2flg + character(len=26),intent(in) :: co2usr_file,co2cyc_file + real(kind=kind_phys), intent(in) :: con_pi +! --- output: + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: real (kind=kind_phys), dimension(IMXCO2,JMXCO2) :: co2dat @@ -300,6 +303,15 @@ subroutine gas_init & ! !===> ... begin here ! + +! Initialize the CCPP error handling variables + errmsg = '' + errflg = 0 + +! Initiailize module parameters + raddeg = 180.0/con_pi + hfpi = 0.5*con_pi + if ( me == 0 ) print *, VTAGGAS ! print out version tag kyrsav = 0 @@ -316,7 +328,10 @@ subroutine gas_init & print *,' - Using climatology ozone distribution' print *,' timeozc=',timeozc, ' is not monthly mean', & & ' - job aborting in subroutin gas_init!!!' - stop + errflg = 1 + errmsg = 'ERROR(gas_init): Climatological o3 distribution '// & + & 'is not monthly mean' + return endif allocate (pkstr(LOZ), o3r(JMR,LOZ,12)) @@ -391,9 +406,10 @@ subroutine gas_init & inquire (file=co2usr_file, exist=file_exist) if ( .not. file_exist ) then - print *,' Can not find user CO2 data file: ',co2usr_file, & - & ' - Stopped in subroutine gas_init !!' - stop + print *,' Can not find user CO2 data file: ',co2usr_file + errflg = 1 + errmsg = 'ERROR(gas_init): Can not find user CO2 data file' + return else close (NICO2CN) open(NICO2CN,file=co2usr_file,form='formatted',status='old') @@ -434,9 +450,10 @@ subroutine gas_init & enddo endif else - print *,' ICO2=',ico2flg,' is not a valid selection', & - & ' - Stoped in subroutine gas_init!!!' - stop + print *,' ICO2=',ico2flg,' is not a valid selection' + errflg = 1 + errmsg = 'ERROR(gas_init): ICO2 is not valid' + return endif ! endif_ico2flg_block close (NICO2CN) @@ -455,9 +472,10 @@ subroutine gas_init & print *,' - Using observed co2 monthly 2-d data' endif else - print *,' ICO2=',ico2flg,' is not a valid selection', & - & ' - Stoped in subroutine gas_init!!!' - stop + print *,' ICO2=',ico2flg,' is not a valid selection' + errflg = 1 + errmsg = 'ERROR(gas_init): ICO2 is not valid' + return endif if ( ictmflg == -2 ) then @@ -465,9 +483,12 @@ subroutine gas_init & if ( .not. file_exist ) then if ( me == 0 ) then print *,' Can not find seasonal cycle CO2 data: ', & - & co2cyc_file,' - Stopped in subroutine gas_init !!' + & co2cyc_file endif - stop + errflg = 1 + errmsg = 'ERROR(gas_init): Can not find seasonal cycle '//& + & 'CO2 data' + return else allocate( co2cyc_sav(IMXCO2,JMXCO2,12) ) @@ -517,18 +538,25 @@ end subroutine gas_init !> This subroutine reads in 2-d monthly co2 data set for a specified !! year. Data are in a 15 degree lat/lon horizontal resolution. -!!\param iyear year of the requested data for fcst -!!\param imon month of the year -!!\param iday day of the month -!!\param ihour hour of the day -!!\param loz1st clim ozone 1st time update control flag -!!\param ldoco2 co2 update control flag -!!\param me print message control flag +!!\param iyear year of the requested data for fcst +!!\param imon month of the year +!!\param iday day of the month +!!\param ihour hour of the day +!!\param loz1st clim ozone 1st time update control flag +!!\param ldoco2 co2 update control flag +!!\param me print message control flag +!!\param co2dat_file co2 2d monthly obsv data table +!!\param co2gbl_file co2 global annual mean data table +!!\param ictmflg data ic time/date control flag +!!\param ico2flg co2 data source control flag +!!\param ioznflg ozone data control flag +!!\param errflg error flag +!!\param errmsg error message !>\section gen_gas_update gas_update General Algorithm !----------------------------------- - subroutine gas_update & - & ( iyear, imon, iday, ihour, loz1st, ldoco2, me )! --- inputs -! --- outputs: ( none ) + subroutine gas_update(iyear, imon, iday, ihour, loz1st, ldoco2, & + & me, co2dat_file, co2gbl_file, ictmflg, ico2flg, ioznflg, & + & errflg, errmsg ) ! =================================================================== ! ! ! @@ -536,41 +564,40 @@ subroutine gas_update & ! data are in a 15 degree lat/lon horizontal resolution. ! ! ! ! inputs: dimemsion ! -! iyear - year of the requested data for fcst 1 ! -! imon - month of the year 1 ! -! iday - day of the month 1 ! -! ihour - hour of the day 1 ! -! loz1st - clim ozone 1st time update control flag 1 ! -! ldoco2 - co2 update control flag 1 ! -! me - print message control flag 1 ! -! ! -! outputs: (to the module variables) ! -! ( none ) ! -! ! -! external module variables: (in physparam) ! -! ico2flg - co2 data source control flag ! +! iyear - year of the requested data for fcst 1 ! +! imon - month of the year 1 ! +! iday - day of the month 1 ! +! ihour - hour of the day 1 ! +! loz1st - clim ozone 1st time update control flag 1 ! +! ldoco2 - co2 update control flag 1 ! +! me - print message control flag 1 ! +! ico2flg - co2 data source control flag ! ! =0: use prescribed co2 global mean value ! ! =1: use input global mean co2 value (co2_glb) ! ! =2: use input 2-d monthly co2 value (co2vmr_sav) ! -! ictmflg - =yyyy#, data ic time/date control flag ! -! = -2: same as 0, but superimpose seasonal cycle ! -! from climatology data set. ! -! = -1: use user provided external data for the fcst ! -! time, no extrapolation. ! -! = 0: use data at initial cond time, if not existed! -! then use latest, without extrapolation. ! -! = 1: use data at the forecast time, if not existed! -! then use latest and extrapolate to fcst time.! -! =yyyy0: use yyyy data for the forecast time, no ! -! further data extrapolation. ! -! =yyyy1: use yyyy data for the fcst. if needed, do ! -! extrapolation to match the fcst time. ! -! ioznflg - ozone data control flag ! +! ictmflg - =yyyy#, data ic time/date control flag ! +! =-2: same as 0, but superimpose seasonal cycle ! +! from climatology data set. ! +! =-1: use user provided external data for the fcst ! +! time, no extrapolation. ! +! =0: use data at initial cond time, if not existed ! +! then use latest, without extrapolation. ! +! =1: use data at the forecast time, if not existed ! +! then use latest and extrapolate to fcst time. ! +! =yyyy0: use yyyy data for the forecast time, no ! +! further data extrapolation. ! +! =yyyy1: use yyyy data for the fcst. if needed, do ! +! extrapolation to match the fcst time. ! +! ioznflg - ozone data control flag ! ! =0: use climatological ozone profile ! ! >0: use interactive ozone profile ! -! ivflip - vertical profile indexing flag ! -! co2dat_file- external co2 2d monthly obsv data table ! -! co2gbl_file- external co2 global annual mean data table ! +! ivflip - vertical profile indexing flag ! +! co2dat_file - external co2 2d monthly obsv data table ! +! co2gbl_file - external co2 global annual mean data table ! +! ! +! outputs: (CCPP error handling) ! +! errflg - error flag ! +! errmsg - error message ! ! ! ! internal module variables: ! ! co2vmr_sav - monthly co2 volume mixing ratio IMXCO2*JMXCO2*12 ! @@ -589,11 +616,14 @@ subroutine gas_update & implicit none ! --- inputs: - integer, intent(in) :: iyear, imon, iday, ihour, me - + integer, intent(in) :: iyear,imon,iday,ihour,me,ictmflg,ico2flg + integer, intent(in) :: ioznflg + character(len=26),intent(in) :: co2dat_file, co2gbl_file logical, intent(in) :: loz1st, ldoco2 -! --- output: ( none ) +! --- output: + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: real (kind=kind_phys), dimension(IMXCO2,JMXCO2) :: co2dat, co2ann @@ -610,6 +640,10 @@ subroutine gas_update & ! !===> ... begin here ! +! Initialize the CCPP error handling variables + errmsg = '' + errflg = 0 + !> - Ozone data section if ( ioznflg == 0 ) then @@ -680,8 +714,11 @@ subroutine gas_update & inquire (file=co2gbl_file, exist=file_exist) if ( .not. file_exist ) then print *,' Requested co2 data file "',co2gbl_file, & - & '" not found - Stopped in subroutine gas_update!!' - stop + & '" not found' + errflg = 1 + errmsg = 'ERROR(gas_update): Requested co2 data file not '// & + & 'found' + return else close(NICO2CN) open (NICO2CN,file=co2gbl_file,form='formatted',status='old') @@ -748,9 +785,11 @@ subroutine gas_update & if ( me == 0 ) then print *,' Specified co2 data for year',idyr, & & ' not found !! Need to change namelist ICTM !!' - print *,' *** Stopped in subroutine gas_update !!' endif - stop + errflg = 1 + errmsg = 'ERROR(gas_update): Specified co2 data for year '//& + & 'not found' + return else Lab_if_ictm ! looking for latest available data if ( me == 0 ) then print *,' Requested co2 data for year',idyr, & @@ -774,9 +813,11 @@ subroutine gas_update & if ( .not. file_exist ) then if ( me == 0 ) then print *,' Can not find co2 data source file' - print *,' *** Stopped in subroutine gas_update !!' endif - stop + errflg = 1 + errmsg = 'ERROR(gas_update): Can not find co2 data '// & + & 'source file' + return endif endif Lab_if_ictm endif ! end if_file_exist_block @@ -907,6 +948,9 @@ end subroutine gas_update !! pi/2 -> -pi/2, otherwise see in-line comment !!\param IMAX horizontal dimension for output data !!\param LMAX vertical dimension for output data +!!\param ico2flg (1), co2 data source control flag +!!\param top_at_1 (1), vertical ordering flag +!!\param con_pi (1), physical constant Pi !!\param gasdat (IMAX,LMAX,NF_VGAS) - gases volume mixing ratioes !!\n (:,:,1) - co2 !!\n (:,:,2) - n2o @@ -918,13 +962,16 @@ end subroutine gas_update !!\n (:,:,8) - cfc22 !!\n (:,:,9) - ccl4 !!\n (:,:,10) - cfc113 +!!\n +!> - Internal module variables : +!!\n co2vmr_sav - saved monthly co2 concentration from sub gas_update +!!\n co2_glb - saved global annual mean co2 value from gas_update +!!\n gco2cyc - saved global seasonal variation of co2 climatology +!! in 12-month form !>\section gen_getgases getgases General Algorithm !----------------------------------- - subroutine getgases & - & ( plvl, xlon, xlat, & ! --- inputs - & IMAX, LMAX, & - & gasdat & ! --- outputs - & ) + subroutine getgases( plvl, xlon, xlat, IMAX, LMAX, ico2flg, & + & top_at_1, con_pi, gasdat) ! =================================================================== ! ! ! ! getgases set up global distribution of radiation absorbing gases ! @@ -939,6 +986,12 @@ subroutine getgases & ! xlat(IMAX) - grid latitude in radians, default range to ! ! pi/2 -> -pi/2, otherwise see in-line comment ! ! IMAX, LMAX - horiz, vert dimensions for output data ! +! ico2flg - co2 data source control flag ! +! =0: use prescribed co2 global mean value ! +! =1: use input global mean co2 value (co2_glb) ! +! =2: use input 2-d monthly co2 value (co2vmr_sav)! +! top_at_1 - vertical profile indexing flag ! +! con_pi - physical constant Pi ! ! ! ! outputs: ! ! gasdat(IMAX,LMAX,NF_VGAS) - gases volume mixing ratioes ! @@ -953,19 +1006,7 @@ subroutine getgases & ! (:,:,9) - ccl4 ! ! (:,:,10) - cfc113 ! ! ! -!> - External module variables: (in physparam) -!!\n ico2flg - co2 data source control flag -!!\n =0: use prescribed co2 global mean value -!!\n =1: use input global mean co2 value (co2_glb) -!!\n =2: use input 2-d monthly co2 value (co2vmr_sav) -!!\n ivflip - vertical profile indexing flag -!! -!> - Internal module variables : -!!\n co2vmr_sav - saved monthly co2 concentration from sub gas_update -!!\n co2_glb - saved global annual mean co2 value from gas_update -!!\n gco2cyc - saved global seasonal variation of co2 climatology -!! in 12-month form -!note: for lower atmos co2vmr_sav may have clim monthly deviations ! +! note: for lower atmos co2vmr_sav may have clim monthly deviations ! ! superimposed on init-cond co2 value, while co2_glb only ! ! contains the global mean value, thus needs to add the ! ! monthly dglobal mean deviation gco2cyc at upper atmos. for ! @@ -980,8 +1021,10 @@ subroutine getgases & implicit none ! --- input: - integer, intent(in) :: IMAX, LMAX + integer, intent(in) :: IMAX, LMAX, ico2flg real (kind=kind_phys), intent(in) :: plvl(:,:), xlon(:), xlat(:) + logical, intent(in) :: top_at_1 + real(kind=kind_phys), intent(in) :: con_pi ! --- output: real (kind=kind_phys), intent(out) :: gasdat(:,:,:) @@ -1035,7 +1078,7 @@ subroutine getgases & ilon = min( IMXCO2, int( xlon1*tmp + 1 )) ilat = min( JMXCO2, int( xlat1*tmp + 1 )) - if ( ivflip == 0 ) then ! index from toa to sfc + if (top_at_1) then ! index from toa to sfc do k = 1, LMAX if ( plvl(i,k) >= prsco2 ) then gasdat(i,k,1) = co2vmr_sav(ilon,ilat,kmonsav) @@ -1066,16 +1109,13 @@ end subroutine getgases !!\param prslk (IMAX,LM), exner function = \f$(p/p0)^{rocp}\f$ !!\param xlat (IMAX), latitude in radians, default to pi/2 -> !! -pi/2 range, otherwise see in-line comment -!!\param IMAX, LM horizontal and vertical dimensions +!!\param IMAX, LM (1), horizontal and vertical dimensions +!!\param top_at_1 (1), vertical profile indexing flag !!\param o3mmr (IMAX,LM), output ozone profile in mass mixing !! ratio (g/g) !>\section getozn_gen getozn General Algorithm !----------------------------------- - subroutine getozn & - & ( prslk,xlat, & ! --- inputs - & IMAX, LM, & - & o3mmr & ! --- outputs - & ) + subroutine getozn( prslk,xlat, IMAX, LM, top_at_1, o3mmr) ! =================================================================== ! ! ! @@ -1088,6 +1128,7 @@ subroutine getozn & ! xlat (IMAX) - latitude in radians, default to pi/2 -> -pi/2 ! ! range, otherwise see in-line comment ! ! IMAX, LM - horizontal and vertical dimensions ! +! top_at_1 - vertical profile indexing flag ! ! ! ! outputs: ! ! o3mmr (IMAX,LM) - output ozone profile in mass mixing ratio (g/g)! @@ -1095,7 +1136,6 @@ subroutine getozn & ! module variables: ! ! k1oz, k2oz - ozone data interpolation indices ! ! facoz - ozone data interpolation factor ! -! ivflip - control flag for direction of vertical index ! ! ! ! usage: call getozn ! ! ! @@ -1105,7 +1145,7 @@ subroutine getozn & ! --- inputs: integer, intent(in) :: IMAX, LM - + logical, intent(in) :: top_at_1 real (kind=kind_phys), intent(in) :: prslk(:,:), xlat(:) ! --- outputs: @@ -1149,7 +1189,7 @@ subroutine getozn & do l = 1, LM ll = l - if (ivflip == 1) ll = LM -l + 1 + if (.not. top_at_1) ll = LM -l + 1 do i = 1, IMAX wk1(i) = prslk(i,ll) diff --git a/physics/radiation_surface.f b/physics/radiation_surface.f index 2fea84b5f..299f2e92c 100644 --- a/physics/radiation_surface.f +++ b/physics/radiation_surface.f @@ -104,9 +104,7 @@ !! emissivity for LW radiation. module module_radiation_surface ! - use physparam, only : ialbflg, iemsflg, semis_file, & - & kind_phys - use physcons, only : con_t0c, con_ttp, con_pi, con_tice + use machine, only : kind_phys use module_iounitdef, only : NIRADSF use surface_perturbation, only : ppfbet ! @@ -125,7 +123,7 @@ module module_radiation_surface real (kind=kind_phys), parameter :: f_zero = 0.0 real (kind=kind_phys), parameter :: f_one = 1.0 real (kind=kind_phys), parameter :: epsln = 1.0e-6 - real (kind=kind_phys), parameter :: rad2dg = 180.0 / con_pi + real (kind=kind_phys) :: rad2dg integer, allocatable :: idxems(:,:) ! global surface emissivity index array integer :: iemslw = 1 ! global surface emissivity control flag set up in 'sfc_init' ! @@ -141,7 +139,7 @@ module module_radiation_surface !>\section gen_sfc_init sfc_init General Algorithm !----------------------------------- subroutine sfc_init & - & ( me, errmsg, errflg )! --- inputs/outputs: + & ( me, ialbflg, iemsflg, semis_file, con_pi, errmsg, errflg )! --- inputs/outputs: ! ! =================================================================== ! ! ! @@ -155,11 +153,7 @@ subroutine sfc_init & ! ==================== defination of variables ==================== ! ! ! ! inputs: ! -! me - print control flag ! -! ! -! outputs: (none) to module variables only ! -! ! -! external module variables: ! +! me - print control flag ! ! ialbflg - control flag for surface albedo schemes ! ! =1: use modis based surface albedo ! ! =2: use surface albedo from land model ! @@ -169,13 +163,18 @@ subroutine sfc_init & ! b:=1 use varying climtology sfc emiss (veg based) ! ! =2 use surface emissivity from land model ! ! ! +! outputs: (CCPP error handling) ! +! errmsg - CCPP error message ! +! errflg - CCPP error flag ! +! ! ! ==================== end of description ===================== ! ! implicit none ! --- inputs: - integer, intent(in) :: me - + integer, intent(in) :: me, ialbflg, iemsflg + real(kind=kind_phys), intent(in) :: con_pi + character(len=26), intent(in) :: semis_file ! --- outputs: ( none ) character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -191,10 +190,13 @@ subroutine sfc_init & errmsg = '' errflg = 0 ! + ! Module + rad2dg = 180.0 / con_pi + if ( me == 0 ) print *, VTAGSFC ! print out version tag !> - Initialization of surface albedo section -!! \n physparam::ialbflg +!! \n GFS_typedefs::ialbflg !! - = 1: using MODIS based land surface albedo for SW !! - = 2: using albedo from land model @@ -219,6 +221,9 @@ subroutine sfc_init & endif ! end if_ialbflg_block !> - Initialization of surface emissivity section +!! \n GFS_typedefs::iemsflg +!! - = 1: input SFC emissivity type map from "semis_file" +!! - = 2: input SFC emissivity from land model iemslw = mod(iemsflg, 10) ! emissivity control @@ -344,6 +349,7 @@ subroutine setalb & & lsmalbdvis, lsmalbdnir, lsmalbivis, lsmalbinir, & & icealbdvis, icealbdnir, icealbivis, icealbinir, & & IMAX, NF_ALBD, albPpert, pertalb, fracl, fraco, fraci, icy,& + & ialbflg, con_ttp, & & sfcalb & ! --- outputs: & ) @@ -391,6 +397,9 @@ subroutine setalb & ! fice (IMAX) - sea-ice fraction ! ! tisfc (IMAX) - sea-ice surface temperature ! ! IMAX - array horizontal dimension ! +! ialbflg - control flag for surface albedo schemes ! +! =1: use modis based surface albedo ! +! =2: use surface albedo from land model ! ! ! ! outputs: ! ! sfcalb(IMAX,NF_ALBD) ! @@ -399,17 +408,12 @@ subroutine setalb & ! ( :, 3) - uv+vis direct beam albedo ! ! ( :, 4) - uv+vis diffused albedo ! ! ! -! module internal control variables: ! -! ialbflg - =0 use the default climatology surface albedo ! -! =1 use modis retrieved albedo and input snow cover! -! for land areas ! -! ! ! ==================== end of description ===================== ! ! implicit none ! --- inputs - integer, intent(in) :: IMAX, NF_ALBD + integer, intent(in) :: IMAX, NF_ALBD, ialbflg integer, intent(in) :: lsm, lsm_noahmp, lsm_ruc logical, intent(in) :: use_cice_alb, frac_grid @@ -419,7 +423,7 @@ subroutine setalb & & alvsf, alnsf, alvwf, alnwf, facsf, facwf, fice, tisfc, & & icealbdvis, icealbdnir, icealbivis, icealbinir, & & sncovr, sncovr_ice, snoalb, albPpert ! sfc-perts, mgehne - real (kind=kind_phys), intent(in) :: pertalb ! sfc-perts, mgehne + real (kind=kind_phys), intent(in) :: pertalb, con_ttp! sfc-perts, mgehne real (kind=kind_phys), dimension(:), intent(in) :: & & fracl, fraco, fraci real (kind=kind_phys), dimension(:),intent(inout) :: & diff --git a/physics/radlw_datatb.f b/physics/radlw_datatb.f index f297c8e4c..da0f5eaa3 100644 --- a/physics/radlw_datatb.f +++ b/physics/radlw_datatb.f @@ -66,7 +66,7 @@ module module_radlw_avplank ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NPLNK, NBANDS ! implicit none @@ -747,7 +747,7 @@ end module module_radlw_avplank ! module module_radlw_ref ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys ! implicit none ! @@ -924,7 +924,7 @@ end module module_radlw_ref ! module module_radlw_cldprlw ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NBANDS ! implicit none @@ -1607,7 +1607,7 @@ end module module_radlw_cldprlw ! module module_radlw_kgb01 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG01 ! implicit none @@ -2421,7 +2421,7 @@ end module module_radlw_kgb01 ! module module_radlw_kgb02 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG02 ! implicit none @@ -3278,7 +3278,7 @@ end module module_radlw_kgb02 ! module module_radlw_kgb03 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG03 ! implicit none @@ -10152,7 +10152,7 @@ end module module_radlw_kgb03 ! module module_radlw_kgb04 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG04 ! implicit none @@ -15352,7 +15352,7 @@ end module module_radlw_kgb04 ! module module_radlw_kgb05 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG05 ! implicit none @@ -21849,7 +21849,7 @@ end module module_radlw_kgb05 ! module module_radlw_kgb06 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG06 ! implicit none @@ -22109,7 +22109,7 @@ end module module_radlw_kgb06 ! module module_radlw_kgb07 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG07 ! implicit none @@ -24756,7 +24756,7 @@ end module module_radlw_kgb07 ! module module_radlw_kgb08 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG08 ! implicit none @@ -25553,7 +25553,7 @@ end module module_radlw_kgb08 ! module module_radlw_kgb09 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG09 ! implicit none @@ -28231,7 +28231,7 @@ end module module_radlw_kgb09 ! module module_radlw_kgb10 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG10 ! implicit none @@ -28705,7 +28705,7 @@ end module module_radlw_kgb10 ! module module_radlw_kgb11 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG11 ! implicit none @@ -29404,7 +29404,7 @@ end module module_radlw_kgb11 ! module module_radlw_kgb12 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG12 ! implicit none @@ -30475,7 +30475,7 @@ end module module_radlw_kgb12 ! module module_radlw_kgb13 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG13 ! implicit none @@ -31381,7 +31381,7 @@ end module module_radlw_kgb13 ! module module_radlw_kgb14 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG14 ! implicit none @@ -31605,7 +31605,7 @@ end module module_radlw_kgb14 ! module module_radlw_kgb15 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG15 ! implicit none @@ -32010,7 +32010,7 @@ end module module_radlw_kgb15 ! module module_radlw_kgb16 ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radlw_parameters, only : NG16 ! implicit none diff --git a/physics/radlw_main.F90 b/physics/radlw_main.F90 index 04609382d..7bc1ea80c 100644 --- a/physics/radlw_main.F90 +++ b/physics/radlw_main.F90 @@ -79,7 +79,6 @@ ! ! ! external modules referenced: ! ! ! -! 'module physparam' ! ! 'module physcons' ! ! 'mersenne_twister' ! ! ! @@ -278,8 +277,6 @@ !! rrtmg-lw radiation code from aer inc. module rrtmg_lw ! - use physparam, only : ilwrate, ilwrgas, ilwcliq, ilwcice, & - & isubclw, icldflg, iovr, ivflip use physcons, only : con_g, con_cp, con_avgd, con_amd, & & con_amw, con_amo3 use mersenne_twister, only : random_setseed, random_number, & @@ -425,7 +422,10 @@ subroutine rrtmg_lw_run & & gasvmr_cfc12, gasvmr_cfc22, gasvmr_ccl4, & & icseed,aeraod,aerssa,sfemis,sfgtmp, & & dzlyr,delpin,de_lgth,alpha, & - & npts, nlay, nlp1, lprnt, cld_cf, lslwr, & + & npts, nlay, nlp1, lprnt, cld_cf, lslwr, top_at_1, iovr, & + & iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, & + & iovr_exprand, & + & inc_minor_gas, ilwcliq, ilwcice, isubclw, & & hlwc,topflx,sfcflx,cldtau, & ! --- outputs & HLW0,HLWB,FLXPRF, & ! --- optional & cld_lwp, cld_ref_liq, cld_iwp, cld_ref_ice, & @@ -483,6 +483,33 @@ subroutine rrtmg_lw_run & ! npts : total number of horizontal points ! ! nlay, nlp1 : total number of vertical layers, levels ! ! lprnt : cntl flag for diagnostic print out ! +! inc_minor_gas - control flag for rare gases (ch4,n2o,o2,cfcs, etc.) ! +! =0: do not include rare gases ! +! >0: include all rare gases ! +! ilwcliq - control flag for liq-cloud optical properties ! +! =1: input cld liqp & reliq, hu & stamnes (1993) ! +! =2: not used ! +! ilwcice - control flag for ice-cloud optical properties ! +! =1: input cld icep & reice, ebert & curry (1997) ! +! =2: input cld icep & reice, streamer (1996) ! +! =3: input cld icep & reice, fu (1998) ! +! isubclw - sub-column cloud approximation control flag ! +! =0: no sub-col cld treatment, use grid-mean cld quantities ! +! =1: mcica sub-col, prescribed seeds to get random numbers ! +! =2: mcica sub-col, providing array icseed for random numbers! +! iovr - clouds vertical overlapping control flag ! +! =iovr_rand ! +! =iovr_maxrand ! +! =iovr_max ! +! =iovr_dcorr ! +! =iovr_exp ! +! =iovr_exprand ! +! iovr_rand - choice of cloud-overlap: random ! +! iovr_maxrand - choice of cloud-overlap: maximum random ! +! iovr_max - choice of cloud-overlap: maximum ! +! iovr_dcorr - choice of cloud-overlap: decorrelation length ! +! iovr_exp - choice of cloud-overlap: exponential ! +! iovr_exprand - choice of cloud-overlap: exponential random ! ! ! ! output variables: ! ! hlwc (npts,nlay): total sky heating rate (k/day or k/sec) ! @@ -508,32 +535,6 @@ subroutine rrtmg_lw_run & ! upfx0 - clear sky upward flux ! ! dnfx0 - clear sky dnward flux ! ! ! -! external module variables: (in physparam) ! -! ilwrgas - control flag for rare gases (ch4,n2o,o2,cfcs, etc.) ! -! =0: do not include rare gases ! -! >0: include all rare gases ! -! ilwcliq - control flag for liq-cloud optical properties ! -! =1: input cld liqp & reliq, hu & stamnes (1993) ! -! =2: not used ! -! ilwcice - control flag for ice-cloud optical properties ! -! =1: input cld icep & reice, ebert & curry (1997) ! -! =2: input cld icep & reice, streamer (1996) ! -! =3: input cld icep & reice, fu (1998) ! -! isubclw - sub-column cloud approximation control flag ! -! =0: no sub-col cld treatment, use grid-mean cld quantities ! -! =1: mcica sub-col, prescribed seeds to get random numbers ! -! =2: mcica sub-col, providing array icseed for random numbers! -! iovr - cloud overlapping control flag ! -! =0: random overlapping clouds ! -! =1: maximum/random overlapping clouds ! -! =2: maximum overlap cloud (used for isubclw>0 only) ! -! =3: decorrelation-length overlap (for isubclw>0 only) ! -! =4: exponential cloud overlap (AER) ! -! =5: exponential-random cloud overlap (AER) ! -! ivflip - control flag for vertical index direction ! -! =0: vertical index from toa to surface ! -! =1: vertical index from surface to toa ! -! ! ! module parameters, control variables: ! ! nbands - number of longwave spectral bands ! ! maxgas - maximum number of absorbing gaseous ! @@ -605,10 +606,12 @@ subroutine rrtmg_lw_run & ! ====================== end of definitions =================== ! ! --- inputs: - integer, intent(in) :: npts, nlay, nlp1 + integer, intent(in) :: npts, nlay, nlp1, ilwcliq, ilwcice, & + isubclw, iovr, iovr_dcorr, iovr_exp, iovr_exprand, iovr_rand,& + iovr_maxrand, iovr_max integer, intent(in) :: icseed(npts) - logical, intent(in) :: lprnt + logical, intent(in) :: lprnt, inc_minor_gas real (kind=kind_phys), dimension(:,:), intent(in) :: plvl, & & tlvl @@ -631,6 +634,7 @@ subroutine rrtmg_lw_run & real (kind=kind_phys), dimension(:,:,:),intent(in):: & & aeraod, aerssa + logical, intent(in) :: lslwr, top_at_1 ! --- outputs: real (kind=kind_phys), dimension(:,:), intent(inout) :: hlwc @@ -650,7 +654,6 @@ subroutine rrtmg_lw_run & & intent(inout) :: hlw0 type (proflw_type), dimension(:,:), optional, & & intent(inout) :: flxprf - logical, intent(in) :: lslwr ! --- locals: real (kind=kind_phys), dimension(0:nlp1) :: cldfrc @@ -790,7 +793,7 @@ subroutine rrtmg_lw_run & endif stemp = sfgtmp(iplon) ! surface ground temp - if (iovr == 3) delgth= de_lgth(iplon) ! clouds decorr-length + if (iovr == iovr_dcorr) delgth= de_lgth(iplon) ! clouds decorr-length !> -# Prepare atmospheric profile for use in rrtm. ! the vertical index of internal array is from surface to top @@ -801,7 +804,7 @@ subroutine rrtmg_lw_run & ! layer pressure thickness (in mb), based on the hydrostatic equation ! --- ... and includes a correction to account for h2o in the layer. - if (ivflip == 0) then ! input from toa to sfc + if (top_at_1) then ! input from toa to sfc tem1 = 100.0 * con_g tem2 = 1.0e-20 * 1.0e3 * con_avgd @@ -814,7 +817,7 @@ subroutine rrtmg_lw_run & tavel(k)= tlyr(iplon,k1) tz(k) = tlvl(iplon,k1) dz(k) = dzlyr(iplon,k1) - if (iovr == 4 .or. iovr == 5) alph(k) = alpha(iplon,k) ! alpha decorrelation + if (iovr == iovr_exp .or. iovr == iovr_exprand) alph(k) = alpha(iplon,k) ! alpha decorrelation !> -# Set absorber amount for h2o, co2, and o3. @@ -841,7 +844,7 @@ subroutine rrtmg_lw_run & !! cf22, convert from volume mixing ratio to molec/cm2 based on !! coldry (scaled to 1.0e-20). - if (ilwrgas > 0) then + if (inc_minor_gas) then do k = 1, nlay k1 = nlp1 - k colamt(k,4)=max(temcol(k), coldry(k)*gasvmr_n2o(iplon,k1)) ! n2o @@ -927,7 +930,7 @@ subroutine rrtmg_lw_run & tavel(k)= tlyr(iplon,k) tz(k) = tlvl(iplon,k+1) dz(k) = dzlyr(iplon,k) - if (iovr == 4 .or. iovr == 5) alph(k) = alpha(iplon,k) ! alpha decorrelation + if (iovr == iovr_exp .or. iovr == iovr_exprand) alph(k) = alpha(iplon,k) ! alpha decorrelation ! --- ... set absorber amount !test use @@ -952,7 +955,7 @@ subroutine rrtmg_lw_run & ! --- ... set up col amount for rare gases, convert from volume mixing ratio ! to molec/cm2 based on coldry (scaled to 1.0e-20) - if (ilwrgas > 0) then + if (inc_minor_gas) then do k = 1, nlay colamt(k,4)=max(temcol(k), coldry(k)*gasvmr_n2o(iplon,k)) ! n2o colamt(k,5)=max(temcol(k), coldry(k)*gasvmr_ch4(iplon,k)) ! ch4 @@ -1021,7 +1024,7 @@ subroutine rrtmg_lw_run & tem0 = 10.0 * tem2 / (amdw * tem1 * con_g) pwvcm = tem0 * plvl(iplon,1) - endif ! if_ivflip + endif ! top_at_1 !> -# Compute column amount for broadening gases. @@ -1078,6 +1081,7 @@ subroutine rrtmg_lw_run & ! --- inputs: & ( cldfrc,clwp,relw,ciwp,reiw,cda1,cda2,cda3,cda4, & & nlay, nlp1, ipseed(iplon), dz, delgth, iovr, alph, & + & ilwcliq, ilwcice, isubclw, & ! --- outputs: & cldfmc, taucld & & ) @@ -1085,7 +1089,7 @@ subroutine rrtmg_lw_run & ! --- ... save computed layer cloud optical depth for output ! rrtm band-7 is apprx 10mu channel (or use spectral mean of bands 6-8) - if (ivflip == 0) then ! input from toa to sfc + if (top_at_1) then ! input from toa to sfc do k = 1, nlay k1 = nlp1 - k cldtau(iplon,k1) = taucld( 7,k) @@ -1094,7 +1098,7 @@ subroutine rrtmg_lw_run & do k = 1, nlay cldtau(iplon,k) = taucld( 7,k) enddo - endif ! end if_ivflip_block + endif ! end if_top_at_1_block else cldfmc = f_zero @@ -1229,7 +1233,7 @@ subroutine rrtmg_lw_run & sfcflx(iplon)%dnfxc = totdflux(0) sfcflx(iplon)%dnfx0 = totdclfl(0) - if (ivflip == 0) then ! output from toa to sfc + if (top_at_1) then ! output from toa to sfc !! --- ... optional fluxes if ( lflxprf ) then @@ -1297,7 +1301,7 @@ subroutine rrtmg_lw_run & enddo endif - endif ! if_ivflip + endif ! if_top_at_1 enddo lab_do_iplon @@ -1315,9 +1319,9 @@ end subroutine rrtmg_lw_run !! spectral band are reduced from 256 g-point intervals to 140. !!\param me print control for parallel process !!\section rlwinit_gen rlwinit General Algorithm - subroutine rlwinit & - & ( me ) ! --- inputs -! --- outputs: (none) + subroutine rlwinit( me, rad_hr_units, inc_minor_gas, ilwcliq, & + isubclw, iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr,& + iovr_exp, iovr_exprand, errflg, errmsg ) ! =================== program usage description =================== ! ! ! @@ -1329,17 +1333,9 @@ subroutine rlwinit & ! ==================== defination of variables ==================== ! ! ! ! inputs: ! -! me - print control for parallel process ! -! ! -! outputs: (none) ! -! ! -! external module variables: (in physparam) ! -! ilwrate - heating rate unit selections ! -! =1: output in k/day ! -! =2: output in k/second ! -! ilwrgas - control flag for rare gases (ch4,n2o,o2,cfcs, etc.) ! -! =0: do not include rare gases ! -! >0: include all rare gases ! +! me - print control for parallel process ! +! rad_hr_units - 1 for heating rates in units K/day. 2 for K/s ! +! inc_minor_gas - flag to turn on/off minor gases in rrtmg ! ! ilwcliq - liquid cloud optical properties contrl flag ! ! =0: input cloud opt depth from diagnostic scheme ! ! >0: input cwp,rew, and other cloud content parameters ! @@ -1347,16 +1343,23 @@ subroutine rlwinit & ! =0: no sub-col cld treatment, use grid-mean cld quantities ! ! =1: mcica sub-col, prescribed seeds to get random numbers ! ! =2: mcica sub-col, providing array icseed for random numbers! -! icldflg - cloud scheme control flag ! -! =0: diagnostic scheme gives cloud tau, omiga, and g. ! -! =1: prognostic scheme gives cloud liq/ice path, etc. ! ! iovr - clouds vertical overlapping control flag ! -! =0: random overlapping clouds ! -! =1: maximum/random overlapping clouds ! -! =2: maximum overlap cloud (isubcol>0 only) ! -! =3: decorrelation-length overlap (for isubclw>0 only) ! -! =4: exponential cloud overlap (AER) ! -! =5: exponential-random cloud overlap (AER) ! +! =iovr_rand ! +! =iovr_maxrand ! +! =iovr_max ! +! =iovr_dcorr ! +! =iovr_exp ! +! =iovr_exprand ! +! iovr_rand - choice of cloud-overlap: random ! +! iovr_maxrand - choice of cloud-overlap: maximum random ! +! iovr_max - choice of cloud-overlap: maximum ! +! iovr_dcorr - choice of cloud-overlap: decorrelation length ! +! iovr_exp - choice of cloud-overlap: exponential ! +! iovr_exprand - choice of cloud-overlap: exponential random ! +! ! +! outputs: ! +! errflg - error flag ! +! errmsg - error message ! ! ! ! ******************************************************************* ! ! original code description ! @@ -1386,9 +1389,14 @@ subroutine rlwinit & ! ====================== end of description block ================= ! ! --- inputs: - integer, intent(in) :: me + integer, intent(in) :: me, rad_hr_units, ilwcliq, isubclw, iovr, & + iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, & + iovr_exprand + logical, intent(in) :: inc_minor_gas -! --- outputs: none +! --- outputs: + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: real (kind=kind_phys), parameter :: expeps = 1.e-20 @@ -1400,25 +1408,21 @@ subroutine rlwinit & ! !===> ... begin here ! - if ( iovr<0 .or. iovr>5 ) then - print *,' *** Error in specification of cloud overlap flag', & - & ' IOVR=',iovr,' in RLWINIT !!' - stop - elseif ( (iovr==2 .or. iovr==3) .and. isubclw==0 ) then - if (me == 0) then - print *,' *** IOVR=',iovr,' is not available for', & - & ' ISUBCLW=0 setting!!' - print *,' The program uses maximum/random overlap', & - & ' instead.' - endif + ! Initialize error-handling + errflg = 0 + errmsg = '' - iovr = 1 + if ((iovr .ne. iovr_rand) .and. (iovr .ne. iovr_maxrand) .and. & + (iovr .ne. iovr_max) .and. (iovr .ne. iovr_dcorr) .and. & + (iovr .ne. iovr_exp) .and. (iovr .ne. iovr_exprand)) then + errflg = 1 + errmsg = 'ERROR(rlwinit): Error in specification of cloud overlap flag' endif if (me == 0) then print *,' - Using AER Longwave Radiation, Version: ', VTAGLW - if (ilwrgas > 0) then + if (inc_minor_gas) then print *,' --- Include rare gases N2O, CH4, O2, CFCs ', & & 'absorptions in LW' else @@ -1434,22 +1438,9 @@ subroutine rlwinit & elseif ( isubclw == 2 ) then print *,' --- Using MCICA sub-colum clouds approximation ', & & 'with provided input array of permutation seeds' - else - print *,' *** Error in specification of sub-column cloud ', & - & ' control flag isubclw =',isubclw,' !!' - stop endif endif -!> -# Check cloud flags for consistency. - - if ((icldflg == 0 .and. ilwcliq /= 0) .or. & - & (icldflg == 1 .and. ilwcliq == 0)) then - print *,' *** Model cloud scheme inconsistent with LW', & - & ' radiation cloud radiative property setup !!' - stop - endif - !> -# Setup default surface emissivity for each band. semiss0(:) = f_one @@ -1461,7 +1452,7 @@ subroutine rlwinit & fluxfac = pival * 2.0d4 ! fluxfac = 62831.85307179586 ! = 2 * pi * 1.0e4 - if (ilwrate == 1) then + if (rad_hr_units == 1) then ! heatfac = 8.4391 ! heatfac = con_g * 86400. * 1.0e-2 / con_cp ! (in k/day) heatfac = con_g * 864.0 / con_cp ! (in k/day) @@ -1538,8 +1529,8 @@ end subroutine rlwinit !!\section gen_cldprop cldprop General Algorithm subroutine cldprop & & ( cfrac,cliqp,reliq,cicep,reice,cdat1,cdat2,cdat3,cdat4, & ! --- inputs - & nlay, nlp1, ipseed, dz, de_lgth, iovr, alpha, & - & cldfmc, taucld & ! --- outputs + & nlay, nlp1, ipseed, dz, de_lgth, iovr, alpha, ilwcliq, & + & ilwcice, isubclw, cldfmc, taucld & ! --- outputs & ) ! =================== program usage description =================== ! @@ -1639,7 +1630,8 @@ subroutine cldprop & use module_radlw_cldprlw ! --- inputs: - integer, intent(in) :: nlay, nlp1, ipseed, iovr + integer, intent(in) :: nlay, nlp1, ipseed, iovr, ilwcliq, ilwcice,& + isubclw real (kind=kind_phys), dimension(0:nlp1), intent(in) :: cfrac real (kind=kind_phys), dimension(nlay), intent(in) :: cliqp, & @@ -1804,7 +1796,7 @@ subroutine cldprop & endif lab_if_ilwcliq -!> -# if physparam::isubclw > 0, call mcica_subcol() to distribute +!> -# if GFS_typedefs::isubclw > 0, call mcica_subcol() to distribute !! cloud properties to each g-point. if ( isubclw > 0 ) then ! mcica sub-col clouds approx @@ -1820,7 +1812,7 @@ subroutine cldprop & call mcica_subcol & ! --- inputs: - & ( cldf, nlay, ipseed, dz, de_lgth, alpha, & + & ( cldf, nlay, ipseed, dz, de_lgth, alpha, iovr, & ! --- output: & lcloudy & & ) @@ -1853,7 +1845,7 @@ end subroutine cldprop !!\param lcloudy sub-colum cloud profile flag array !!\section mcica_subcol_gen mcica_subcol General Algorithm subroutine mcica_subcol & - & ( cldf, nlay, ipseed, dz, de_lgth, alpha, & ! --- inputs + & ( cldf, nlay, ipseed, dz, de_lgth, alpha, iovr, & ! --- inputs & lcloudy & ! --- outputs & ) @@ -1868,22 +1860,20 @@ subroutine mcica_subcol & ! for lw and sw, use values differ by the number of g-pts. ! ! dz - real, layer thickness (km) nlay ! ! de_lgth - real, layer cloud decorrelation length (km) 1 ! -! alpha - real, EXP/ER decorrelation parameter nlay ! +! alpha - real, EXP/ER decorrelation parameter nlay ! +! iovr - control flag for cloud overlapping method 1 ! +! =0:random; =1:maximum/random: =2:maximum; =3:decorr ! +! =4:exponential; =5:exponential-random ! ! ! ! output variables: ! ! lcloudy - logical, sub-colum cloud profile flag array ngptlw*nlay! ! ! -! other control flags from module variables: ! -! iovr : control flag for cloud overlapping method ! -! =0:random; =1:maximum/random: =2:maximum; =3:decorr ! -! =4:exponential; =5:exponential-random ! -! ! ! ===================== end of definitions ==================== ! implicit none ! --- inputs: - integer, intent(in) :: nlay, ipseed + integer, intent(in) :: nlay, ipseed, iovr real (kind=kind_phys), dimension(nlay), intent(in) :: cldf, dz real (kind=kind_phys), intent(in) :: de_lgth @@ -7635,7 +7625,9 @@ subroutine cldprmc(nlayers, inflag, iceflag, liqflag, cldfmc, & return elseif(inflag .eq. 1) then - stop 'INFLAG = 1 OPTION NOT AVAILABLE WITH MCICA' + errflg = 1 + errmsg = 'ERROR(rlwinit): INFLAG = 1 OPTION NOT AVAILABLE WITH MCICA' + return ! cwp = ciwpmc(ig,lay) + clwpmc(ig,lay) ! taucmc(ig,lay) = abscld1 * cwp diff --git a/physics/radlw_main.meta b/physics/radlw_main.meta index 9286c45cb..3dccc97b3 100644 --- a/physics/radlw_main.meta +++ b/physics/radlw_main.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = rrtmg_lw type = scheme - dependencies = machine.F,mersenne_twister.f,physcons.F90,physparam.f,radlw_datatb.f,radlw_param.f + dependencies = machine.F,mersenne_twister.f,physcons.F90,radlw_datatb.f,radlw_param.f ######################################################################## [ccpp-arg-table] @@ -241,6 +241,90 @@ dimensions = () type = logical intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation + units = flag + dimensions = () + type = logical + intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = flag for cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[inc_minor_gas] + standard_name = flag_to_include_minor_gases_in_rrtmg + long_name = flag to include minor trace gases in rrtmg + units = flag + dimensions = () + type = logical + intent = in +[ilwcliq] + standard_name = flag_for_optical_property_for_liquid_clouds_for_longwave_radiation + long_name = lw optical property for liquid clouds + units = flag + dimensions = () + type = integer + intent = in +[ilwcice] + standard_name = flag_for_optical_property_for_ice_clouds_for_longwave_radiation + long_name = lw optical property for ice clouds + units = flag + dimensions = () + type = integer + intent = in +[isubclw] + standard_name = flag_for_lw_clouds_sub_grid_approximation + long_name = flag for lw clouds sub-grid approximation + units = flag + dimensions = () + type = integer + intent = in [hlwc] standard_name = tendency_of_air_temperature_due_to_longwave_heating_on_radiation_time_step_and_radiation_levels long_name = longwave total sky heating rate diff --git a/physics/radlw_param.f b/physics/radlw_param.f index fa7ceecb0..bc2aae224 100644 --- a/physics/radlw_param.f +++ b/physics/radlw_param.f @@ -65,7 +65,7 @@ module module_radlw_parameters ! !! \htmlinclude module_radlw_parameters.html !! - use physparam, only : kind_phys + use machine, only : kind_phys implicit none ! diff --git a/physics/radsw_datatb.f b/physics/radsw_datatb.f index 6d88f1989..e0bb651e9 100644 --- a/physics/radsw_datatb.f +++ b/physics/radsw_datatb.f @@ -73,7 +73,7 @@ module module_radsw_ref ! !........................................! ! - use physparam, only : kind_phys + use machine, only : kind_phys ! implicit none ! @@ -217,7 +217,7 @@ module module_radsw_cldprtb ! ! ! ! ************************* end description ************************ ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : nblow, nbhgh ! implicit none @@ -2503,7 +2503,7 @@ module module_radsw_sflux ! ! ! ! ************************* end description ************************ ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NGMAX, NG16, NG17, NG18, NG19,& & NG20, NG21, NG22, NG23, NG24, & & NG25, NG26, NG27, NG28, NG29, & @@ -2838,7 +2838,7 @@ module module_radsw_kgb16 ! ! ! ! ************************ end description ************************ ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG16 ! @@ -4031,7 +4031,7 @@ module module_radsw_kgb17 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG17 ! @@ -8640,7 +8640,7 @@ module module_radsw_kgb18 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG18 ! @@ -10158,7 +10158,7 @@ module module_radsw_kgb19 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG19 ! @@ -11677,7 +11677,7 @@ module module_radsw_kgb20 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG20 ! @@ -12461,7 +12461,7 @@ module module_radsw_kgb21 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG21 ! @@ -16319,7 +16319,7 @@ module module_radsw_kgb22 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG22 ! @@ -16766,7 +16766,7 @@ module module_radsw_kgb23 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG23 ! @@ -17023,7 +17023,7 @@ module module_radsw_kgb24 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG24 ! @@ -18588,7 +18588,7 @@ module module_radsw_kgb25 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG25 ! @@ -18748,7 +18748,7 @@ module module_radsw_kgb26 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG26 ! @@ -18784,7 +18784,7 @@ module module_radsw_kgb27 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG27 ! @@ -19387,7 +19387,7 @@ module module_radsw_kgb28 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG28 ! @@ -21701,7 +21701,7 @@ module module_radsw_kgb29 ! ! ! ! ********* ********* end description ********* ********* ! ! - use physparam, only : kind_phys + use machine, only : kind_phys use module_radsw_parameters, only : NG29 ! diff --git a/physics/radsw_main.F90 b/physics/radsw_main.F90 index ae2f21e18..fe63963f5 100644 --- a/physics/radsw_main.F90 +++ b/physics/radsw_main.F90 @@ -90,7 +90,6 @@ ! ! ! external modules referenced: ! ! ! -! 'module physparam' ! ! 'module physcons' ! ! 'mersenne_twister' ! ! ! @@ -304,9 +303,6 @@ !! rrtmg-sw radiation code from aer inc. module rrtmg_sw ! - use physparam, only : iswrate, iswrgas, iswcliq, iswcice, & - & isubcsw, icldflg, iovr, ivflip, & - & iswmode use physcons, only : con_g, con_cp, con_avgd, con_amd, & & con_amw, con_amo3 use machine, only : rb => kind_phys, im => kind_io4, & @@ -503,8 +499,9 @@ subroutine rrtmg_sw_run & & sfcalb_uvis_dir, sfcalb_uvis_dif, & & dzlyr,delpin,de_lgth,alpha, & & cosz,solcon,NDAY,idxday, & - & npts, nlay, nlp1, lprnt, & - & cld_cf, lsswr, & + & npts, nlay, nlp1, lprnt, inc_minor_gas, iswcliq, iswcice, & + & isubcsw, iovr, top_at_1, iswmode, cld_cf, lsswr, iovr_rand,& + & iovr_maxrand, iovr_max, iovr_dcorr, iovr_exp, iovr_exprand,& & hswc,topflx,sfcflx,cldtau, & ! --- outputs & HSW0,HSWB,FLXPRF,FDNCMP, & ! --- optional & cld_lwp, cld_ref_liq, cld_iwp, cld_ref_ice, & @@ -570,6 +567,36 @@ subroutine rrtmg_sw_run & ! npts : number of horizontal points ! ! nlay,nlp1 : vertical layer/lavel numbers ! ! lprnt : logical check print flag ! +! iswcliq - control flag for liq-cloud optical properties ! +! =0: input cloud optical depth, fixed ssa, asy ! +! =1: use hu and stamnes(1993) method for liq cld ! +! =2: use updated coeffs for hu and stamnes scheme ! +! iswcice - control flag for ice-cloud optical properties ! +! *** if iswcliq==0, iswcice is ignored ! +! =1: use ebert and curry (1992) scheme for ice clouds ! +! =2: use streamer v3.0 (2001) method for ice clouds ! +! =3: use fu's method (1996) for ice clouds ! +! iswmode - control flag for 2-stream transfer scheme ! +! =1; delta-eddington (joseph et al., 1976) ! +! =2: pifm (zdunkowski et al., 1980) ! +! =3: discrete ordinates (liou, 1973) ! +! isubcsw - sub-column cloud approximation control flag ! +! =0: no sub-col cld treatment, use grid-mean cld quantities ! +! =1: mcica sub-col, prescribed seeds to get random numbers ! +! =2: mcica sub-col, providing array icseed for random numbers! +! iovr - clouds vertical overlapping control flag ! +! =iovr_rand ! +! =iovr_maxrand ! +! =iovr_max ! +! =iovr_dcorr ! +! =iovr_exp ! +! =iovr_exprand ! +! iovr_rand - choice of cloud-overlap: random ! +! iovr_maxrand - choice of cloud-overlap: maximum random ! +! iovr_max - choice of cloud-overlap: maximum ! +! iovr_dcorr - choice of cloud-overlap: decorrelation length ! +! iovr_exp - choice of cloud-overlap: exponential ! +! iovr_exprand - choice of cloud-overlap: exponential random ! ! ! ! output variables: ! ! hswc (npts,nlay): total sky heating rates (k/sec or k/day) ! @@ -604,38 +631,6 @@ subroutine rrtmg_sw_run & ! visbm - downward surface uv+vis direct beam flux ! ! visdf - downward surface uv+vis diffused flux ! ! ! -! external module variables: (in physparam) ! -! iswrgas - control flag for rare gases (ch4,n2o,o2, etc.) ! -! =0: do not include rare gases ! -! >0: include all rare gases ! -! iswcliq - control flag for liq-cloud optical properties ! -! =0: input cloud optical depth, fixed ssa, asy ! -! =1: use hu and stamnes(1993) method for liq cld ! -! =2: use updated coeffs for hu and stamnes scheme ! -! iswcice - control flag for ice-cloud optical properties ! -! *** if iswcliq==0, iswcice is ignored ! -! =1: use ebert and curry (1992) scheme for ice clouds ! -! =2: use streamer v3.0 (2001) method for ice clouds ! -! =3: use fu's method (1996) for ice clouds ! -! iswmode - control flag for 2-stream transfer scheme ! -! =1; delta-eddington (joseph et al., 1976) ! -! =2: pifm (zdunkowski et al., 1980) ! -! =3: discrete ordinates (liou, 1973) ! -! isubcsw - sub-column cloud approximation control flag ! -! =0: no sub-col cld treatment, use grid-mean cld quantities ! -! =1: mcica sub-col, prescribed seeds to get random numbers ! -! =2: mcica sub-col, providing array icseed for random numbers! -! iovr - cloud overlapping control flag ! -! =0: random overlapping clouds ! -! =1: maximum/random overlapping clouds ! -! =2: maximum overlap cloud ! -! =3: decorrelation-length overlap clouds ! -! =4: exponential cloud overlap (AER) ! -! =5: exponential-random cloud overlap (AER) ! -! ivflip - control flg for direction of vertical index ! -! =0: index from toa to surface ! -! =1: index from surface to toa ! -! ! ! module parameters, control variables: ! ! nblow,nbhgh - lower and upper limits of spectral bands ! ! maxgas - maximum number of absorbing gaseous ! @@ -690,11 +685,13 @@ subroutine rrtmg_sw_run & ! ===================== end of definitions ==================== ! ! --- inputs: - integer, intent(in) :: npts, nlay, nlp1, NDAY + integer, intent(in) :: npts, nlay, nlp1, NDAY, iswcliq, iswcice, & + isubcsw, iovr, iswmode, iovr_dcorr, iovr_exp, iovr_exprand, & + iovr_rand, iovr_maxrand, iovr_max integer, dimension(:), intent(in) :: idxday, icseed - logical, intent(in) :: lprnt, lsswr + logical, intent(in) :: lprnt, lsswr, inc_minor_gas, top_at_1 real (kind=kind_phys), dimension(:,:), intent(in) :: & & plvl, tlvl @@ -899,7 +896,7 @@ subroutine rrtmg_sw_run & cosz1 = cosz(j1) sntz1 = f_one / cosz(j1) ssolar = s0fac * cosz(j1) - if (iovr == 3) delgth = de_lgth(j1) ! clouds decorr-length + if (iovr == iovr_dcorr) delgth = de_lgth(j1) ! clouds decorr-length !> - Prepare surface albedo: bm,df - dir,dif; 1,2 - nir,uvv. albbm(1) = sfcalb_nir_dir(j1) @@ -910,7 +907,7 @@ subroutine rrtmg_sw_run & !> - Prepare atmospheric profile for use in rrtm. ! the vertical index of internal array is from surface to top - if (ivflip == 0) then ! input from toa to sfc + if (top_at_1) then ! input from toa to sfc tem1 = 100.0 * con_g tem2 = 1.0e-20 * 1.0e3 * con_avgd @@ -921,7 +918,7 @@ subroutine rrtmg_sw_run & tavel(k) = tlyr(j1,kk) delp (k) = delpin(j1,kk) dz (k) = dzlyr (j1,kk) - if (iovr == 4 .or. iovr == 5) alph(k) = alpha(j1,k) ! alpha decorrelation + if (iovr == iovr_exp .or. iovr == iovr_exprand) alph(k) = alpha(j1,k) ! alpha decorrelation !> - Set absorber and gas column amount, convert from volume mixing !! ratio to molec/cm2 based on coldry (scaled to 1.0e-20) @@ -950,7 +947,7 @@ subroutine rrtmg_sw_run & ! --- ... set up gas column amount, convert from volume mixing ratio ! to molec/cm2 based on coldry (scaled to 1.0e-20) - if (iswrgas > 0) then + if (inc_minor_gas) then do k = 1, nlay kk = nlp1 - k colamt(k,4) = max(temcol(k), coldry(k)*gasvmr_n2o(j1,kk)) ! n2o @@ -1012,7 +1009,7 @@ subroutine rrtmg_sw_run & tavel(k) = tlyr(j1,k) delp (k) = delpin(j1,k) dz (k) = dzlyr (j1,k) - if (iovr == 4 .or. iovr == 5) alph(k) = alpha(j1,k) ! alpha decorrelation + if (iovr == iovr_exp .or. iovr == iovr_exprand) alph(k) = alpha(j1,k) ! alpha decorrelation ! --- ... set absorber amount !test use @@ -1047,7 +1044,7 @@ subroutine rrtmg_sw_run & ! --- ... set up gas column amount, convert from volume mixing ratio ! to molec/cm2 based on coldry (scaled to 1.0e-20) - if (iswrgas > 0) then + if (inc_minor_gas) then do k = 1, nlay colamt(k,4) = max(temcol(k), coldry(k)*gasvmr_n2o(j1,k)) ! n2o colamt(k,5) = max(temcol(k), coldry(k)*gasvmr_ch4(j1,k)) ! ch4 @@ -1094,7 +1091,7 @@ subroutine rrtmg_sw_run & enddo endif ! end if_iswcliq - endif ! if_ivflip + endif ! if_top_at_1 !> - Compute fractions of clear sky view: !! - random overlapping @@ -1103,11 +1100,11 @@ subroutine rrtmg_sw_run & zcf0 = f_one zcf1 = f_one - if (iovr == 0) then ! random overlapping + if (iovr == iovr_rand) then ! random overlapping do k = 1, nlay zcf0 = zcf0 * (f_one - cfrac(k)) enddo - else if (iovr == 1) then ! max/ran/exp overlapping + else if (iovr == iovr_maxrand) then ! max/ran/exp overlapping do k = 1, nlay if (cfrac(k) > ftiny) then ! cloudy layer zcf1 = min ( zcf1, f_one-cfrac(k) ) @@ -1135,7 +1132,8 @@ subroutine rrtmg_sw_run & call cldprop & ! --- inputs: & ( cfrac,cliqp,reliq,cicep,reice,cdat1,cdat2,cdat3,cdat4, & - & zcf1, nlay, ipseed(j1), dz, delgth, alph, & + & zcf1, nlay, ipseed(j1), dz, delgth, alph, iswcliq, iswcice,& + & isubcsw, iovr, & ! --- outputs: & taucw, ssacw, asycw, cldfrc, cldfmc & & ) @@ -1143,7 +1141,7 @@ subroutine rrtmg_sw_run & ! --- ... save computed layer cloud optical depth for output ! rrtm band 10 is approx to the 0.55 mu spectrum - if (ivflip == 0) then ! input from toa to sfc + if (top_at_1) then ! input from toa to sfc do k = 1, nlay kk = nlp1 - k cldtau(j1,kk) = taucw(k,10) @@ -1152,7 +1150,7 @@ subroutine rrtmg_sw_run & do k = 1, nlay cldtau(j1,k) = taucw(k,10) enddo - endif ! end if_ivflip_block + endif ! end if_top_at_1_block else ! clear sky column cldfrc(:) = f_zero @@ -1187,9 +1185,9 @@ subroutine rrtmg_sw_run & & ) !> - Call the 2-stream radiation transfer model: -!! - if physparam::isubcsw .le.0, using standard cloud scheme, +!! - if GFS_typedefs::isubcsw .le.0, using standard cloud scheme, !! call spcvrtc(). -!! - if physparam::isubcsw .gt.0, using mcica cloud scheme, +!! - if GFS_typedefs::isubcsw .gt.0, using mcica cloud scheme, !! call spcvrtm(). if ( isubcsw <= 0 ) then ! use standard cloud scheme @@ -1198,7 +1196,7 @@ subroutine rrtmg_sw_run & ! --- inputs: & ( ssolar,cosz1,sntz1,albbm,albdf,sfluxzen,cldfrc, & & zcf1,zcf0,taug,taur,tauae,ssaae,asyae,taucw,ssacw,asycw, & - & nlay, nlp1, & + & nlay, nlp1, iswmode, & ! --- outputs: & fxupc,fxdnc,fxup0,fxdn0, & & ftoauc,ftoau0,ftoadc,fsfcuc,fsfcu0,fsfcdc,fsfcd0, & @@ -1211,7 +1209,7 @@ subroutine rrtmg_sw_run & ! --- inputs: & ( ssolar,cosz1,sntz1,albbm,albdf,sfluxzen,cldfmc, & & zcf1,zcf0,taug,taur,tauae,ssaae,asyae,taucw,ssacw,asycw, & - & nlay, nlp1, & + & nlay, nlp1, iswmode, & ! --- outputs: & fxupc,fxdnc,fxup0,fxdn0, & & ftoauc,ftoau0,ftoadc,fsfcuc,fsfcu0,fsfcdc,fsfcd0, & @@ -1276,7 +1274,7 @@ subroutine rrtmg_sw_run & sfcflx(j1)%upfx0 = fsfcu0 sfcflx(j1)%dnfx0 = fsfcd0 - if (ivflip == 0) then ! output from toa to sfc + if (top_at_1) then ! output from toa to sfc ! --- ... compute heating rates @@ -1372,7 +1370,7 @@ subroutine rrtmg_sw_run & enddo endif - endif ! if_ivflip + endif ! if_top_at_1 enddo lab_do_ipt @@ -1387,9 +1385,9 @@ end subroutine rrtmg_sw_run !!\param me print control for parallel process !>\section rswinit_gen rswinit General Algorithm !----------------------------------- - subroutine rswinit & - & ( me ) ! --- inputs: -! --- outputs: (none) + subroutine rswinit( me, rad_hr_units, inc_minor_gas, iswcliq, & + isubcsw, iovr, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr,& + iovr_exp, iovr_exprand, iswmode, errflg, errmsg ) ! =================== program usage description =================== ! ! ! @@ -1401,17 +1399,8 @@ subroutine rswinit & ! ==================== defination of variables ==================== ! ! ! ! inputs: ! -! me - print control for parallel process ! -! ! -! outputs: (none) ! -! ! -! external module variables: (in physparam) ! -! iswrate - heating rate unit selections ! -! =1: output in k/day ! -! =2: output in k/second ! -! iswrgas - control flag for rare gases (ch4,n2o,o2, etc.) ! -! =0: do not include rare gases ! -! >0: include all rare gases ! +! me - print control for parallel process ! +! rad_hr_units - ! ! iswcliq - liquid cloud optical properties contrl flag ! ! =0: input cloud opt depth from diagnostic scheme ! ! >0: input cwp,rew, and other cloud content parameters ! @@ -1419,21 +1408,27 @@ subroutine rswinit & ! =0: no sub-col cld treatment, use grid-mean cld quantities ! ! =1: mcica sub-col, prescribed seeds to get random numbers ! ! =2: mcica sub-col, providing array icseed for random numbers! -! icldflg - cloud scheme control flag ! -! =0: diagnostic scheme gives cloud tau, omiga, and g. ! -! =1: prognostic scheme gives cloud liq/ice path, etc. ! -! iovr - clouds vertical overlapping control flag ! -! =0: random overlapping clouds ! -! =1: maximum/random overlapping clouds ! -! =2: maximum overlap cloud ! -! =3: decorrelation-length overlap clouds ! -! =4: exponential cloud overlap (AER) ! -! =5: exponential-random cloud overlap (AER) ! +! iovr - clouds vertical overlapping control flag ! +! =iovr_rand ! +! =iovr_maxrand ! +! =iovr_max ! +! =iovr_dcorr ! +! =iovr_exp ! +! =iovr_exprand ! +! iovr_rand - choice of cloud-overlap: random ! +! iovr_maxrand - choice of cloud-overlap: maximum random ! +! iovr_max - choice of cloud-overlap: maximum ! +! iovr_dcorr - choice of cloud-overlap: decorrelation length ! +! iovr_exp - choice of cloud-overlap: exponential ! +! iovr_exprand - choice of cloud-overlap: exponential random ! ! iswmode - control flag for 2-stream transfer scheme ! ! =1; delta-eddington (joseph et al., 1976) ! ! =2: pifm (zdunkowski et al., 1980) ! ! =3: discrete ordinates (liou, 1973) ! ! ! +! outputs: ! +! errflg - error flag ! +! errmsg - error message ! ! ******************************************************************* ! ! ! ! definitions: ! @@ -1446,9 +1441,13 @@ subroutine rswinit & ! ====================== end of description block ================= ! ! --- inputs: - integer, intent(in) :: me - -! --- outputs: none + integer, intent(in) :: me, rad_hr_units, iswcliq, isubcsw, iovr, & + iswmode, iovr_rand, iovr_maxrand, iovr_max, iovr_dcorr, & + iovr_exp, iovr_exprand + logical, intent(in) :: inc_minor_gas +! --- outputs: + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: real (kind=kind_phys), parameter :: expeps = 1.e-20 @@ -1460,10 +1459,15 @@ subroutine rswinit & ! !===> ... begin here ! - if ( iovr<0 .or. iovr>5 ) then - print *,' *** Error in specification of cloud overlap flag', & - & ' IOVR=',iovr,' in RSWINIT !!' - stop + ! Initialize error-handling + errflg = 0 + errmsg = '' + + if ((iovr .ne. iovr_rand) .and. (iovr .ne. iovr_maxrand) .and. & + (iovr .ne. iovr_max) .and. (iovr .ne. iovr_dcorr) .and. & + (iovr .ne. iovr_exp) .and. (iovr .ne. iovr_exprand)) then + errflg = 1 + errmsg = 'ERROR(rswinit): Error in specification of cloud overlap flag' endif if (me == 0) then @@ -1477,7 +1481,7 @@ subroutine rswinit & print *,' --- Discrete ordinates 2-stream transfer scheme' endif - if (iswrgas <= 0) then + if (.not. inc_minor_gas) then print *,' --- Rare gases absorption is NOT included in SW' else print *,' --- Include rare gases N2O, CH4, O2, absorptions',& @@ -1493,37 +1497,13 @@ subroutine rswinit & elseif ( isubcsw == 2 ) then print *,' --- Using MCICA sub-colum clouds approximation ', & & 'with provided input array of permutation seeds' - else - print *,' *** Error in specification of sub-column cloud ', & - & ' control flag isubcsw =',isubcsw,' !!' - stop endif endif -!> - Check cloud flags for consistency. - - if ((icldflg == 0 .and. iswcliq /= 0) .or. & - & (icldflg == 1 .and. iswcliq == 0)) then - print *,' *** Model cloud scheme inconsistent with SW', & - & ' radiation cloud radiative property setup !!' - stop - endif - - if ( isubcsw==0 .and. iovr>2 ) then - if (me == 0) then - print *,' *** IOVR=',iovr,' is not available for', & - & ' ISUBCSW=0 setting!!' - print *,' The program will use maximum/random overlap', & - & ' instead.' - endif - - iovr = 1 - endif - !> - Setup constant factors for heating rate !! the 1.0e-2 is to convert pressure from mb to \f$N/m^2\f$ . - if (iswrate == 1) then + if (rad_hr_units == 1) then ! heatfac = 8.4391 ! heatfac = con_g * 86400. * 1.0e-2 / con_cp ! (in k/day) heatfac = con_g * 864.0 / con_cp ! (in k/day) @@ -1585,8 +1565,8 @@ end subroutine rswinit !!\section General_cldprop cldprop General Algorithm subroutine cldprop & & ( cfrac,cliqp,reliq,cicep,reice,cdat1,cdat2,cdat3,cdat4, & ! --- inputs - & cf1, nlay, ipseed, dz, delgth, alpha, & - & taucw, ssacw, asycw, cldfrc, cldfmc & ! --- output + & cf1, nlay, ipseed, dz, delgth, alpha, iswcliq, iswcice, & + & isubcsw, iovr, taucw, ssacw, asycw, cldfrc, cldfmc & ! --- output & ) ! =================== program usage description =================== ! @@ -1637,7 +1617,7 @@ subroutine cldprop & ! ! ! ! ! explanation of the method for each value of iswcliq, and iswcice. ! -! set up in module "physparam" ! +! provided by host-model ! ! ! ! iswcliq=0 : input cloud optical property (tau, ssa, asy). ! ! (used for diagnostic cloud method) ! @@ -1672,7 +1652,8 @@ subroutine cldprop & use module_radsw_cldprtb ! --- inputs: - integer, intent(in) :: nlay, ipseed + integer, intent(in) :: nlay, ipseed, iswcliq, iswcice, isubcsw, & + iovr real (kind=kind_phys), intent(in) :: cf1, delgth real (kind=kind_phys), dimension(nlay), intent(in) :: cliqp, & @@ -1930,7 +1911,7 @@ subroutine cldprop & call mcica_subcol & ! --- inputs: - & ( cldf, nlay, ipseed, dz, delgth, alpha, & + & ( cldf, nlay, ipseed, dz, delgth, alpha, iovr, & ! --- outputs: & lcloudy & & ) @@ -1969,7 +1950,7 @@ end subroutine cldprop !!\section mcica_sw_gen mcica_subcol General Algorithm ! ---------------------------------- subroutine mcica_subcol & - & ( cldf, nlay, ipseed, dz, de_lgth, alpha, & ! --- inputs + & ( cldf, nlay, ipseed, dz, de_lgth, alpha, iovr, & ! --- inputs & lcloudy & ! --- outputs & ) @@ -1982,15 +1963,10 @@ subroutine mcica_subcol & ! ** note : if the cloud generator is called multiple times, need ! ! to permute the seed between each call; if between calls ! ! for lw and sw, use values differ by the number of g-pts. ! -! dz - real, layer thickness (km) nlay ! -! de_lgth-real, layer cloud decorrelation length (km) 1 ! -! alpha - real, EXP/ER decorrelation parameter nlay ! -! ! -! output variables: ! -! lcloudy - logical, sub-colum cloud profile flag array nlay*ngptsw! -! ! -! other control flags from module variables: ! -! iovr : control flag for cloud overlapping method ! +! dz - real, layer thickness (km) nlay ! +! de_lgth - real, layer cloud decorrelation length (km) 1 ! +! alpha - real, EXP/ER decorrelation parameter nlay ! +! iovr - control flag for cloud overlapping method 1 ! ! =0: random ! ! =1: maximum/random overlapping clouds ! ! =2: maximum overlap cloud ! @@ -1998,12 +1974,15 @@ subroutine mcica_subcol & ! =4: exponential cloud overlap method (AER) ! ! =5: exponential-random cloud overlap method (AER) ! ! ! +! output variables: ! +! lcloudy - logical, sub-colum cloud profile flag array nlay*ngptsw! +! ! ! ===================== end of definitions ==================== ! implicit none ! --- inputs: - integer, intent(in) :: nlay, ipseed + integer, intent(in) :: nlay, ipseed, iovr real (kind=kind_phys), dimension(nlay), intent(in) :: cldf, dz real (kind=kind_phys), intent(in) :: de_lgth @@ -2453,7 +2432,7 @@ end subroutine setcoef subroutine spcvrtc & & ( ssolar,cosz,sntz,albbm,albdf,sfluxzen,cldfrc, & ! --- inputs & cf1,cf0,taug,taur,tauae,ssaae,asyae,taucw,ssacw,asycw, & - & nlay, nlp1, & + & nlay, nlp1, iswmode, & & fxupc,fxdnc,fxup0,fxdn0, & ! --- outputs & ftoauc,ftoau0,ftoadc,fsfcuc,fsfcu0,fsfcdc,fsfcd0, & & sfbmc,sfdfc,sfbm0,sfdf0,suvbfc,suvbf0 & @@ -2515,7 +2494,7 @@ subroutine spcvrtc & ! zldbt - real, layer beam transmittance for clear/cloudy nlp1 ! ! ztdbt - real, lev total beam transmittance for clr/cld nlp1 ! ! ! -! control parameters in module "physparam" ! +! control parameters in module "GFS_typedefs" ! ! iswmode - control flag for 2-stream transfer schemes ! ! = 1 delta-eddington (joseph et al., 1976) ! ! = 2 pifm (zdunkowski et al., 1980) ! @@ -2556,7 +2535,7 @@ subroutine spcvrtc & real (kind=kind_phys), parameter :: eps1 = 1.0e-8 ! --- inputs: - integer, intent(in) :: nlay, nlp1 + integer, intent(in) :: nlay, nlp1, iswmode real (kind=kind_phys), dimension(nlay,ngptsw), intent(in) :: & & taug, taur @@ -2661,7 +2640,7 @@ subroutine spcvrtc & !! transmittance. ! - Set up toa direct beam and surface values (beam and diff). ! - Delta scaling for clear-sky condition. -! - General two-stream expressions for physparam::iswmode . +! - General two-stream expressions. ! - Compute homogeneous reflectance and transmittance for both ! conservative and non-conservative scattering. ! - Pre-delta-scaling clear and cloudy direct beam transmittance. @@ -2693,7 +2672,7 @@ subroutine spcvrtc & zasy3 = 0.75 * zasy1 !> - Perform general two-stream expressions: -!!\n control parameters in module "physparam" +!!\n control parameters provided by host-model !!\n iswmode - control flag for 2-stream transfer schemes !!\n = 1 delta-eddington (joseph et al., 1976) !!\n = 2 pifm (zdunkowski et al., 1980) @@ -2887,7 +2866,7 @@ subroutine spcvrtc & !! transmittance. ! - Set up toa direct beam and surface values (beam and diff) ! - Delta scaling for total-sky condition -! - General two-stream expressions for physparam::iswmode +! - General two-stream expressions ! - Compute homogeneous reflectance and transmittance for ! conservative scattering and non-conservative scattering ! - Pre-delta-scaling clear and cloudy direct beam transmittance @@ -2922,7 +2901,7 @@ subroutine spcvrtc & zasy3 = 0.75 * zasy1 !> - Perform general two-stream expressions: -!!\n control parameters in module "physparam" +!!\n control parameters provided by host-model !!\n iswmode - control flag for 2-stream transfer schemes !!\n = 1 delta-eddington (joseph et al., 1976) !!\n = 2 pifm (zdunkowski et al., 1980) @@ -3249,7 +3228,7 @@ end subroutine spcvrtc subroutine spcvrtm & & ( ssolar,cosz,sntz,albbm,albdf,sfluxzen,cldfmc, & ! --- inputs & cf1,cf0,taug,taur,tauae,ssaae,asyae,taucw,ssacw,asycw, & - & nlay, nlp1, & + & nlay, nlp1, iswmode, & & fxupc,fxdnc,fxup0,fxdn0, & ! --- outputs & ftoauc,ftoau0,ftoadc,fsfcuc,fsfcu0,fsfcdc,fsfcd0, & & sfbmc,sfdfc,sfbm0,sfdf0,suvbfc,suvbf0 & @@ -3285,6 +3264,10 @@ subroutine spcvrtm & ! ssacw - real, weighted cloud single scat albedo nlay*nbdsw ! ! asycw - real, weighted cloud asymmetry factor nlay*nbdsw ! ! nlay,nlp1 - integer, number of layers/levels 1 ! +! iswmode - control flag for 2-stream transfer schemes ! +! = 1 delta-eddington (joseph et al., 1976) ! +! = 2 pifm (zdunkowski et al., 1980) ! +! = 3 discrete ordinates (liou, 1973) ! ! ! ! output variables: ! ! fxupc - real, tot sky upward flux nlp1*nbdsw ! @@ -3313,12 +3296,6 @@ subroutine spcvrtm & ! zldbt - real, layer beam transmittance for clear/cloudy nlp1 ! ! ztdbt - real, lev total beam transmittance for clr/cld nlp1 ! ! ! -! control parameters in module "physparam" ! -! iswmode - control flag for 2-stream transfer schemes ! -! = 1 delta-eddington (joseph et al., 1976) ! -! = 2 pifm (zdunkowski et al., 1980) ! -! = 3 discrete ordinates (liou, 1973) ! -! ! ! ******************************************************************* ! ! original code description ! ! ! @@ -3354,7 +3331,7 @@ subroutine spcvrtm & real (kind=kind_phys), parameter :: eps1 = 1.0e-8 ! --- inputs: - integer, intent(in) :: nlay, nlp1 + integer, intent(in) :: nlay, nlp1, iswmode real (kind=kind_phys), dimension(nlay,ngptsw), intent(in) :: & & taug, taur, cldfmc @@ -3458,7 +3435,7 @@ subroutine spcvrtm & !! transmittance. ! - Set up toa direct beam and surface values (beam and diff) ! - Delta scaling for clear-sky condition -! - General two-stream expressions for physparam::iswmode +! - General two-stream expressions ! - Compute homogeneous reflectance and transmittance for both ! conservative and non-conservative scattering ! - Pre-delta-scaling clear and cloudy direct beam transmittance @@ -3489,7 +3466,7 @@ subroutine spcvrtm & zasy3 = 0.75 * zasy1 !> - Perform general two-stream expressions: -!!\n control parameters in module "physparam" +!!\n control parameters provided by host-model !!\n iswmode - control flag for 2-stream transfer schemes !!\n = 1 delta-eddington (joseph et al., 1976) !!\n = 2 pifm (zdunkowski et al., 1980) @@ -3682,7 +3659,7 @@ subroutine spcvrtm & !! transmittance. ! - Set up toa direct beam and surface values (beam and diff) ! - Delta scaling for total-sky condition -! - General two-stream expressions for physparam::iswmode +! - General two-stream expressions ! - Compute homogeneous reflectance and transmittance for ! conservative scattering and non-conservative scattering ! - Pre-delta-scaling clear and cloudy direct beam transmittance diff --git a/physics/radsw_main.meta b/physics/radsw_main.meta index 506e2edf0..1edb6fcac 100644 --- a/physics/radsw_main.meta +++ b/physics/radsw_main.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = rrtmg_sw type = scheme - dependencies = machine.F,mersenne_twister.f,physcons.F90,physparam.f,radsw_datatb.f,radsw_param.f + dependencies = machine.F,mersenne_twister.f,physcons.F90,radsw_datatb.f,radsw_param.f ######################################################################## [ccpp-arg-table] @@ -280,6 +280,97 @@ dimensions = () type = logical intent = in +[inc_minor_gas] + standard_name = flag_to_include_minor_gases_in_rrtmg + long_name = flag to include minor trace gases in rrtmg + units = flag + dimensions = () + type = logical + intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation + units = flag + dimensions = () + type = logical + intent = in +[iswcice] + standard_name = flag_for_optical_property_for_ice_clouds_for_shortwave_radiation + long_name = sw optical property for ice clouds + units = flag + dimensions = () + type = integer + intent = in +[iswcliq] + standard_name = control_for_shortwave_radiation_liquid_clouds + long_name = sw optical property for liquid clouds + units = flag + dimensions = () + type = integer + intent = in +[isubcsw] + standard_name = flag_for_sw_clouds_grid_approximation + long_name = flag for sw clouds sub-grid approximation + units = flag + dimensions = () + type = integer + intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = max-random overlap clouds + units = flag + dimensions = () + type = integer + intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iswmode] + standard_name = control_for_sw_scattering_choice + long_name = control of rrtmg shortwave scattering choice + units = 1 + dimensions = () + type = integer + intent = in [cld_cf] standard_name = total_cloud_fraction long_name = total cloud fraction diff --git a/physics/radsw_param.f b/physics/radsw_param.f index 69c8c2446..2086f5df8 100644 --- a/physics/radsw_param.f +++ b/physics/radsw_param.f @@ -66,7 +66,7 @@ module module_radsw_parameters ! !! \htmlinclude module_radsw_parameters.html !! - use physparam, only : kind_phys + use machine, only : kind_phys implicit none ! diff --git a/physics/rrtmgp_aerosol_optics.F90 b/physics/rrtmgp_aerosol_optics.F90 index e2cc95994..9a92ea98a 100644 --- a/physics/rrtmgp_aerosol_optics.F90 +++ b/physics/rrtmgp_aerosol_optics.F90 @@ -3,16 +3,10 @@ module rrtmgp_aerosol_optics use machine, only: kind_phys - use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp - use mo_optical_props, only: ty_optical_props_2str, ty_optical_props_1scl use radiation_tools, only: check_error_msg use rrtmgp_sw_gas_optics, only: sw_gas_props use rrtmgp_lw_gas_optics, only: lw_gas_props - use module_radiation_aerosols, only: & - NF_AESW, & ! Number of optical-fields in SW output (3=tau+g+omega) - NF_AELW, & ! Number of optical-fields in LW output (3=tau+g+omega) - setaer, & ! Routine to compute aerosol radiative properties (tau,g,omega) - NSPC1 ! Number of species for vertically integrated aerosol optical-depth + use module_radiation_aerosols, only: setaer use netcdf implicit none @@ -30,22 +24,28 @@ module rrtmgp_aerosol_optics !! \section arg_table_rrtmgp_aerosol_optics_run !! \htmlinclude rrtmgp_aerosol_optics_run.html !! - subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTracerAer, & - nDay, idxday, p_lev, p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, & - aerodp, sw_optical_props_aerosol, lw_optical_props_aerosol, errmsg, errflg ) + subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nDay, idxday, p_lev, & + p_lay, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, iaermdl, iaerflg, & + top_at_1, con_pi, con_rd, con_g, aerodp, aerlw_tau, aerlw_ssa, aerlw_g, aersw_tau, & + aersw_ssa, aersw_g, ext550, errmsg, errflg ) ! Inputs logical, intent(in) :: & doSWrad, & ! Logical flag for shortwave radiation call - doLWrad ! Logical flag for longwave radiation call + doLWrad, & ! Logical flag for longwave radiation call + top_at_1 ! Logical flag for vertical grid direcetion integer, intent(in) :: & nCol, & ! Number of horizontal grid points nDay, & ! Number of daylit points nLev, & ! Number of vertical layers - nTracer, & ! Number of tracers - nTracerAer ! Number of aerosol tracers + iaermdl, & ! Aerosol model scheme flag + iaerflg ! Aerosol effects to include integer,intent(in),dimension(:) :: & - idxday ! Indices for daylit points. + idxday ! Indices for daylit points. + real(kind_phys),intent(in) :: & + con_pi, & ! Physical constant (pi) + con_rd, & ! Physical constant (gas constant for dry-air) + con_g ! Physical constant (gravitational constant) real(kind_phys), dimension(:), intent(in) :: & lon, & ! Longitude lat, & ! Latitude @@ -61,23 +61,28 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTra aerfld ! aerosol input concentrations real(kind_phys), dimension(:,:),intent(in) :: & p_lev ! Pressure @ layer-interfaces (Pa) + real (kind=kind_phys), dimension(:,:), intent(out) :: & + ext550 ! 3d optical extinction for total aerosol species ! Outputs real(kind_phys), dimension(:,:), intent(out) :: & aerodp ! Vertical integrated optical depth for various aerosol species - type(ty_optical_props_2str),intent(out) :: & - sw_optical_props_aerosol ! RRTMGP DDT: Longwave aerosol optical properties (tau) - type(ty_optical_props_1scl),intent(inout) :: & - lw_optical_props_aerosol ! RRTMGP DDT: Longwave aerosol optical properties (tau) + real(kind_phys), dimension(:,:,:), intent(out) :: & + aerlw_tau, & ! Longwave aerosol optical depth + aerlw_ssa, & ! Longwave aerosol single scattering albedo + aerlw_g, & ! Longwave aerosol asymmetry parameter + aersw_tau, & ! Shortwave aerosol optical depth + aersw_ssa, & ! Shortwave aerosol single scattering albedo + aersw_g ! Shortwave aerosol asymmetry parameter integer, intent(out) :: & errflg ! CCPP error flag character(len=*), intent(out) :: & errmsg ! CCPP error message ! Local variables - real(kind_phys), dimension(nCol, nLev, lw_gas_props%get_nband(), NF_AELW) :: & + real(kind_phys), dimension(nCol, nLev, lw_gas_props%get_nband(), 3) :: & aerosolslw ! - real(kind_phys), dimension(nCol, nLev, sw_gas_props%get_nband(), NF_AESW) :: & + real(kind_phys), dimension(nCol, nLev, sw_gas_props%get_nband(), 3) :: & aerosolssw, aerosolssw2 integer :: iBand @@ -85,14 +90,15 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTra errmsg = '' errflg = 0 - if (.not. doSWrad) return + if (.not. (doSWrad .or. doLWrad)) return ! Call module_radiation_aerosols::setaer(),to setup aerosols property profile call setaer(p_lev*0.01, p_lay*0.01, p_lk, tv_lay, relhum, lsmask, tracer, aerfld, lon, lat, nCol, nLev, & - nLev+1, .true., .true., aerosolssw2, aerosolslw, aerodp) + nLev+1, .true., .true., iaermdl, iaerflg, top_at_1, con_pi, con_rd, con_g, aerosolssw2, aerosolslw, & + aerodp, ext550, errflg, errmsg) ! Shortwave - if (nDay .gt. 0) then + if (doSWrad .and. (nDay .gt. 0)) then ! Store aerosol optical properties ! SW. ! For RRTMGP SW the bands are now ordered from [IR(band) -> nIR -> UV], in RRTMG the @@ -103,26 +109,19 @@ subroutine rrtmgp_aerosol_optics_run(doSWrad, doLWrad, nCol, nLev, nTracer, nTra aerosolssw(1:nCol,:,2:sw_gas_props%get_nband(),1) = aerosolssw2(1:nCol,:,1:sw_gas_props%get_nband()-1,1) aerosolssw(1:nCol,:,2:sw_gas_props%get_nband(),2) = aerosolssw2(1:nCol,:,1:sw_gas_props%get_nband()-1,2) aerosolssw(1:nCol,:,2:sw_gas_props%get_nband(),3) = aerosolssw2(1:nCol,:,1:sw_gas_props%get_nband()-1,3) - - ! Allocate RRTMGP DDT: Aerosol optics [nCol,nlev,nBands] - call check_error_msg('rrtmgp_aerosol_optics_run',sw_optical_props_aerosol%alloc_2str( & - nDay, nlev, sw_gas_props%get_band_lims_wavenumber())) - - ! Copy aerosol optical information to RRTMGP DDT - sw_optical_props_aerosol%tau = aerosolssw(idxday(1:nday),:,:,1) - sw_optical_props_aerosol%ssa = aerosolssw(idxday(1:nday),:,:,2) - sw_optical_props_aerosol%g = aerosolssw(idxday(1:nday),:,:,3) + + ! Copy aerosol optical information/ + aersw_tau = aerosolssw(:,:,:,1) + aersw_ssa = aerosolssw(:,:,:,2) + aersw_g = aerosolssw(:,:,:,3) endif ! Longwave - if (.not. doLWrad) return - lw_optical_props_aerosol%tau = aerosolslw(:,:,:,1) * (1. - aerosolslw(:,:,:,2)) - - lw_optical_props_aerosol%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_aerosol%band2gpt(1:2,iBand) = iBand - lw_optical_props_aerosol%gpt2band(iBand) = iBand - end do + if (doLWrad) then + aerlw_tau = aerosolslw(:,:,:,1) + aerlw_ssa = aerosolslw(:,:,:,2) + aerlw_g = aerosolslw(:,:,:,3) + endif end subroutine rrtmgp_aerosol_optics_run !> @} diff --git a/physics/rrtmgp_aerosol_optics.meta b/physics/rrtmgp_aerosol_optics.meta index f0c37edc0..cc9eb1cc2 100644 --- a/physics/rrtmgp_aerosol_optics.meta +++ b/physics/rrtmgp_aerosol_optics.meta @@ -21,6 +21,37 @@ dimensions = () type = logical intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation + units = flag + dimensions = () + type = logical + intent = in +[con_pi] + standard_name = pi + long_name = ratio of a circle's circumference to its diameter + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[con_rd] + standard_name = gas_constant_of_dry_air + long_name = ideal gas constant for dry air + units = J kg-1 K-1 + dimensions = () + type = real + kind = kind_phys + intent = in +[con_g] + standard_name = gravitational_acceleration + long_name = gravitational acceleration + units = m s-2 + dimensions = () + type = real + kind = kind_phys + intent = in [ncol] standard_name = horizontal_loop_extent long_name = horizontal dimension @@ -35,20 +66,6 @@ dimensions = () type = integer intent = in -[nTracer] - standard_name = number_of_tracers - long_name = number of tracers - units = count - dimensions = () - type = integer - intent = in -[nTracerAer] - standard_name = number_of_aerosol_tracers_MG - long_name = number of aerosol tracers for Morrison Gettelman MP - units = count - dimensions = () - type = integer - intent = in [nday] standard_name = daytime_points_dimension long_name = daytime points dimension @@ -112,9 +129,9 @@ kind = kind_phys intent = in [tracer] - standard_name = chemical_tracers - long_name = chemical tracers - units = g g-1 + standard_name = tracer_concentration + long_name = model layer mean tracer concentration + units = kg kg-1 dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) type = real kind = kind_phys @@ -143,6 +160,20 @@ type = real kind = kind_phys intent = in +[iaermdl] + standard_name = control_for_aerosol_radiation_scheme + long_name = control of aerosol scheme in radiation + units = 1 + dimensions = () + type = integer + intent = in +[iaerflg] + standard_name = control_for_aerosol_effects_in_radiation + long_name = control of aerosol effects in radiation + units = 1 + dimensions = () + type = integer + intent = in [aerodp] standard_name = atmosphere_optical_thickness_due_to_ambient_aerosol_particles long_name = vertical integrated optical depth for various aerosol species @@ -151,20 +182,62 @@ type = real kind = kind_phys intent = out -[sw_optical_props_aerosol] - standard_name = shortwave_optical_properties_for_aerosols - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str +[aersw_tau] + standard_name = aerosol_optical_depth_for_shortwave_bands_01_16 + long_name = aerosol optical depth for shortwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = out +[aersw_ssa] + standard_name = aerosol_single_scattering_albedo_for_shortwave_bands_01_16 + long_name = aerosol single scattering albedo for shortwave bands 01-16 + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = out +[aersw_g] + standard_name = aerosol_asymmetry_parameter_for_shortwave_bands_01_16 + long_name = aerosol asymmetry parameter for shortwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = out +[aerlw_tau] + standard_name = aerosol_optical_depth_for_longwave_bands_01_16 + long_name = aerosol optical depth for longwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = out +[aerlw_ssa] + standard_name = aerosol_single_scattering_albedo_for_longwave_bands_01_16 + long_name = aerosol single scattering albedo for longwave bands 01-16 + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = out +[aerlw_g] + standard_name = aerosol_asymmetry_parameter_for_longwave_bands_01_16 + long_name = aerosol asymmetry parameter for longwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = out +[ext550] + standard_name = aerosol_optical_depth_at_550nm + long_name = 3d optical extinction for total aerosol species + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys intent = out -[lw_optical_props_aerosol] - standard_name = longwave_optical_properties_for_aerosols - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_1scl - intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/rrtmgp_lw_cloud_optics.F90 b/physics/rrtmgp_lw_cloud_optics.F90 index 8bdd71696..9915c0040 100644 --- a/physics/rrtmgp_lw_cloud_optics.F90 +++ b/physics/rrtmgp_lw_cloud_optics.F90 @@ -12,8 +12,6 @@ module rrtmgp_lw_cloud_optics use machine, only: kind_phys use mo_rte_kind, only: wl use mo_cloud_optics, only: ty_cloud_optics - use mo_optical_props, only: ty_optical_props_1scl, ty_optical_props_2str - use mo_rrtmg_lw_cloud_optics, only: rrtmg_lw_cloud_optics use rrtmgp_lw_gas_optics, only: lw_gas_props use radiation_tools, only: check_error_msg use netcdf @@ -74,55 +72,42 @@ module rrtmgp_lw_cloud_optics contains -!>\defgroup rrtmgp_lw_cloud_optics_mod GFS RRTMGP-LW Cloud Optics Module -!> \section arg_table_rrtmgp_lw_cloud_optics_init -!! \htmlinclude rrtmgp_lw_cloud_optics.html -!! -!> \ingroup rrtmgp_lw_cloud_optics -!! -!! RRTMGP relies heavily on derived-data-types, which contain type-bound procedures -!! that are referenced frequently throughout the RRTMGP longwave scheme. The data needed -!! to compute the shortwave cloud optical properties are initialized here and loaded into -!! the RRTMGP DDT, ty_cloud_optics. -!! -!! \section rrtmgp_sw_cloud_optics_init - subroutine rrtmgp_lw_cloud_optics_init(nrghice, mpicomm, mpirank, mpiroot, & - doG_cldoptics, doGP_cldoptics_PADE, doGP_cldoptics_LUT, rrtmgp_root_dir, & - rrtmgp_lw_file_clouds, errmsg, errflg) + ! ###################################################################################### + ! SUBROUTINE rrtmgp_lw_cloud_optics_init() + ! ###################################################################################### + subroutine rrtmgp_lw_cloud_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_clouds, & + doGP_cldoptics_PADE, doGP_cldoptics_LUT, nrghice, mpicomm, mpirank, mpiroot, & + errmsg, errflg) ! Inputs + character(len=128),intent(in) :: & + rrtmgp_root_dir, & ! RTE-RRTMGP root directory + rrtmgp_lw_file_clouds ! RRTMGP file containing clouds optics data + logical, intent(in) :: & - doG_cldoptics, & ! Use legacy RRTMG cloud-optics? - doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? - doGP_cldoptics_LUT ! Use RRTMGP cloud-optics: LUTs? + doGP_cldoptics_PADE,& ! Use RRTMGP cloud-optics: PADE approximation? + doGP_cldoptics_LUT ! Use RRTMGP cloud-optics: LUTs? integer, intent(inout) :: & - nrghice ! Number of ice-roughness categories + nrghice ! Number of ice-roughness categories integer, intent(in) :: & - mpicomm, & ! MPI communicator - mpirank, & ! Current MPI rank - mpiroot ! Master MPI rank - character(len=128),intent(in) :: & - rrtmgp_root_dir, & ! RTE-RRTMGP root directory - rrtmgp_lw_file_clouds ! RRTMGP file containing coefficients used to compute clouds optical properties + mpicomm, & ! MPI communicator + mpirank, & ! Current MPI rank + mpiroot ! Master MPI rank ! Outputs character(len=*), intent(out) :: & - errmsg ! Error message + errmsg ! Error message integer, intent(out) :: & - errflg ! Error code + errflg ! Error code ! Local variables integer :: dimID,varID,status,ncid,mpierr character(len=264) :: lw_cloud_props_file - integer,parameter :: max_strlen=256, nrghice_default=2 ! Initialize errmsg = '' errflg = 0 - ! If not using RRTMGP cloud optics, return. - if (doG_cldoptics) return - ! Filenames are set in the physics_nml lw_cloud_props_file = trim(rrtmgp_root_dir)//trim(rrtmgp_lw_file_clouds) @@ -391,171 +376,4 @@ subroutine rrtmgp_lw_cloud_optics_init(nrghice, mpicomm, mpirank, mpiroot, call check_error_msg('lw_cloud_optics_init',lw_cloud_props%set_ice_roughness(nrghice)) end subroutine rrtmgp_lw_cloud_optics_init - ! ###################################################################################### -!> \section arg_table_rrtmgp_lw_cloud_optics_run -!! \htmlinclude rrtmgp_lw_cloud_optics.html -!! -!> \ingroup rrtmgp_lw_cloud_optics -!! -!! Compute longwave optical prperties (optical-depth) for ALL cloud types visible to RRTMGP. -!! -!! \section rrtmgp_lw_gas_optics_run - subroutine rrtmgp_lw_cloud_optics_run(doLWrad, doG_cldoptics, icliq_lw, icice_lw, & - doGP_cldoptics_PADE, doGP_cldoptics_LUT, doGP_lwscat, do_mynnedmf, imfdeepcnv, & - imfdeepcnv_gf, imfdeepcnv_samf, nCol, nLev, nbndsGPlw , p_lay, cld_frac, cld_lwp, & - cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, & - precip_frac, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_pbl_lwp, & - cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, lon, lat, cldtaulw, & - lw_optical_props_cloudsByBand, lw_optical_props_cnvcloudsByBand, & - lw_optical_props_MYNNcloudsByBand, lw_optical_props_precipByBand, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doLWrad, & ! Logical flag for longwave radiation call - doG_cldoptics, & ! Use legacy RRTMG cloud-optics? - doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? - doGP_cldoptics_LUT, & ! Use RRTMGP cloud-optics: LUTs? - doGP_lwscat, & ! Include scattering in LW cloud-optics? - do_mynnedmf ! - integer, intent(in) :: & - nbndsGPlw, & ! - nCol, & ! Number of horizontal gridpoints - nLev, & ! Number of vertical levels - icliq_lw, & ! Choice of treatment of liquid cloud optical properties (RRTMG legacy) - icice_lw, & ! Choice of treatment of ice cloud optical properties (RRTMG legacy) - imfdeepcnv, & ! - imfdeepcnv_gf, & ! - imfdeepcnv_samf ! - real(kind_phys), dimension(:), intent(in) :: & - lon, & ! Longitude - lat ! Latitude - real(kind_phys), dimension(:,:),intent(in) :: & - p_lay, & ! Layer pressure (Pa) - cld_frac, & ! Total cloud fraction by layer - cld_lwp, & ! Cloud liquid water path - cld_reliq, & ! Cloud liquid effective radius - cld_iwp, & ! Cloud ice water path - cld_reice, & ! Cloud ice effective radius - cld_swp, & ! Cloud snow water path - cld_resnow, & ! Cloud snow effective radius - cld_rwp, & ! Cloud rain water path - cld_rerain, & ! Cloud rain effective radius - precip_frac, & ! Precipitation fraction by layer. - cld_cnv_lwp, & ! Water path for convective liquid cloud-particles (microns) - cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles (microns) - cld_cnv_iwp, & ! Water path for convective ice cloud-particles (microns) - cld_cnv_reice, & ! Effective radius for convective ice cloud-particles (microns) - cld_pbl_lwp, & ! Water path for SGS PBL liquid cloud-particles - cld_pbl_reliq, & ! Effective radius for SGS PBL liquid cloud-particles - cld_pbl_iwp, & ! Water path for SGS PBL ice cloud-particles - cld_pbl_reice ! Effective radius for SGS PBL ice cloud-particles - - ! Outputs - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - type(ty_optical_props_2str),intent(inout) :: & - lw_optical_props_cloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (clouds) - lw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (convective cloud) - lw_optical_props_MYNNcloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (MYNN-PBL cloud) - lw_optical_props_precipByBand ! RRTMGP DDT: Longwave optical properties in each band (precipitation) - real(kind_phys), dimension(:,:), intent(inout) :: & - cldtaulw ! Approx 10.mu band layer cloud optical depth - - ! Local variables - real(kind_phys) :: tau_rain, tau_snow - real(kind_phys), dimension(ncol,nLev,nbndsGPlw) :: & - tau_cld, tau_precip - integer :: iCol, iLay, iBand - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - ! Initialize locals - tau_cld = 0._kind_phys - tau_precip = 0._kind_phys - - if (.not. doLWrad) return - - ! Compute cloud-optics for RTE. - if (doGP_cldoptics_PADE .or. doGP_cldoptics_LUT) then - - ! i) Cloud-optics. - lw_optical_props_cloudsByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_cloudsByBand%band2gpt(1:2,iBand) = iBand - lw_optical_props_cloudsByBand%gpt2band(iBand) = iBand - end do - call check_error_msg('rrtmgp_lw_cloud_optics_run - clouds',lw_cloud_props%cloud_optics(& - cld_lwp, & ! IN - Cloud liquid water path (g/m2) - cld_iwp, & ! IN - Cloud ice water path (g/m2) - cld_reliq, & ! IN - Cloud liquid effective radius (microns) - cld_reice, & ! IN - Cloud ice effective radius (microns) - lw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT containing cloud radiative properties - ! in each band - ! ii) Convective cloud-optics - if (imfdeepcnv == imfdeepcnv_samf .or. imfdeepcnv == imfdeepcnv_gf) then - lw_optical_props_cnvcloudsByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_cnvcloudsByBand%band2gpt(1:2,iBand) = iBand - lw_optical_props_cnvcloudsByBand%gpt2band(iBand) = iBand - end do - call check_error_msg('rrtmgp_lw_cnvcloud_optics_run - convective cloud',lw_cloud_props%cloud_optics(& - cld_cnv_lwp, & ! IN - Convective cloud liquid water path (g/m2) - cld_cnv_iwp, & ! IN - Convective cloud ice water path (g/m2) - cld_cnv_reliq, & ! IN - Convective cloud liquid effective radius (microns) - cld_cnv_reice, & ! IN - Convective cloud ice effective radius (microns) - lw_optical_props_cnvcloudsByBand)) ! OUT - RRTMGP DDT containing convective cloud radiative properties - ! in each band - endif - - ! iii) MYNN cloud-optics - if (do_mynnedmf) then - lw_optical_props_MYNNcloudsByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_MYNNcloudsByBand%band2gpt(1:2,iBand) = iBand - lw_optical_props_MYNNcloudsByBand%gpt2band(iBand) = iBand - end do - call check_error_msg('rrtmgp_lw_MYNNcloud_optics_run - MYNN-EDMF cloud',lw_cloud_props%cloud_optics(& - cld_pbl_lwp, & ! IN - MYNN-EDMF PBL cloud liquid water path (g/m2) - cld_pbl_iwp, & ! IN - MYNN-EDMF PBL cloud ice water path (g/m2) - cld_pbl_reliq, & ! IN - MYNN-EDMF PBL cloud liquid effective radius (microns) - cld_pbl_reice, & ! IN - MYNN-EDMF PBL cloud ice effective radius (microns) - lw_optical_props_MYNNcloudsByBand)) ! OUT - RRTMGP DDT containing MYNN-EDMF PBL cloud radiative properties - ! in each band - endif - - ! iv) Cloud precipitation optics: rain and snow(+groupel) - lw_optical_props_precipByBand%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_precipByBand%band2gpt(1:2,iBand) = iBand - lw_optical_props_precipByBand%gpt2band(iBand) = iBand - end do - do iCol=1,nCol - do iLay=1,nLev - if (cld_frac(iCol,iLay) .gt. 0.) then - ! Rain optical-depth (No band dependence) - tau_rain = absrain*cld_rwp(iCol,iLay) - - ! Snow (+groupel) optical-depth (No band dependence) - if (cld_swp(iCol,iLay) .gt. 0. .and. cld_resnow(iCol,iLay) .gt. 10._kind_phys) then - tau_snow = abssnow0*1.05756*cld_swp(iCol,iLay)/cld_resnow(iCol,iLay) - else - tau_snow = 0.0 - endif - do iBand=1,nbndsGPlw - lw_optical_props_precipByBand%tau(iCol,iLay,iBand) = tau_rain + tau_snow - enddo - endif - enddo - enddo - endif - - ! All-sky LW optical depth ~10microns (DJS asks: Same as SW, move to cloud-diagnostics?) - cldtaulw = lw_optical_props_cloudsByBand%tau(:,:,7) - - end subroutine rrtmgp_lw_cloud_optics_run - end module rrtmgp_lw_cloud_optics diff --git a/physics/rrtmgp_lw_cloud_optics.meta b/physics/rrtmgp_lw_cloud_optics.meta deleted file mode 100644 index c58496dc5..000000000 --- a/physics/rrtmgp_lw_cloud_optics.meta +++ /dev/null @@ -1,412 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_cloud_optics - type = scheme - dependencies = machine.F,rrtmg_lw_cloud_optics.F90,radiation_tools.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_cloud_optics_init - type = scheme -[doG_cldoptics] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMG - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_PADE] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_LUT] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[nrghice] - standard_name = number_of_ice_roughness_categories - long_name = number of ice-roughness categories in RRTMGP calculation - units = count - dimensions = () - type = integer - intent = inout -[rrtmgp_root_dir] - standard_name = directory_for_rte_rrtmgp_source_code - long_name = directory for rte+rrtmgp source code - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[rrtmgp_lw_file_clouds] - standard_name = filename_of_rrtmgp_longwave_cloud_optics_coefficients - long_name = file containing coefficients for RRTMGP LW cloud optics - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[mpirank] - standard_name = mpi_rank - long_name = current MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpiroot] - standard_name = mpi_root - long_name = master MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpicomm] - standard_name = mpi_communicator - long_name = MPI communicator - units = index - dimensions = () - type = integer - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_cloud_optics_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[doG_cldoptics] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMG - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[icliq_lw] - standard_name = flag_for_optical_property_for_liquid_clouds_for_longwave_radiation - long_name = lw optical property for liquid clouds - units = flag - dimensions = () - type = integer - intent = in -[icice_lw] - standard_name = flag_for_optical_property_for_ice_clouds_for_longwave_radiation - long_name = lw optical property for ice clouds - units = flag - dimensions = () - type = integer - intent = in -[doGP_cldoptics_PADE] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_LUT] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_lwscat] - standard_name = flag_to_include_longwave_scattering_in_cloud_optics - long_name = logical flag to control the addition of LW scattering in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[do_mynnedmf] - standard_name = flag_for_mellor_yamada_nakanishi_niino_pbl_scheme - long_name = flag to activate MYNN-EDMF - units = flag - dimensions = () - type = logical - intent = in -[imfdeepcnv] - standard_name = control_for_deep_convection_scheme - long_name = flag for mass-flux deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_gf] - standard_name = identifier_for_grell_freitas_deep_convection - long_name = flag for Grell-Freitas deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_samf] - standard_name = identifer_for_scale_aware_mass_flux_deep_convection - long_name = flag for SAMF deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_lwp] - standard_name = cloud_liquid_water_path - long_name = layer cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_reliq] - standard_name = mean_effective_radius_for_liquid_cloud - long_name = mean effective radius for liquid cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_iwp] - standard_name = cloud_ice_water_path - long_name = layer cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_reice] - standard_name = mean_effective_radius_for_ice_cloud - long_name = mean effective radius for ice cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_swp] - standard_name = cloud_snow_water_path - long_name = cloud snow water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_resnow] - standard_name = mean_effective_radius_for_snow_flake - long_name = mean effective radius for snow flake - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_rwp] - standard_name = cloud_rain_water_path - long_name = cloud rain water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[cld_rerain] - standard_name = mean_effective_radius_for_rain_drop - long_name = mean effective radius for rain drop - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - intent = in - kind = kind_phys -[precip_frac] - standard_name = precipitation_fraction_by_layer - long_name = precipitation fraction in each layer - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_lwp] - standard_name = convective_cloud_liquid_water_path - long_name = layer convective cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_iwp] - standard_name = convective_cloud_ice_water_path - long_name = layer convective cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_reliq] - standard_name = mean_effective_radius_for_liquid_convective_cloud - long_name = mean effective radius for liquid convective cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_reice] - standard_name = mean_effective_radius_for_ice_convective_cloud - long_name = mean effective radius for ice convective cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_lwp] - standard_name = MYNN_SGS_cloud_liquid_water_path - long_name = layer convective cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_iwp] - standard_name = MYNN_SGS_cloud_ice_water_path - long_name = layer convective cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_reliq] - standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud - long_name = mean effective radius for liquid MYNN_SGS cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_reice] - standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud - long_name = mean effective radius for ice MYNN_SGS cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure layer - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[nbndsGPlw] - standard_name = number_of_longwave_bands - long_name = number of lw bands used in RRTMGP - units = count - dimensions = () - type = integer - intent = in -[lon] - standard_name = longitude - long_name = longitude - units = radian - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[lat] - standard_name = latitude - long_name = latitude - units = radian - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[cldtaulw] - standard_name = cloud_optical_depth_layers_at_10mu_band - long_name = approx 10mu band layer cloud optical depth - units = none - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[lw_optical_props_cloudsByBand] - standard_name = longwave_optical_properties_for_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_cnvcloudsByBand] - standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_MYNNcloudsByBand] - standard_name = longwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_precipByBand] - standard_name = longwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - diff --git a/physics/rrtmgp_lw_cloud_sampling.F90 b/physics/rrtmgp_lw_cloud_sampling.F90 deleted file mode 100644 index 80fd3444a..000000000 --- a/physics/rrtmgp_lw_cloud_sampling.F90 +++ /dev/null @@ -1,170 +0,0 @@ -!> \file rrtmgp_lw_cloud_sampling.F90 -!! -!> \defgroup rrtmgp_lw_cloud_sampling rrtmgp_lw_cloud_sampling.F90 -!! -!! \brief -!! -module rrtmgp_lw_cloud_sampling - use machine, only: kind_phys, kind_dbl_prec - use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp - use mo_optical_props, only: ty_optical_props_2str - use rrtmgp_sampling, only: sampled_mask, draw_samples - use mersenne_twister, only: random_setseed, random_number, random_stat - use radiation_tools, only: check_error_msg - use rrtmgp_lw_gas_optics, only: lw_gas_props - use netcdf - - implicit none - -contains - -!>\defgroup rrtmgp_lw_cloud_sampling_mod GFS RRTMGP-LW Cloud Sampling Module -!> \section arg_table_rrtmgp_lw_cloud_sampling_run -!! \htmlinclude rrtmgp_lw_cloud_sampling_run.html -!! -!> \ingroup rrtmgp_lw_cloud_sampling -!! -!! \brief This routine performs the McICA cloud-sampling and maps the shortwave cloud- -!! optical properties, defined for each spectral band, to each spectral point (g-point). -!! -!! \section rrtmgp_lw_cloud_sampling_run - subroutine rrtmgp_lw_cloud_sampling_run(doLWrad, nCol, nLev, icseed_lw, iovr,iovr_convcld,& - iovr_max, iovr_maxrand, iovr_rand, iovr_dcorr, iovr_exp, iovr_exprand, isubc_lw, & - cld_frac, precip_frac, cloud_overlap_param, precip_overlap_param, cld_cnv_frac, & - cnv_cloud_overlap_param, imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, & - lw_optical_props_cloudsByBand, lw_optical_props_cnvcloudsByBand, & - lw_optical_props_precipByBand, lw_optical_props_clouds, lw_optical_props_cnvclouds, & - lw_optical_props_precip, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doLWrad ! Logical flag for shortwave radiation call - integer, intent(in) :: & - nCol, & ! Number of horizontal gridpoints - nLev, & ! Number of vertical layers - imfdeepcnv, & ! - imfdeepcnv_gf, & ! - imfdeepcnv_samf, & ! - iovr, & ! Choice of cloud-overlap method - iovr_convcld, & ! Choice of convective cloud-overlap - iovr_max, & ! Flag for maximum cloud overlap method - iovr_maxrand, & ! Flag for maximum-random cloud overlap method - iovr_rand, & ! Flag for random cloud overlap method - iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method - iovr_exp, & ! Flag for exponential cloud overlap method - iovr_exprand, & ! Flag for exponential-random cloud overlap method - isubc_lw - integer,intent(in),dimension(:) :: & - icseed_lw ! auxiliary special cloud related array when module - ! variable isubc_lw=2, it provides permutation seed - ! for each column profile that are used for generating - ! random numbers. when isubc_lw /=2, it will not be used. - real(kind_phys), dimension(:,:),intent(in) :: & - cld_frac, & ! Total cloud fraction by layer - cld_cnv_frac, & ! Convective cloud fraction by layer - precip_frac, & ! Precipitation fraction by layer - cloud_overlap_param, & ! Cloud overlap parameter - cnv_cloud_overlap_param, & ! Convective cloud overlap parameter - precip_overlap_param ! Precipitation overlap parameter - type(ty_optical_props_2str),intent(in) :: & - lw_optical_props_cloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (clouds) - lw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: Longwave optical properties in each band (convective cloud) - lw_optical_props_precipByBand ! RRTMGP DDT: Longwave optical properties in each band (precipitation) - - ! Outputs - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error code - type(ty_optical_props_2str),intent(inout) :: & - lw_optical_props_clouds, & ! RRTMGP DDT: Shortwave optical properties by spectral point (clouds) - lw_optical_props_cnvclouds, & ! RRTMGP DDT: Shortwave optical properties by spectral point (convective cloud) - lw_optical_props_precip ! RRTMGP DDT: Shortwave optical properties by spectral point (precipitation) - - ! Local variables - integer :: iCol, iLay, iBand - integer,dimension(ncol) :: ipseed_lw - type(random_stat) :: rng_stat - real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt(),nLev,ncol) :: rng3D,rng3D2 - real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt()*nLev) :: rng2D - real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt()) :: rng1D - logical, dimension(ncol,nLev,lw_gas_props%get_ngpt()) :: maskMCICA - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doLWrad) return - - ! #################################################################################### - ! First sample the clouds... - ! #################################################################################### - lw_optical_props_clouds%band2gpt = lw_gas_props%get_band_lims_gpoint() - lw_optical_props_clouds%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do iBand=1,lw_gas_props%get_nband() - lw_optical_props_clouds%gpt2band(lw_optical_props_clouds%band2gpt(1,iBand):lw_optical_props_clouds%band2gpt(2,iBand)) = iBand - end do - - ! Change random number seed value for each radiation invocation (isubc_lw =1 or 2). - if(isubc_lw == 1) then ! advance prescribed permutation seed - do iCol = 1, ncol - ipseed_lw(iCol) = lw_gas_props%get_ngpt() + iCol - enddo - elseif (isubc_lw == 2) then ! use input array of permutaion seeds - do iCol = 1, ncol - ipseed_lw(iCol) = icseed_lw(iCol) - enddo - endif - - ! Call RNG. Mersennse Twister accepts 1D array, so loop over columns and collapse along G-points - ! and layers. ([nGpts,nLev,nColumn]-> [nGpts*nLev]*nColumn) - do iCol=1,ncol - call random_setseed(ipseed_lw(icol),rng_stat) - ! Use same rng for each layer - if (iovr == iovr_max) then - call random_number(rng1D,rng_stat) - do iLay=1,nLev - rng3D(:,iLay,iCol) = rng1D - enddo - else - do iLay=1,nLev - call random_number(rng1D,rng_stat) - rng3D(:,iLay,iCol) = rng1D - enddo - endif - enddo - - ! Cloud-overlap. - ! Maximum-random, random or maximum. - if (iovr == iovr_maxrand .or. iovr == iovr_rand .or. iovr == iovr_max) then - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac, maskMCICA) - endif - ! Exponential decorrelation length overlap - if (iovr == iovr_dcorr) then - ! Generate second RNG - do iCol=1,ncol - call random_setseed(ipseed_lw(icol),rng_stat) - call random_number(rng2D,rng_stat) - rng3D2(:,:,iCol) = reshape(source = rng2D,shape=[lw_gas_props%get_ngpt(),nLev]) - enddo - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac, maskMCICA, & - overlap_param = cloud_overlap_param(:,1:nLev-1), & - randoms2 = real(rng3D2, kind=kind_phys)) - endif - ! Exponential or Exponential-random - if (iovr == iovr_exp .or. iovr == iovr_exprand) then - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac, maskMCICA, & - overlap_param = cloud_overlap_param(:,1:nLev-1)) - endif - - ! - ! Sampling. Map band optical depth to each g-point using McICA - ! - call check_error_msg('rrtmgp_lw_cloud_sampling_run_draw_samples',& - draw_samples(maskMCICA, .true., & - lw_optical_props_cloudsByBand, & - lw_optical_props_clouds)) - - end subroutine rrtmgp_lw_cloud_sampling_run - -end module rrtmgp_lw_cloud_sampling diff --git a/physics/rrtmgp_lw_cloud_sampling.meta b/physics/rrtmgp_lw_cloud_sampling.meta deleted file mode 100644 index c1ae9d139..000000000 --- a/physics/rrtmgp_lw_cloud_sampling.meta +++ /dev/null @@ -1,226 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_cloud_sampling - type = scheme - dependencies = machine.F,mersenne_twister.f,rrtmgp_sampling.F90,radiation_tools.F90 - -###################################################### -[ccpp-arg-table] - name = rrtmgp_lw_cloud_sampling_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[imfdeepcnv] - standard_name = control_for_deep_convection_scheme - long_name = flag for mass-flux deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_gf] - standard_name = identifier_for_grell_freitas_deep_convection - long_name = flag for Grell-Freitas deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_samf] - standard_name = identifer_for_scale_aware_mass_flux_deep_convection - long_name = flag for SAMF deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[iovr_convcld] - standard_name = flag_for_convective_cloud_overlap_method_for_radiation - long_name = flag for convective cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[isubc_lw] - standard_name = flag_for_lw_clouds_sub_grid_approximation - long_name = flag for lw clouds sub-grid approximation - units = flag - dimensions = () - type = integer - intent = in -[iovr] - standard_name = flag_for_cloud_overlap_method_for_radiation - long_name = max-random overlap clouds - units = flag - dimensions = () - type = integer - intent = in -[iovr_maxrand] - standard_name = flag_for_maximum_random_cloud_overlap_method - long_name = choice of maximum-random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_dcorr] - standard_name = flag_for_decorrelation_length_cloud_overlap_method - long_name = choice of decorrelation-length cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_exp] - standard_name = flag_for_exponential_cloud_overlap_method - long_name = choice of exponential cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_exprand] - standard_name = flag_for_exponential_random_cloud_overlap_method - long_name = choice of exponential-random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_rand] - standard_name = flag_for_random_cloud_overlap_method - long_name = choice of random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_max] - standard_name = flag_for_maximum_cloud_overlap_method - long_name = choice of maximum cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[icseed_lw] - standard_name = random_number_seed_for_mcica_longwave - long_name = seed for random number generation for longwave radiation - units = none - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_frac] - standard_name = convective_cloud_fraction_for_RRTMGP - long_name = layer convective cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[precip_frac] - standard_name = precipitation_fraction_by_layer - long_name = precipitation fraction in each layer - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cloud_overlap_param] - standard_name = cloud_overlap_param - long_name = cloud overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cnv_cloud_overlap_param] - standard_name = convective_cloud_overlap_param - long_name = convective cloud overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[precip_overlap_param] - standard_name = precip_overlap_param - long_name = precipitation overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[lw_optical_props_cloudsByBand] - standard_name = longwave_optical_properties_for_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[lw_optical_props_cnvcloudsByBand] - standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[lw_optical_props_precipByBand] - standard_name = longwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[lw_optical_props_clouds] - standard_name = longwave_optical_properties_for_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_precip] - standard_name = longwave_optical_properties_for_precipitation - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_cnvclouds] - standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_lw_gas_optics.F90 b/physics/rrtmgp_lw_gas_optics.F90 index fad01a336..8cd38f210 100644 --- a/physics/rrtmgp_lw_gas_optics.F90 +++ b/physics/rrtmgp_lw_gas_optics.F90 @@ -12,8 +12,6 @@ module rrtmgp_lw_gas_optics use mo_rte_kind, only: wl use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp use mo_gas_concentrations, only: ty_gas_concs - use mo_source_functions, only: ty_source_func_lw - use mo_optical_props, only: ty_optical_props_1scl use radiation_tools, only: check_error_msg use netcdf #ifdef MPI @@ -77,28 +75,18 @@ module rrtmgp_lw_gas_optics contains -!>\defgroup rrtmgp_lw_gas_optics_mod GFS RRTMGP-LW Gas Optics Module -!! \section arg_table_rrtmgp_lw_gas_optics_init -!! \htmlinclude rrtmgp_lw_gas_optics.html -!! -!> \ingroup rrtmgp_lw_gas_optics -!! -!! RRTMGP relies heavility on derived-data-types, which contain type-bound procedures -!! that are referenced frequently throughout the RRTMGP longwave scheme. The data needed -!! for the correlated k-distribution is also contained within this type. Within this module, -!! the full k-distribution data is read in, reduced by the "active gases" provided, and -!! loaded into the RRTMGP DDT, ty_gas_optics_rrtmgp. -!! -!! \section rrtmgp_lw_gas_optics_init - ! ###################################################################################### - subroutine rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, mpicomm, & - mpirank, mpiroot, minGPpres, maxGPpres, minGPtemp, maxGPtemp, active_gases_array, & - errmsg, errflg) + ! ######################################################################################### + ! SUBROUTINE rrtmgp_lw_gas_optics_init + ! ######################################################################################### + subroutine rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, & + active_gases_array, mpicomm, mpirank, mpiroot, errmsg, errflg) ! Inputs character(len=128),intent(in) :: & rrtmgp_root_dir, & ! RTE-RRTMGP root directory - rrtmgp_lw_file_gas ! RRTMGP file containing coefficients used to compute gaseous optical properties + rrtmgp_lw_file_gas ! RRTMGP file containing K-distribution data + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array integer,intent(in) :: & mpicomm, & ! MPI communicator mpirank, & ! Current MPI rank @@ -109,20 +97,12 @@ subroutine rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, mpicom errmsg ! CCPP error message integer, intent(out) :: & errflg ! CCPP error code - real(kind_phys), intent(out) :: & - minGPtemp, & ! Minimum temperature allowed by RRTMGP. - maxGPtemp, & ! Maximum ... - minGPpres, & ! Minimum pressure allowed by RRTMGP. - maxGPpres ! Maximum pressure allowed by RRTMGP. - character(len=*), dimension(:), intent(in) :: & - active_gases_array ! List of active gases from namelist as array ! Local variables - integer :: ncid, dimID, varID, status, iGas, ierr, ii, mpierr, iChar - integer,dimension(:),allocatable :: temp1, temp2, temp3, temp4, & - temp_log_array1, temp_log_array2, temp_log_array3, temp_log_array4 + integer :: ncid, dimID, varID, status, ii, mpierr, iChar + integer,dimension(:),allocatable :: temp1, temp2, temp3, temp4 character(len=264) :: lw_gas_props_file - type(ty_gas_concs) :: gas_concentrations ! RRTMGP DDT: trace gas concentrations (vmr) + type(ty_gas_concs) :: gas_concs ! RRTMGP DDT: trace gas concentrations (vmr) ! Initialize errmsg = '' @@ -455,9 +435,8 @@ subroutine rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, mpicom ! Initialize RRTMGP DDT's... ! ! ####################################################################################### - allocate(gas_concentrations%gas_name(1:size(active_gases_array))) - gas_concentrations%gas_name(:) = active_gases_array(:) - call check_error_msg('rrtmgp_lw_gas_optics_init',lw_gas_props%load(gas_concentrations, & + call check_error_msg('rrtmgp_lw_gas_optics_init_gas_concs',gas_concs%init(active_gases_array)) + call check_error_msg('rrtmgp_lw_gas_optics_init_load',lw_gas_props%load(gas_concs, & gas_namesLW, key_speciesLW, band2gptLW, band_limsLW, press_refLW, press_ref_tropLW,& temp_refLW, temp_ref_pLW, temp_ref_tLW, vmr_refLW, kmajorLW, kminor_lowerLW, & kminor_upperLW, gas_minorLW, identifier_minorLW, minor_gases_lowerLW, & @@ -467,80 +446,6 @@ subroutine rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, mpicom scale_by_complement_upperLW, kminor_start_lowerLW, kminor_start_upperLW, totplnkLW,& planck_fracLW, rayl_lowerLW, rayl_upperLW, optimal_angle_fitLW)) - ! The minimum pressure allowed in GP RTE calculations. Used to bound uppermost layer - ! temperature (GFS_rrtmgp_pre.F90) - minGPpres = lw_gas_props%get_press_min() - maxGPpres = lw_gas_props%get_press_max() - minGPtemp = lw_gas_props%get_temp_min() - maxGPtemp = lw_gas_props%get_temp_max() - end subroutine rrtmgp_lw_gas_optics_init -!> \section arg_table_rrtmgp_lw_gas_optics_run -!! \htmlinclude rrtmgp_lw_gas_optics_run.html -!! -!! Compute longwave optical prperties (optical-depth) for clear-sky conditions. -!! \section rrtmgp_lw_gas_optics_run - subroutine rrtmgp_lw_gas_optics_run(doLWrad, nCol, nLev, p_lay, p_lev, t_lay, t_lev, tsfg, & - gas_concentrations, lw_optical_props_clrsky, sources, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doLWrad ! Flag to calculate LW irradiances - integer,intent(in) :: & - ncol, & ! Number of horizontal points - nLev ! Number of vertical levels - real(kind_phys), dimension(ncol,nLev), intent(in) :: & - p_lay, & ! Pressure @ model layer-centers (Pa) - t_lay ! Temperature (K) - real(kind_phys), dimension(ncol,nLev+1), intent(in) :: & - p_lev, & ! Pressure @ model layer-interfaces (Pa) - t_lev ! Temperature @ model levels - real(kind_phys), dimension(ncol), intent(in) :: & - tsfg ! Surface ground temperature (K) - type(ty_gas_concs),intent(in) :: & - gas_concentrations ! RRTMGP DDT: trace gas concentrations (vmr) - - ! Output - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error code - type(ty_optical_props_1scl),intent(inout) :: & - lw_optical_props_clrsky ! RRTMGP DDT: longwave clear-sky radiative properties - type(ty_source_func_lw),intent(inout) :: & - sources ! RRTMGP DDT: longwave source functions - - ! Local - integer :: ii - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doLWrad) return - - ! Copy spectral information into GP DDTs. - lw_optical_props_clrsky%band2gpt = lw_gas_props%get_band_lims_gpoint() - sources%band2gpt = lw_gas_props%get_band_lims_gpoint() - sources%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - lw_optical_props_clrsky%band_lims_wvn = lw_gas_props%get_band_lims_wavenumber() - do ii=1,nbndsLW - lw_optical_props_clrsky%gpt2band(band2gptLW(1,ii):band2gptLW(2,ii)) = ii - sources%gpt2band(band2gptLW(1,ii):band2gptLW(2,ii)) = ii - end do - - ! Gas-optics - call check_error_msg('rrtmgp_lw_gas_optics_run',lw_gas_props%gas_optics(& - p_lay, & ! IN - Pressure @ layer-centers (Pa) - p_lev, & ! IN - Pressure @ layer-interfaces (Pa) - t_lay, & ! IN - Temperature @ layer-centers (K) - tsfg, & ! IN - Skin-temperature (K) - gas_concentrations, & ! IN - RRTMGP DDT: trace gas volumne mixing-ratios - lw_optical_props_clrsky, & ! OUT - RRTMGP DDT: longwave optical properties - sources, & ! OUT - RRTMGP DDT: source functions - tlev=t_lev)) ! IN - Temperature @ layer-interfaces (K) (optional) - - end subroutine rrtmgp_lw_gas_optics_run - end module rrtmgp_lw_gas_optics diff --git a/physics/rrtmgp_lw_gas_optics.meta b/physics/rrtmgp_lw_gas_optics.meta deleted file mode 100644 index 0b484b6ac..000000000 --- a/physics/rrtmgp_lw_gas_optics.meta +++ /dev/null @@ -1,203 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_gas_optics - type = scheme - dependencies = machine.F,radiation_tools.F90,GFS_rrtmgp_pre.F90,rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90,rte-rrtmgp/rte/mo_rte_kind.F90,rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90,rte-rrtmgp/rte/mo_optical_props.F90,rte-rrtmgp/rte/mo_source_functions.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_gas_optics_init - type = scheme -[rrtmgp_root_dir] - standard_name = directory_for_rte_rrtmgp_source_code - long_name = directory for rte+rrtmgp source code - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[rrtmgp_lw_file_gas] - standard_name = filename_of_rrtmgp_longwave_k_distribution - long_name = file containing RRTMGP LW k-distribution - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[mpirank] - standard_name = mpi_rank - long_name = current MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpiroot] - standard_name = mpi_root - long_name = master MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpicomm] - standard_name = mpi_communicator - long_name = MPI communicator - units = index - dimensions = () - type = integer - intent = in -[minGPpres] - standard_name = minimum_pressure_in_RRTMGP - long_name = minimum pressure allowed in RRTMGP - units = Pa - dimensions = () - type = real - kind = kind_phys - intent = out -[maxGPpres] - standard_name = maximum_pressure_in_RRTMGP - long_name = maximum pressure allowed in RRTMGP - units = Pa - dimensions = () - type = real - kind = kind_phys - intent = out -[minGPtemp] - standard_name = minimum_temperature_in_RRTMGP - long_name = minimum temperature allowed in RRTMGP - units = K - dimensions = () - type = real - kind = kind_phys - intent = out -[maxGPtemp] - standard_name = maximum_temperature_in_RRTMGP - long_name = maximum temperature allowed in RRTMGP - units = K - dimensions = () - type = real - kind = kind_phys - intent = out -[active_gases_array] - standard_name = list_of_active_gases_used_by_RRTMGP - long_name = list of active gases used by RRTMGP - units = none - dimensions = (number_of_active_gases_used_by_RRTMGP) - type = character - kind = len=* - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_gas_optics_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = flag to calculate LW irradiances - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure layer - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure level - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature layer - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[t_lev] - standard_name = air_temperature_at_interface_for_RRTMGP - long_name = air temperature level - units = K - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[tsfg] - standard_name = surface_ground_temperature_for_radiation - long_name = surface ground temperature for radiation - units = K - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[gas_concentrations] - standard_name = Gas_concentrations_for_RRTMGP_suite - long_name = DDT containing gas concentrations for RRTMGP radiation scheme - units = DDT - dimensions = () - type = ty_gas_concs - intent = in -[lw_optical_props_clrsky] - standard_name = longwave_optical_properties_for_clear_sky - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_1scl - intent = inout -[sources] - standard_name = longwave_source_function - long_name = Fortran DDT containing RRTMGP source functions - units = DDT - dimensions = () - type = ty_source_func_lw - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_lw_main.F90 b/physics/rrtmgp_lw_main.F90 new file mode 100644 index 000000000..c0bc99d35 --- /dev/null +++ b/physics/rrtmgp_lw_main.F90 @@ -0,0 +1,611 @@ +! ########################################################################################### +!> \file rrtmgp_lw_main.F90 +!! +!> \defgroup rrtmgp_lw_main rrtmgp_lw_main.F90 +!! +!! \brief This module contains the longwave RRTMGP radiation scheme. +!! +! ########################################################################################### +module rrtmgp_lw_main + use machine, only: kind_phys, kind_dbl_prec + use mo_optical_props, only: ty_optical_props_1scl, ty_optical_props_2str + use mo_cloud_optics, only: ty_cloud_optics + use mo_rte_lw, only: rte_lw + use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp + use mo_gas_concentrations, only: ty_gas_concs + use mo_fluxes_byband, only: ty_fluxes_byband + use mo_source_functions, only: ty_source_func_lw + use radiation_tools, only: check_error_msg + use rrtmgp_lw_gas_optics, only: lw_gas_props,rrtmgp_lw_gas_optics_init + use rrtmgp_lw_cloud_optics, only: lw_cloud_props, rrtmgp_lw_cloud_optics_init, abssnow0, & + abssnow1, absrain + use module_radiation_gases, only: NF_VGAS, getgases, getozn + use GFS_rrtmgp_pre, only: iStr_h2o, iStr_co2, iStr_o3, iStr_n2o, iStr_ch4, & + iStr_o2, iStr_ccl4, iStr_cfc11, iStr_cfc12, iStr_cfc22, & + eps, oneminus, ftiny + use mersenne_twister, only: random_setseed, random_number, random_stat + use rrtmgp_sampling, only: sampled_mask, draw_samples + implicit none + + type(ty_gas_concs) :: gas_concs + type(ty_optical_props_1scl) :: lw_optical_props_clrsky, lw_optical_props_aerosol_local + type(ty_optical_props_2str) :: lw_optical_props_clouds, lw_optical_props_cloudsByBand, & + lw_optical_props_cnvcloudsByBand, lw_optical_props_pblcloudsByBand, & + lw_optical_props_precipByBand + type(ty_source_func_lw) :: sources + + public rrtmgp_lw_main_init, rrtmgp_lw_main_run +contains + ! ######################################################################################### +!! \section arg_table_rrtmgp_lw_main_init +!! \htmlinclude rrtmgp_lw_main_int.html +!! +!> \ingroup rrtmgp_lw_main +!! +!! \brief +!! +!! \section rrtmgp_lw_main_init +!> @{ + ! ######################################################################################### + subroutine rrtmgp_lw_main_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, rrtmgp_lw_file_clouds,& + active_gases_array, doGP_cldoptics_PADE, doGP_cldoptics_LUT, doGP_sgs_pbl, & + doGP_sgs_cnv, nrghice, mpicomm, mpirank, mpiroot, nLay, rrtmgp_phys_blksz, & + errmsg, errflg) + + ! Inputs + character(len=128),intent(in) :: & + rrtmgp_root_dir, & ! RTE-RRTMGP root directory + rrtmgp_lw_file_clouds, & ! RRTMGP file containing coefficients used to compute + ! clouds optical properties + rrtmgp_lw_file_gas ! RRTMGP file containing coefficients used to compute + ! gaseous optical properties + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array) + logical, intent(in) :: & + doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? + doGP_cldoptics_LUT, & ! Use RRTMGP cloud-optics: LUTs? + doGP_sgs_pbl, & ! Flag to include sgs PBL clouds + doGP_sgs_cnv ! Flag to include sgs convective clouds + integer, intent(inout) :: & + nrghice ! Number of ice-roughness categories + integer,intent(in) :: & + mpicomm, & ! MPI communicator + mpirank, & ! Current MPI rank + mpiroot, & ! Master MPI rank + rrtmgp_phys_blksz, & ! Number of horizontal points to process at once. + nLay + + ! Outputs + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error code + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! RRTMGP longwave gas-optics (k-distribution) initialization + call rrtmgp_lw_gas_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_gas, & + active_gases_array, mpicomm, mpirank, mpiroot, errmsg, errflg) + + ! RRTMGP longwave cloud-optics initialization + call rrtmgp_lw_cloud_optics_init(rrtmgp_root_dir, rrtmgp_lw_file_clouds, & + doGP_cldoptics_PADE, doGP_cldoptics_LUT, nrghice, mpicomm, mpirank, mpiroot, & + errmsg, errflg) + + ! DDTs + + ! ty_gas_concs + call check_error_msg('rrtmgp_lw_main_gas_concs_init',gas_concs%init(active_gases_array)) + + ! ty_optical_props + call check_error_msg('rrtmgp_lw_main_gas_optics_init',& + lw_optical_props_clrsky%alloc_1scl(rrtmgp_phys_blksz, nLay, lw_gas_props)) + call check_error_msg('rrtmgp_lw_main_sources_init',& + sources%alloc(rrtmgp_phys_blksz, nLay, lw_gas_props)) + call check_error_msg('rrtmgp_lw_main_cloud_optics_init',& + lw_optical_props_cloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, lw_gas_props%get_band_lims_wavenumber())) + call check_error_msg('rrtmgp_lw_main_precip_optics_init',& + lw_optical_props_precipByBand%alloc_2str(rrtmgp_phys_blksz, nLay, lw_gas_props%get_band_lims_wavenumber())) + call check_error_msg('rrtmgp_lw_mian_cloud_sampling_init', & + lw_optical_props_clouds%alloc_2str(rrtmgp_phys_blksz, nLay, lw_gas_props)) + call check_error_msg('rrtmgp_lw_main_aerosol_optics_init',& + lw_optical_props_aerosol_local%alloc_1scl(rrtmgp_phys_blksz, nLay, lw_gas_props%get_band_lims_wavenumber())) + if (doGP_sgs_cnv) then + call check_error_msg('rrtmgp_lw_main_cnv_cloud_optics_init',& + lw_optical_props_cnvcloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, lw_gas_props%get_band_lims_wavenumber())) + endif + if (doGP_sgs_pbl) then + call check_error_msg('rrtmgp_lw_main_pbl_cloud_optics_init',& + lw_optical_props_pblcloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, lw_gas_props%get_band_lims_wavenumber())) + endif + + end subroutine rrtmgp_lw_main_init +!> @} + ! ###################################################################################### +!! \section arg_table_rrtmgp_lw_main_run +!! \htmlinclude rrtmgp_lw_main_run.html +!! +!> \ingroup rrtmgp_lw_main +!! +!! \brief +!! +!! \section rrtmgp_lw_main_run +!> @{ + ! ###################################################################################### + subroutine rrtmgp_lw_main_run(doLWrad, doLWclrsky, top_at_1, doGP_lwscat, & + use_LW_jacobian, doGP_sgs_cnv, doGP_sgs_pbl, nCol, nLay, nGases,rrtmgp_phys_blksz,& + nGauss_angles, icseed_lw, iovr, iovr_convcld, iovr_max, iovr_maxrand, iovr_rand, & + iovr_dcorr, iovr_exp, iovr_exprand, isubc_lw, semis, tsfg, p_lay, p_lev, t_lay, & + t_lev, vmr_o2, vmr_h2o, vmr_o3, vmr_ch4, vmr_n2o, vmr_co2, & + cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, & + cld_rwp, cld_rerain, precip_frac, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, & + cld_cnv_reice, cld_pbl_lwp, cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, & + cloud_overlap_param, active_gases_array, aerlw_tau, aerlw_ssa, aerlw_g, & + fluxlwUP_allsky, fluxlwDOWN_allsky, fluxlwUP_clrsky, fluxlwDOWN_clrsky, & + fluxlwUP_jac, fluxlwUP_radtime, fluxlwDOWN_radtime, errmsg, errflg) + + ! Inputs + logical, intent(in) :: & + doLWrad, & ! Flag to perform longwave calculation + doLWclrsky, & ! Flag to compute clear-sky fluxes + top_at_1, & ! Flag for vertical ordering convention + use_LW_jacobian, & ! Flag to compute Jacobian of longwave surface flux + doGP_sgs_pbl, & ! Flag to include sgs PBL clouds + doGP_sgs_cnv, & ! Flag to include sgs convective clouds + doGP_lwscat ! Flag to include scattering in clouds + integer,intent(in) :: & + nCol, & ! Number of horizontal points + nLay, & ! Number of vertical grid points. + nGases, & ! Number of active gases + rrtmgp_phys_blksz, & ! Number of horizontal points to process at once. + nGauss_angles, & ! Number of gaussian quadrature angles used + iovr, & ! Choice of cloud-overlap method + iovr_convcld, & ! Choice of convective cloud-overlap + iovr_max, & ! Flag for maximum cloud overlap method + iovr_maxrand, & ! Flag for maximum-random cloud overlap method + iovr_rand, & ! Flag for random cloud overlap method + iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method + iovr_exp, & ! Flag for exponential cloud overlap method + iovr_exprand, & ! Flag for exponential-random cloud overlap method + isubc_lw ! Flag for cloud-seeding (rng) for cloud-sampling + integer,intent(in),dimension(:) :: & + icseed_lw ! Seed for random number generation for longwave radiation + real(kind_phys), dimension(:), intent(in) :: & + semis, & ! Surface-emissivity (1) + tsfg ! Skin temperature (K) + real(kind_phys), dimension(:,:), intent(in) :: & + p_lay, & ! Pressure @ model layer-centers (Pa) + t_lay, & ! Temperature (K) + p_lev, & ! Pressure @ model layer-interfaces (Pa) + t_lev, & ! Temperature @ model levels (K) + vmr_o2, & ! Molar-mixing ratio oxygen + vmr_h2o, & ! Molar-mixing ratio water vapor + vmr_o3, & ! Molar-mixing ratio ozone + vmr_ch4, & ! Molar-mixing ratio methane + vmr_n2o, & ! Molar-mixing ratio nitrous oxide + vmr_co2, & ! Molar-mixing ratio carbon dioxide + cld_frac, & ! Cloud-fraction for stratiform clouds + cld_lwp, & ! Water path for stratiform liquid cloud-particles + cld_reliq, & ! Effective radius for stratiform liquid cloud-particles + cld_iwp, & ! Water path for stratiform ice cloud-particles + cld_reice, & ! Effective radius for stratiform ice cloud-particles + cld_swp, & ! Water path for snow hydrometeors + cld_resnow, & ! Effective radius for snow hydrometeors + cld_rwp, & ! Water path for rain hydrometeors + cld_rerain, & ! Effective radius for rain hydrometeors + precip_frac, & ! Precipitation fraction (not active, currently precipitation optics uses cloud-fraction) + cld_cnv_lwp, & ! Water path for convective liquid cloud-particles + cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles + cld_cnv_iwp, & ! Water path for convective ice cloud-particles + cld_cnv_reice, & ! Effective radius for convective ice cloud-particles + cld_pbl_lwp, & ! Water path for PBL liquid cloud-particles + cld_pbl_reliq, & ! Effective radius for PBL liquid cloud-particles + cld_pbl_iwp, & ! Water path for PBL ice cloud-particles + cld_pbl_reice, & ! Effective radius for PBL ice cloud-particles + cloud_overlap_param ! Cloud overlap parameter + real(kind_phys), dimension(:,:,:), intent(in) :: & + aerlw_tau, & ! Aerosol optical depth + aerlw_ssa, & ! Aerosol single scattering albedo + aerlw_g ! Aerosol asymmetry paramter + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array + + ! Outputs + real(kind_phys), dimension(:,:), intent(inout) :: & + fluxlwUP_jac, & ! Jacobian of upwelling LW surface radiation (W/m2/K) + fluxlwUP_allsky, & ! All-sky flux (W/m2) + fluxlwDOWN_allsky, & ! All-sky flux (W/m2) + fluxlwUP_clrsky, & ! Clear-sky flux (W/m2) + fluxlwDOWN_clrsky, & ! All-sky flux (W/m2) + fluxlwUP_radtime, & ! Copy of fluxes (Used for coupling) + fluxlwDOWN_radtime ! + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + + ! Local variables + type(ty_fluxes_byband) :: flux_allsky, flux_clrsky + integer :: iCol, iLay, iGas, iBand, iCol2, ix, iblck + integer, dimension(rrtmgp_phys_blksz) :: ipseed_lw + type(random_stat) :: rng_stat + real(kind_phys), dimension(rrtmgp_phys_blksz) :: zcf0, zcf1 + logical, dimension(rrtmgp_phys_blksz,nLay,lw_gas_props%get_ngpt()) :: maskMCICA + real(kind_phys), dimension(rrtmgp_phys_blksz) :: tau_rain, tau_snow + real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt()) :: rng1D + real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt(),nLay,rrtmgp_phys_blksz) :: rng3D,rng3D2 + real(kind_dbl_prec), dimension(lw_gas_props%get_ngpt()*nLay) :: rng2D + real(kind_phys), dimension(rrtmgp_phys_blksz,nLay+1,lw_gas_props%get_nband()),target :: & + fluxLW_up_allsky, fluxLW_up_clrsky, fluxLW_dn_allsky, fluxLW_dn_clrsky + real(kind_phys), dimension(rrtmgp_phys_blksz,lw_gas_props%get_ngpt()) :: lw_Ds + real(kind_phys), dimension(lw_gas_props%get_nband(),rrtmgp_phys_blksz) :: sfc_emiss_byband + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + if (.not. doLWrad) return + + ! ###################################################################################### + ! + ! Loop over all columns... + ! + ! ###################################################################################### + do iCol=1,nCol,rrtmgp_phys_blksz + iCol2 = iCol + rrtmgp_phys_blksz - 1 + + ! Initialize/reset + + ! ty_optical_props + lw_optical_props_clrsky%tau = 0._kind_phys + lw_optical_props_precipByBand%tau = 0._kind_phys + lw_optical_props_precipByBand%ssa = 0._kind_phys + lw_optical_props_precipByBand%g = 0._kind_phys + lw_optical_props_cloudsByBand%tau = 0._kind_phys + lw_optical_props_cloudsByBand%ssa = 0._kind_phys + lw_optical_props_cloudsByBand%g = 0._kind_phys + lw_optical_props_clouds%tau = 0._kind_phys + lw_optical_props_clouds%ssa = 0._kind_phys + lw_optical_props_clouds%g = 0._kind_phys + sources%sfc_source = 0._kind_phys + sources%lay_source = 0._kind_phys + sources%lev_source_inc = 0._kind_phys + sources%lev_source_dec = 0._kind_phys + sources%sfc_source_Jac = 0._kind_phys + fluxLW_up_allsky = 0._kind_phys + fluxLW_dn_allsky = 0._kind_phys + fluxLW_up_clrsky = 0._kind_phys + fluxLW_dn_clrsky = 0._kind_phys + if (doGP_sgs_cnv) lw_optical_props_cnvcloudsByBand%tau = 0._kind_phys + if (doGP_sgs_pbl) lw_optical_props_pblcloudsByBand%tau = 0._kind_phys + + ! ty_fluxes_byband + fluxLW_up_allsky = 0._kind_phys + fluxLW_dn_allsky = 0._kind_phys + fluxLW_up_clrsky = 0._kind_phys + fluxLW_dn_clrsky = 0._kind_phys + flux_allsky%bnd_flux_up => fluxLW_up_allsky + flux_allsky%bnd_flux_dn => fluxLW_dn_allsky + flux_clrsky%bnd_flux_up => fluxLW_up_clrsky + flux_clrsky%bnd_flux_dn => fluxLW_dn_clrsky + + ! ################################################################################### + ! + ! Set gas-concentrations + ! + ! ################################################################################### + call check_error_msg('rrtmgp_lw_main_set_vmr_o2', & + gas_concs%set_vmr(trim(active_gases_array(istr_o2)), vmr_o2(iCol:iCol2,:))) + call check_error_msg('rrtmgp_lw_main_set_vmr_co2', & + gas_concs%set_vmr(trim(active_gases_array(istr_co2)),vmr_co2(iCol:iCol2,:))) + call check_error_msg('rrtmgp_lw_main_set_vmr_ch4', & + gas_concs%set_vmr(trim(active_gases_array(istr_ch4)),vmr_ch4(iCol:iCol2,:))) + call check_error_msg('rrtmgp_lw_main_set_vmr_n2o', & + gas_concs%set_vmr(trim(active_gases_array(istr_n2o)),vmr_n2o(iCol:iCol2,:))) + call check_error_msg('rrtmgp_lw_main_set_vmr_h2o', & + gas_concs%set_vmr(trim(active_gases_array(istr_h2o)),vmr_h2o(iCol:iCol2,:))) + call check_error_msg('rrtmgp_lw_main_set_vmr_o3', & + gas_concs%set_vmr(trim(active_gases_array(istr_o3)), vmr_o3(iCol:iCol2,:))) + + ! ################################################################################### + ! + ! Surface emissity in each band + ! + ! ################################################################################### + ! Assign same emissivity to all band + do iblck=1,rrtmgp_phys_blksz + if (semis(iCol+iblck-1) > eps .and. semis(iCol+iblck-1) <= 1._kind_phys) then + do iBand=1,lw_gas_props%get_nband() + sfc_emiss_byband(iBand,iblck) = semis(iCol+iblck-1) + enddo + else + sfc_emiss_byband(1:lw_gas_props%get_nband(),iblck) = 1.0 + endif + enddo + + ! ################################################################################### + ! + ! Compute gas-optics... + ! + ! ################################################################################### + call check_error_msg('rrtmgp_lw_main_gas_optics',lw_gas_props%gas_optics(& + p_lay(iCol:iCol2,:), & ! IN - Pressure @ layer-centers (Pa) + p_lev(iCol:iCol2,:), & ! IN - Pressure @ layer-interfaces (Pa) + t_lay(iCol:iCol2,:), & ! IN - Temperature @ layer-centers (K) + tsfg(iCol:iCol2), & ! IN - Skin-temperature (K) + gas_concs, & ! IN - RRTMGP DDT: trace gas volumne mixing-ratios + lw_optical_props_clrsky, & ! OUT - RRTMGP DDT: longwave optical properties + sources, & ! OUT - RRTMGP DDT: source functions + tlev=t_lev(iCol:iCol2,:))) ! IN - Temperature @ layer-interfaces (K) (optional) + + ! ################################################################################### + ! + ! Compute cloud-optics... + ! + ! ################################################################################### + ! Create clear/cloudy indicator + zcf0(:) = 1._kind_phys + zcf1(:) = 1._kind_phys + do iblck = 1, rrtmgp_phys_blksz + do iLay=1,nLay + zcf0(iblck) = min(zcf0(iblck), 1._kind_phys - cld_frac(iCol+iblck-1,iLay)) + enddo + if (zcf0(iblck) <= ftiny) zcf0(iblck) = 0._kind_phys + if (zcf0(iblck) > oneminus) zcf0(iblck) = 1._kind_phys + zcf1(iblck) = 1._kind_phys - zcf0(iblck) + enddo + + if (any(zcf1 .gt. eps)) then + ! Microphysical (gridmean) cloud optics + call check_error_msg('rrtmgp_lw_main_cloud_optics',lw_cloud_props%cloud_optics(& + cld_lwp(iCol:iCol2,:), & ! IN - Cloud liquid water path (g/m2) + cld_iwp(iCol:iCol2,:), & ! IN - Cloud ice water path (g/m2) + cld_reliq(iCol:iCol2,:), & ! IN - Cloud liquid effective radius (microns) + cld_reice(iCol:iCol2,:), & ! IN - Cloud ice effective radius (microns) + lw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT containing cloud radiative properties + ! in each band + ! Include convective (subgrid scale) clouds? + if (doGP_sgs_cnv) then + ! Compute + call check_error_msg('rrtmgp_lw_main_cnv_cloud_optics',lw_cloud_props%cloud_optics(& + cld_cnv_lwp(iCol:iCol2,:), & ! IN - Convective cloud liquid water path (g/m2) + cld_cnv_iwp(iCol:iCol2,:), & ! IN - Convective cloud ice water path (g/m2) + cld_cnv_reliq(iCol:iCol2,:), & ! IN - Convective cloud liquid effective radius (microns) + cld_cnv_reice(iCol:iCol2,:), & ! IN - Convective cloud ice effective radius (microns) + lw_optical_props_cnvcloudsByBand)) ! OUT - RRTMGP DDT containing convective cloud radiative properties + ! in each band + ! Increment + call check_error_msg('rrtmgp_lw_main_increment_cnvclouds_to_clouds',& + lw_optical_props_cnvcloudsByBand%increment(lw_optical_props_cloudsByBand)) + endif + + ! Include PBL (subgrid scale) clouds? + if (doGP_sgs_pbl) then + ! Compute + call check_error_msg('rrtmgp_lw_main_pbl_cloud_optics',lw_cloud_props%cloud_optics(& + cld_pbl_lwp(iCol:iCol2,:), & ! IN - PBL cloud liquid water path (g/m2) + cld_pbl_iwp(iCol:iCol2,:), & ! IN - PBL cloud ice water path (g/m2) + cld_pbl_reliq(iCol:iCol2,:), & ! IN - PBL cloud liquid effective radius (microns) + cld_pbl_reice(iCol:iCol2,:), & ! IN - PBL cloud ice effective radius (microns) + lw_optical_props_pblcloudsByBand)) ! OUT - RRTMGP DDT containing PBL cloud radiative properties + ! in each band + ! Increment + call check_error_msg('rrtmgp_lw_main_increment_pblclouds_to_clouds',& + lw_optical_props_pblcloudsByBand%increment(lw_optical_props_cloudsByBand)) + endif + endif + + ! ################################################################################### + ! + ! Cloud precipitation optics: rain and snow(+groupel) + ! + ! ################################################################################### + tau_rain(:) = 0._kind_phys + tau_snow(:) = 0._kind_phys + do ix=1,rrtmgp_phys_blksz + do iLay=1,nLay + if (cld_frac(iCol+ix-1,iLay) .gt. eps) then + ! Rain optical-depth (No band dependence) + tau_rain(ix) = absrain*cld_rwp(iCol+ix-1,iLay) + + ! Snow (+groupel) optical-depth (No band dependence) + if (cld_swp(iCol+ix-1,iLay) .gt. 0. .and. cld_resnow(iCol+ix-1,iLay) .gt. 10._kind_phys) then + tau_snow(ix) = abssnow0*1.05756*cld_swp(iCol+ix-1,iLay)/cld_resnow(iCol+ix-1,iLay) + else + tau_snow(ix) = 0.0 + endif + do iBand=1,lw_gas_props%get_nband() + lw_optical_props_precipByBand%tau(ix,iLay,iBand) = tau_rain(ix) + tau_snow(ix) + enddo + endif + enddo + enddo + ! Increment + call check_error_msg('rrtmgp_lw_main_increment_precip_to_clouds',& + lw_optical_props_precipByBand%increment(lw_optical_props_cloudsByBand)) + + ! ################################################################################### + ! + ! Cloud-sampling + ! *Note* All of the included cloud-types are sampled together, not independently. + ! + ! ################################################################################### + if (any(zcf1 .gt. eps)) then + ! Change random number seed value for each radiation invocation (isubc_lw =1 or 2). + if(isubc_lw == 1) then ! advance prescribed permutation seed + do ix=1,rrtmgp_phys_blksz + ipseed_lw(ix) = lw_gas_props%get_ngpt() + iCol + ix - 1 + enddo + elseif (isubc_lw == 2) then ! use input array of permutaion seeds + do ix=1,rrtmgp_phys_blksz + ipseed_lw(ix) = icseed_lw(iCol+ix-1) + enddo + endif + + ! Call RNG + do ix=1,rrtmgp_phys_blksz + call random_setseed(ipseed_lw(ix),rng_stat) + ! Use same rng for each layer + if (iovr == iovr_max) then + call random_number(rng1D,rng_stat) + do iLay=1,nLay + rng3D(:,iLay,ix) = rng1D + enddo + else + do iLay=1,nLay + call random_number(rng1D,rng_stat) + rng3D(:,iLay,ix) = rng1D + enddo + endif + enddo + + ! Cloud-overlap. + ! Maximum-random, random or maximum. + if (iovr == iovr_maxrand .or. iovr == iovr_rand .or. iovr == iovr_max) then + call sampled_mask(real(rng3D,kind=kind_phys), cld_frac(iCol:iCol2,:), maskMCICA) + endif + ! Exponential decorrelation length overlap + if (iovr == iovr_dcorr) then + do ix=1,rrtmgp_phys_blksz + ! Generate second RNG + call random_setseed(ipseed_lw(ix),rng_stat) + call random_number(rng2D,rng_stat) + rng3D2(:,:,ix) = reshape(source = rng2D,shape=[lw_gas_props%get_ngpt(),nLay]) + enddo + ! + call sampled_mask(real(rng3D,kind=kind_phys), cld_frac(iCol:iCol2,:), maskMCICA, & + overlap_param = cloud_overlap_param(iCol:iCol2,1:nLay-1), randoms2 = real(rng3D2, kind=kind_phys)) + endif + ! Exponential or Exponential-random + if (iovr == iovr_exp .or. iovr == iovr_exprand) then + call sampled_mask(real(rng3D,kind=kind_phys), cld_frac(iCol:iCol2,:), maskMCICA, & + overlap_param = cloud_overlap_param(iCol:iCol2,1:nLay-1)) + endif + ! Sampling. Map band optical depth to each g-point using McICA + call check_error_msg('rrtmgp_lw_main_cloud_sampling',& + draw_samples(maskMCICA, .true., & + lw_optical_props_cloudsByBand, lw_optical_props_clouds)) + endif + + ! ################################################################################### + ! + ! Compute clear-sky fluxes (gaseous+aerosol) (optional) + ! + ! ################################################################################### + ! Increment + lw_optical_props_aerosol_local%tau = aerlw_tau(iCol:iCol2,:,:) + call check_error_msg('rrtmgp_lw_main_increment_aerosol_to_clrsky',& + lw_optical_props_aerosol_local%increment(lw_optical_props_clrsky)) + + ! Call RTE solver + if (doLWclrsky) then + call check_error_msg('rrtmgp_lw_main_opt_angle',& + lw_gas_props%compute_optimal_angles(lw_optical_props_clrsky,lw_Ds)) + if (nGauss_angles .gt. 1) then + call check_error_msg('rrtmgp_lw_main_lw_rte_clrsky',rte_lw( & + lw_optical_props_clrsky, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_clrsky, & ! OUT - Fluxes + n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature + else + call check_error_msg('rrtmgp_lw_main_lw_rte_clrsky',rte_lw( & + lw_optical_props_clrsky, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_clrsky, & ! OUT - Fluxes + lw_Ds = lw_Ds)) + endif + + ! Store fluxes + fluxlwUP_clrsky(iCol:iCol2,:) = sum(flux_clrsky%bnd_flux_up, dim=3) + fluxlwDOWN_clrsky(iCol:iCol2,:) = sum(flux_clrsky%bnd_flux_dn, dim=3) + else + fluxlwUP_clrsky(iCol:iCol2,:) = 0.0 + fluxlwDOWN_clrsky(iCol:iCol2,:) = 0.0 + endif + + ! ################################################################################### + ! + ! All-sky fluxes (clear-sky + clouds + precipitation) + ! *Note* CCPP does not allow for polymorphic types, they are ambiguous to the CCPP + ! framework. rte-rrtmgp uses polymorphic types extensively, for example, querying the + ! type to determine physics configuration/pathway/etc... + ! + ! The logic in the code below is to satisfy the polymorphishm in the rte-rrtmgp code. + ! The rte-rrtmgp "increment" procedures are utilized to provide the correct type to the + ! rte solver (rte_lw). Rte_lw quieries the type determine if scattering is to be + ! included in the calculation. The increment procedures are called so that the correct + ! optical properties are inherited. ugh... + ! + ! ################################################################################### + + ! Include LW cloud-scattering? + if (doGP_lwscat) then + ! Increment + call check_error_msg('rrtmgp_lw_main_increment_clrsky_to_clouds',& + lw_optical_props_clrsky%increment(lw_optical_props_clouds)) + + if (use_LW_jacobian) then + ! Compute LW Jacobians + call check_error_msg('rrtmgp_lw_main_lw_rte_allsky',rte_lw( & + lw_optical_props_clouds, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_allsky, & ! OUT - Flxues + n_gauss_angles = nGauss_angles, & ! IN - Number of angles in Gaussian quadrature + flux_up_Jac = fluxlwUP_jac)) ! OUT - surface temperature flux (upward) Jacobian (W/m2/K) + else + call check_error_msg('rrtmgp_lw_main_lw_rte_allsky',rte_lw( & + lw_optical_props_clouds, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_allsky, & ! OUT - Flxues + n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature + end if + ! No scattering in LW clouds. + else + ! Increment + call check_error_msg('rrtmgp_lw_main_increment_clouds_to_clrsky', & + lw_optical_props_clouds%increment(lw_optical_props_clrsky)) + + if (use_LW_jacobian) then + ! Compute LW Jacobians + call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & + lw_optical_props_clrsky, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_allsky, & ! OUT - Flxues + n_gauss_angles = nGauss_angles, & ! IN - Number of angles in Gaussian quadrature + flux_up_Jac = fluxlwUP_jac)) ! OUT - surface temperature flux (upward) Jacobian (W/m2/K) + else + call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & + lw_optical_props_clrsky, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + sources, & ! IN - source function + sfc_emiss_byband, & ! IN - surface emissivity in each LW band + flux_allsky, & ! OUT - Flxues + n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature + end if + endif + + ! Store fluxes + fluxlwUP_allsky(iCol:iCol2,:) = sum(flux_allsky%bnd_flux_up, dim=3) + fluxlwDOWN_allsky(iCol:iCol2,:) = sum(flux_allsky%bnd_flux_dn, dim=3) + + ! Save fluxes for coupling + fluxlwUP_radtime(iCol:iCol2,:) = fluxlwUP_allsky(iCol:iCol2,:) + fluxlwDOWN_radtime(iCol:iCol2,:) = fluxlwDOWN_allsky(iCol:iCol2,:) + + enddo + + end subroutine rrtmgp_lw_main_run +!> @} +end module rrtmgp_lw_main diff --git a/physics/rrtmgp_lw_main.meta b/physics/rrtmgp_lw_main.meta new file mode 100644 index 000000000..fd96eb14b --- /dev/null +++ b/physics/rrtmgp_lw_main.meta @@ -0,0 +1,641 @@ +[ccpp-table-properties] + name = rrtmgp_lw_main + type = scheme + dependencies = machine.F,radiation_tools.F90,GFS_rrtmgp_pre.F90,rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90 + dependencies = rte-rrtmgp/rte/mo_rte_kind.F90,rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90,rte-rrtmgp/rte/mo_optical_props.F90 + dependencies = rte-rrtmgp/rte/mo_source_functions.F90,rte-rrtmgp/rte/mo_rte_lw.F90,rte-rrtmgp/rte/mo_fluxes.F90 + dependencies = rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90, rte-rrtmgp/rte/kernels/mo_rte_solver_kernels.F90 + dependencies = mersenne_twister.f,rrtmgp_sampling.F90,rte-rrtmgp/extensions/mo_fluxes_byband.F90 + dependencies = rrtmgp_lw_gas_optics.F90, rrtmgp_lw_cloud_optics.F90 + +######################################################################## +[ccpp-arg-table] + name = rrtmgp_lw_main_init + type = scheme +[rrtmgp_root_dir] + standard_name = directory_for_rte_rrtmgp_source_code + long_name = directory for rte+rrtmgp source code + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[rrtmgp_lw_file_gas] + standard_name = filename_of_rrtmgp_longwave_k_distribution + long_name = file containing RRTMGP LW k-distribution + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[rrtmgp_lw_file_clouds] + standard_name = filename_of_rrtmgp_longwave_cloud_optics_coefficients + long_name = file containing coefficients for RRTMGP LW cloud optics + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[doGP_cldoptics_PADE] + standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE + long_name = logical flag to control cloud optics scheme. + units = flag + dimensions = () + type = logical + intent = in +[doGP_cldoptics_LUT] + standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT + long_name = logical flag to control cloud optics scheme. + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_cnv] + standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP + long_name = logical flag to control sgs convective cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_pbl] + standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP + long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[nrghice] + standard_name = number_of_ice_roughness_categories + long_name = number of ice-roughness categories in RRTMGP calculation + units = count + dimensions = () + type = integer + intent = inout +[mpirank] + standard_name = mpi_rank + long_name = current MPI rank + units = index + dimensions = () + type = integer + intent = in +[mpiroot] + standard_name = mpi_root + long_name = master MPI rank + units = index + dimensions = () + type = integer + intent = in +[mpicomm] + standard_name = mpi_communicator + long_name = MPI communicator + units = index + dimensions = () + type = integer + intent = in +[rrtmgp_phys_blksz] + standard_name = number_of_columns_per_RRTMGP_LW_block + long_name = number of columns to process at a time by RRTMGP LW scheme + units = count + dimensions = () + type = integer + intent = in +[nLay] + standard_name = vertical_layer_dimension + long_name = number of vertical levels + units = count + dimensions = () + type = integer + intent = in +[active_gases_array] + standard_name = list_of_active_gases_used_by_RRTMGP + long_name = list of active gases used by RRTMGP + units = none + dimensions = (number_of_active_gases_used_by_RRTMGP) + type = character + kind = len=* + intent = in +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out + +######################################################################## +[ccpp-arg-table] + name = rrtmgp_lw_main_run + type = scheme +[doLWrad] + standard_name = flag_for_calling_longwave_radiation + long_name = logical flags for lw radiation calls + units = flag + dimensions = () + type = logical + intent = in +[doLWclrsky] + standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep_assuming_clear_sky + long_name = flag to output lw heating rate (Radtend%lwhc) + units = flag + dimensions = () + type = logical + intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiaiton + units = flag + dimensions = () + type = logical + intent = in +[use_LW_jacobian] + standard_name = flag_to_calc_RRTMGP_LW_jacobian + long_name = logical flag to control RRTMGP LW calculation + units = flag + dimensions = () + type = logical + intent = in +[doGP_lwscat] + standard_name = flag_to_include_longwave_scattering_in_cloud_optics + long_name = logical flag to control the addition of LW scattering in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_cnv] + standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP + long_name = logical flag to control sgs convective cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_pbl] + standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP + long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[ncol] + standard_name = horizontal_loop_extent + long_name = horizontal dimension + units = count + dimensions = () + type = integer + intent = in +[rrtmgp_phys_blksz] + standard_name = number_of_columns_per_RRTMGP_LW_block + long_name = number of columns to process at a time by RRTMGP LW scheme + units = count + dimensions = () + type = integer + intent = in +[nLay] + standard_name = vertical_layer_dimension + long_name = number of vertical levels + units = count + dimensions = () + type = integer + intent = in +[nGauss_angles] + standard_name = number_of_gaussian_quadrature_angles_for_radiation + long_name = Number of angles used in Gaussian quadrature + units = count + dimensions = () + type = integer + intent = in +[nGases] + standard_name = number_of_active_gases_used_by_RRTMGP + long_name = number of gases available used by RRTMGP (Model%nGases) + units = count + dimensions = () + type = integer + intent = in +[isubc_lw] + standard_name = flag_for_lw_clouds_sub_grid_approximation + long_name = flag for lw clouds sub-grid approximation + units = flag + dimensions = () + type = integer + intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = max-random overlap clouds + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_convcld] + standard_name = flag_for_convective_cloud_overlap_method_for_radiation + long_name = flag for convective cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[icseed_lw] + standard_name = random_number_seed_for_mcica_longwave + long_name = seed for random number generation for longwave radiation + units = none + dimensions = (horizontal_loop_extent) + type = integer + intent = in +[semis] + standard_name = surface_longwave_emissivity + long_name = surface lw emissivity in fraction + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[tsfg] + standard_name = surface_ground_temperature_for_radiation + long_name = surface ground temperature for radiation + units = K + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[p_lay] + standard_name = air_pressure_at_layer_for_RRTMGP + long_name = air pressure at vertical layer for radiation calculation + units = Pa + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[p_lev] + standard_name = air_pressure_at_interface_for_RRTMGP + long_name = air pressure at vertical interface for radiation calculation + units = Pa + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[t_lay] + standard_name = air_temperature_at_layer_for_RRTMGP + long_name = air temperature at vertical layer for radiation calculation + units = K + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[t_lev] + standard_name = air_temperature_at_interface_for_RRTMGP + long_name = air temperature at vertical interface for radiation calculation + units = K + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[vmr_o2] + standard_name = volume_mixing_ratio_for_o2 + long_name = molar mixing ratio of o2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_h2o] + standard_name = volume_mixing_ratio_for_h2o + long_name = molar mixing ratio of h2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_o3] + standard_name = volume_mixing_ratio_for_o3 + long_name = molar mixing ratio of o3 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_ch4] + standard_name = volume_mixing_ratio_for_ch4 + long_name = molar mixing ratio of ch4 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_n2o] + standard_name = volume_mixing_ratio_for_n2o + long_name = molar mixing ratio of n2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_co2] + standard_name = volume_mixing_ratio_for_co2 + long_name = molar mixing ratio of co2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_frac] + standard_name = total_cloud_fraction + long_name = layer total cloud fraction + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_lwp] + standard_name = cloud_liquid_water_path + long_name = layer cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_reliq] + standard_name = mean_effective_radius_for_liquid_cloud + long_name = mean effective radius for liquid cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_iwp] + standard_name = cloud_ice_water_path + long_name = layer cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_reice] + standard_name = mean_effective_radius_for_ice_cloud + long_name = mean effective radius for ice cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_swp] + standard_name = cloud_snow_water_path + long_name = layer cloud snow water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_resnow] + standard_name = mean_effective_radius_for_snow_flake + long_name = mean effective radius for snow cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_rwp] + standard_name = cloud_rain_water_path + long_name = layer cloud rain water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_rerain] + standard_name = mean_effective_radius_for_rain_drop + long_name = mean effective radius for rain cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[precip_frac] + standard_name = precipitation_fraction_by_layer + long_name = precipitation fraction in each layer + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_lwp] + standard_name = convective_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_iwp] + standard_name = convective_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reliq] + standard_name = mean_effective_radius_for_liquid_convective_cloud + long_name = mean effective radius for liquid convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reice] + standard_name = mean_effective_radius_for_ice_convective_cloud + long_name = mean effective radius for ice convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_lwp] + standard_name = MYNN_SGS_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_iwp] + standard_name = MYNN_SGS_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reliq] + standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud + long_name = mean effective radius for liquid MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reice] + standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud + long_name = mean effective radius for ice MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cloud_overlap_param] + standard_name = cloud_overlap_param + long_name = cloud overlap parameter + units = km + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[active_gases_array] + standard_name = list_of_active_gases_used_by_RRTMGP + long_name = list of active gases used by RRTMGP + units = none + dimensions = (number_of_active_gases_used_by_RRTMGP) + type = character + kind = len=* + intent = in +[aerlw_tau] + standard_name = aerosol_optical_depth_for_longwave_bands_01_16 + long_name = aerosol optical depth for longwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = in +[aerlw_ssa] + standard_name = aerosol_single_scattering_albedo_for_longwave_bands_01_16 + long_name = aerosol single scattering albedo for longwave bands 01-16 + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = in +[aerlw_g] + standard_name = aerosol_asymmetry_parameter_for_longwave_bands_01_16 + long_name = aerosol asymmetry parameter for longwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_longwave_radiation) + type = real + kind = kind_phys + intent = in +[fluxlwUP_radtime] + standard_name = RRTMGP_lw_flux_profile_upward_allsky_on_radiation_timestep + long_name = RRTMGP upward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwDOWN_radtime] + standard_name = RRTMGP_lw_flux_profile_downward_allsky_on_radiation_timestep + long_name = RRTMGP downward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwUP_allsky] + standard_name = RRTMGP_lw_flux_profile_upward_allsky + long_name = RRTMGP upward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwDOWN_allsky] + standard_name = RRTMGP_lw_flux_profile_downward_allsky + long_name = RRTMGP downward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwUP_clrsky] + standard_name = RRTMGP_lw_flux_profile_upward_clrsky + long_name = RRTMGP upward longwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwDOWN_clrsky] + standard_name = RRTMGP_lw_flux_profile_downward_clrsky + long_name = RRTMGP downward longwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxlwUP_jac] + standard_name = RRTMGP_jacobian_of_lw_flux_upward + long_name = RRTMGP Jacobian upward longwave flux profile + units = W m-2 K-1 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out \ No newline at end of file diff --git a/physics/rrtmgp_lw_pre.F90 b/physics/rrtmgp_lw_pre.F90 deleted file mode 100644 index 1501ca319..000000000 --- a/physics/rrtmgp_lw_pre.F90 +++ /dev/null @@ -1,61 +0,0 @@ -!> \file rrtmgp_lw_pre.F90 -!! -!> \defgroup rrtmgp_lw_pre rrtmgp_lw_pre.F90 -!! -!! \brief RRTMGP Longwave pre-processing routine. -!! -module rrtmgp_lw_pre - use machine, only: & - kind_phys ! Working type - use mo_gas_optics_rrtmgp, only: & - ty_gas_optics_rrtmgp - use rrtmgp_lw_gas_optics, only: lw_gas_props - - implicit none - - public rrtmgp_lw_pre_run - -contains - -!>\defgroup rrtmgp_lw_pre_mode GFS RRTMGP-LW Pre Module -!> \section arg_table_rrtmgp_lw_pre_run -!! \htmlinclude rrtmgp_lw_pre_run.html -!! -!> \ingroup rrtmgp_lw_pre -!! -!! \brief -!! -!! \section rrtmgp_lw_pre_run - subroutine rrtmgp_lw_pre_run (doLWrad, semis, sfc_emiss_byband, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doLWrad - real(kind_phys), dimension(:), intent(in) :: & - semis - - ! Outputs - real(kind_phys), dimension(:,:), intent(inout) :: & - sfc_emiss_byband ! Surface emissivity in each band - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - - ! Local variables - integer :: iBand - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doLWrad) return - - ! Assign same emissivity to all bands - do iBand=1,lw_gas_props%get_nband() - sfc_emiss_byband(iBand,:) = semis - enddo - - end subroutine rrtmgp_lw_pre_run - -end module rrtmgp_lw_pre diff --git a/physics/rrtmgp_lw_pre.meta b/physics/rrtmgp_lw_pre.meta deleted file mode 100644 index aa2a06a0f..000000000 --- a/physics/rrtmgp_lw_pre.meta +++ /dev/null @@ -1,47 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_pre - type = scheme - dependencies = iounitdef.f,machine.F - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_pre_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[semis] - standard_name = surface_longwave_emissivity - long_name = surface lw emissivity in fraction - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_emiss_byband] - standard_name = surface_emissivity_in_each_RRTMGP_LW_band - long_name = surface emissivity in each RRTMGP LW band - units = none - dimensions = (number_of_longwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_lw_rte.F90 b/physics/rrtmgp_lw_rte.F90 deleted file mode 100644 index 9109a5780..000000000 --- a/physics/rrtmgp_lw_rte.F90 +++ /dev/null @@ -1,208 +0,0 @@ -!> \file rrtmgp_lw_rte.F90 -!! -!> \defgroup rrtmgp_lw_rte rrtmgp_lw_rte.F90 -!! -!! \brief This module contains the main rte longwave driver. -!! -module rrtmgp_lw_rte - use machine, only: kind_phys - use mo_optical_props, only: ty_optical_props_1scl, ty_optical_props_2str - use mo_rte_lw, only: rte_lw - use mo_fluxes_byband, only: ty_fluxes_byband - use mo_source_functions, only: ty_source_func_lw - use radiation_tools, only: check_error_msg - use rrtmgp_lw_gas_optics, only: lw_gas_props - implicit none - - public rrtmgp_lw_rte_run -contains - -!>\defgroup rrtmgp_lw_rte_mod GFS RRTMGP-LW RTE Module -!> \section arg_table_rrtmgp_lw_rte_run -!! \htmlinclude rrtmgp_lw_rte_run.html -!! -!> \ingroup rrtmgp_lw_rte -!! -!! \brief This routine takes all of the longwave optical properties ,ty_optical_props_1scl, -!! and computes the longwave radiative fluxes for cloudy and clear-sky conditions. -!! -!! \section rrtmgp_lw_rte_run - subroutine rrtmgp_lw_rte_run(doLWrad, doLWclrsky, use_LW_jacobian, doGP_lwscat, nCol, & - nLev, top_at_1, doGP_sgs_cnv, doGP_sgs_mynn, sfc_emiss_byband, sources, & - lw_optical_props_clrsky, lw_optical_props_clouds, lw_optical_props_precipByBand, & - lw_optical_props_cnvcloudsByBand, lw_optical_props_MYNNcloudsByBand, & - lw_optical_props_aerosol, nGauss_angles, fluxlwUP_allsky, fluxlwDOWN_allsky, & - fluxlwUP_clrsky, fluxlwDOWN_clrsky, fluxlwUP_jac, fluxlwUP_radtime, & - fluxlwDOWN_radtime, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - top_at_1, & ! Vertical ordering flag - doLWrad, & ! Logical flag for longwave radiation call - doLWclrsky, & ! Compute clear-sky fluxes for clear-sky heating-rate? - use_LW_jacobian, & ! Compute Jacobian of LW to update radiative fluxes between radiation calls? - doGP_sgs_mynn, & ! Flag for sgs MYNN-EDMF PBL cloud scheme - doGP_sgs_cnv, & ! Flagg for sgs convective cloud scheme - doGP_lwscat ! Include scattering in LW cloud-optics? - integer, intent(in) :: & - nCol, & ! Number of horizontal gridpoints - nLev, & ! Number of vertical levels - nGauss_angles ! Number of angles used in Gaussian quadrature - real(kind_phys), dimension(:,:), intent(in) :: & - sfc_emiss_byband ! Surface emissivity in each band - type(ty_source_func_lw),intent(in) :: & - sources ! RRTMGP DDT: longwave source functions - type(ty_optical_props_1scl),intent(inout) :: & - lw_optical_props_aerosol, &! RRTMGP DDT: longwave aerosol optical properties - lw_optical_props_clrsky ! RRTMGP DDT: longwave clear-sky optical properties - type(ty_optical_props_2str),intent(inout) :: & - lw_optical_props_clouds, & ! RRTMGP DDT: longwave cloud optical properties - lw_optical_props_precipByBand, & ! RRTMGP DDT: longwave precipitation optical properties - lw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: longwave convective cloud optical properties - lw_optical_props_MYNNcloudsByBand ! RRTMGP DDT: longwave MYNN-EDMF PBL cloud optical properties - ! Outputs - real(kind_phys), dimension(:,:), intent(inout) :: & - fluxlwUP_jac, & ! Jacobian of upwelling LW surface radiation (W/m2/K) - fluxlwUP_allsky, & ! All-sky flux (W/m2) - fluxlwDOWN_allsky, & ! All-sky flux (W/m2) - fluxlwUP_clrsky, & ! Clear-sky flux (W/m2) - fluxlwDOWN_clrsky, & ! All-sky flux (W/m2) - fluxlwUP_radtime, & ! Copy of fluxes (Used for coupling) - fluxlwDOWN_radtime - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - - ! Local variables - type(ty_fluxes_byband) :: & - flux_allsky, flux_clrsky - real(kind_phys), dimension(ncol,nLev+1,lw_gas_props%get_nband()),target :: & - fluxLW_up_allsky, fluxLW_up_clrsky, fluxLW_dn_allsky, fluxLW_dn_clrsky - real(kind_phys), dimension(nCol,lw_gas_props%get_ngpt()) :: lw_Ds - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doLWrad) return - - ! Initialize RRTMGP DDT containing 2D(3D) fluxes - flux_allsky%bnd_flux_up => fluxLW_up_allsky - flux_allsky%bnd_flux_dn => fluxLW_dn_allsky - flux_clrsky%bnd_flux_up => fluxLW_up_clrsky - flux_clrsky%bnd_flux_dn => fluxLW_dn_clrsky - - ! - ! Compute clear-sky fluxes (if requested) - ! - ! Add aerosol optics to gas optics - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_aerosol%increment(lw_optical_props_clrsky)) - - ! Call RTE solver - if (doLWclrsky) then - call check_error_msg('rrtmgp_lw_rte_run_opt_angle',lw_gas_props%compute_optimal_angles(lw_optical_props_clrsky,lw_Ds)) - if (nGauss_angles .gt. 1) then - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_clrsky, & ! OUT - Fluxes - n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature - else - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_clrsky, & ! OUT - Fluxes - lw_Ds = lw_Ds)) - endif - - ! Store fluxes - fluxlwUP_clrsky = sum(flux_clrsky%bnd_flux_up,dim=3) - fluxlwDOWN_clrsky = sum(flux_clrsky%bnd_flux_dn,dim=3) - else - fluxlwUP_clrsky = 0.0 - fluxlwDOWN_clrsky = 0.0 - endif - - ! - ! All-sky fluxes (clear-sky + clouds + precipitation) - ! - - ! Include convective cloud? - if (doGP_sgs_cnv) then - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_cnvcloudsByBand%increment(lw_optical_props_clrsky)) - endif - - ! Include MYNN-EDMF PBL clouds? - if (doGP_sgs_mynn) then - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_MYNNcloudsByBand%increment(lw_optical_props_clrsky)) - endif - - ! Add in precipitation - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_precipByBand%increment(lw_optical_props_clouds)) - - ! Include LW cloud-scattering? - if (doGP_lwscat) then - ! Add clear-sky optics to cloud-optics (2-stream) - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_clrsky%increment(lw_optical_props_clouds)) - - if (use_LW_jacobian) then - ! Compute LW Jacobians - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clouds, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_allsky, & ! OUT - Flxues - n_gauss_angles = nGauss_angles, & ! IN - Number of angles in Gaussian quadrature - flux_up_Jac = fluxlwUP_jac)) ! OUT - surface temperature flux (upward) Jacobian (W/m2/K) - else - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clouds, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_allsky, & ! OUT - Flxues - n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature - end if - ! No scattering in LW clouds. - else - ! Add cloud optics to clear-sky optics (scalar) - call check_error_msg('rrtmgp_lw_rte_run',lw_optical_props_clouds%increment(lw_optical_props_clrsky)) - - if (use_LW_jacobian) then - ! Compute LW Jacobians - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_allsky, & ! OUT - Flxues - n_gauss_angles = nGauss_angles, & ! IN - Number of angles in Gaussian quadrature - flux_up_Jac = fluxlwUP_jac)) ! OUT - surface temperature flux (upward) Jacobian (W/m2/K) - else - call check_error_msg('rrtmgp_lw_rte_run',rte_lw( & - lw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - sources, & ! IN - source function - sfc_emiss_byband, & ! IN - surface emissivity in each LW band - flux_allsky, & ! OUT - Flxues - n_gauss_angles = nGauss_angles)) ! IN - Number of angles in Gaussian quadrature - end if - endif - - ! Store fluxes - fluxlwUP_allsky = sum(flux_allsky%bnd_flux_up,dim=3) - fluxlwDOWN_allsky = sum(flux_allsky%bnd_flux_dn,dim=3) - - ! Save fluxes for coupling - fluxlwUP_radtime = fluxlwUP_allsky - fluxlwDOWN_radtime = fluxlwDOWN_allsky - - end subroutine rrtmgp_lw_rte_run - -end module rrtmgp_lw_rte diff --git a/physics/rrtmgp_lw_rte.meta b/physics/rrtmgp_lw_rte.meta deleted file mode 100644 index 0ad0754b5..000000000 --- a/physics/rrtmgp_lw_rte.meta +++ /dev/null @@ -1,208 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_lw_rte - type = scheme - dependencies = machine.F,rte-rrtmgp/rte/mo_rte_lw.F90,rte-rrtmgp/rte/mo_fluxes.F90,rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90,radiation_tools.F90 - dependencies = rte-rrtmgp/rte/kernels/mo_rte_solver_kernels.F90,rte-rrtmgp/extensions/mo_fluxes_byband.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_lw_rte_run - type = scheme -[doLWrad] - standard_name = flag_for_calling_longwave_radiation - long_name = logical flags for lw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[doLWclrsky] - standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep_assuming_clear_sky - long_name = flag to output lw heating rate (Radtend%lwhc) - units = flag - dimensions = () - type = logical - intent = in -[use_LW_jacobian] - standard_name = flag_to_calc_RRTMGP_LW_jacobian - long_name = logical flag to control RRTMGP LW calculation - units = flag - dimensions = () - type = logical - intent = in -[doGP_lwscat] - standard_name = flag_to_include_longwave_scattering_in_cloud_optics - long_name = logical flag to control the addition of LW scattering in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[doGP_sgs_cnv] - standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP - long_name = logical flag to control sgs convective cloud in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[doGP_sgs_mynn] - standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP - long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[nGauss_angles] - standard_name = number_of_gaussian_quadrature_angles_for_radiation - long_name = Number of angles used in Gaussian quadrature - units = count - dimensions = () - type = integer - intent = in -[top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[sfc_emiss_byband] - standard_name = surface_emissivity_in_each_RRTMGP_LW_band - long_name = surface emissivity in each RRTMGP LW band - units = none - dimensions = (number_of_longwave_bands,horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[lw_optical_props_clrsky] - standard_name = longwave_optical_properties_for_clear_sky - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_1scl - intent = inout -[lw_optical_props_clouds] - standard_name = longwave_optical_properties_for_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_precipByBand] - standard_name = longwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_cnvcloudsByBand] - standard_name = longwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_MYNNcloudsByBand] - standard_name = longwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[lw_optical_props_aerosol] - standard_name = longwave_optical_properties_for_aerosols - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_1scl - intent = inout -[sources] - standard_name = longwave_source_function - long_name = Fortran DDT containing RRTMGP source functions - units = DDT - dimensions = () - type = ty_source_func_lw - intent = in -[fluxlwUP_radtime] - standard_name = RRTMGP_lw_flux_profile_upward_allsky_on_radiation_timestep - long_name = RRTMGP upward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwDOWN_radtime] - standard_name = RRTMGP_lw_flux_profile_downward_allsky_on_radiation_timestep - long_name = RRTMGP downward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwUP_allsky] - standard_name = RRTMGP_lw_flux_profile_upward_allsky - long_name = RRTMGP upward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwDOWN_allsky] - standard_name = RRTMGP_lw_flux_profile_downward_allsky - long_name = RRTMGP downward longwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwUP_clrsky] - standard_name = RRTMGP_lw_flux_profile_upward_clrsky - long_name = RRTMGP upward longwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwDOWN_clrsky] - standard_name = RRTMGP_lw_flux_profile_downward_clrsky - long_name = RRTMGP downward longwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxlwUP_jac] - standard_name = RRTMGP_jacobian_of_lw_flux_upward - long_name = RRTMGP Jacobian upward longwave flux profile - units = W m-2 K-1 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_sw_cloud_optics.F90 b/physics/rrtmgp_sw_cloud_optics.F90 index 3aab115cd..4293a7be6 100644 --- a/physics/rrtmgp_sw_cloud_optics.F90 +++ b/physics/rrtmgp_sw_cloud_optics.F90 @@ -1,18 +1,7 @@ -!> \file rrtmgp_sw_cloud_optics.F90 -!! -!> \defgroup rrtmgp_sw_cloud_optics rrtmgp_sw_cloud_optics.F90 -!! -!! \brief This module contains two routines: The first initializes data and functions -!! needed to compute the shortwave cloud radiative properteis in RRTMGP. The second routine -!! is a ccpp scheme within the "radiation loop", where the shortwave optical prperties -!! (optical-depth, single-scattering albedo, asymmetry parameter) are computed for ALL -!! cloud types visible to RRTMGP. module rrtmgp_sw_cloud_optics use machine, only: kind_phys use mo_rte_kind, only: wl use mo_cloud_optics, only: ty_cloud_optics - use mo_optical_props, only: ty_optical_props_2str - use mo_rrtmg_sw_cloud_optics, only: rrtmg_sw_cloud_optics use rrtmgp_sw_gas_optics, only: sw_gas_props use radiation_tools, only: check_error_msg use netcdf @@ -59,52 +48,41 @@ module rrtmgp_sw_cloud_optics pade_exticeSW, & ! PADE coefficients for shortwave ice extinction pade_ssaiceSW, & ! PADE coefficients for shortwave ice single scattering albedo pade_asyiceSW ! PADE coefficients for shortwave ice asymmetry parameter + real(kind_phys) :: & + radliq_lwrSW, & ! Liquid particle size lower bound for LUT interpolation + radliq_uprSW, & ! Liquid particle size upper bound for LUT interpolation + radice_lwrSW, & ! Ice particle size upper bound for LUT interpolation + radice_uprSW ! Ice particle size lower bound for LUT interpolation - ! Parameters used for rain and snow(+groupel) RRTMGP cloud-optics + ! Parameters used for rain and snow(+groupel) RRTMGP cloud-optics. *NOTE* Same as in RRTMG + ! Need to document these magic numbers below. real(kind_phys),parameter :: & - a0r = 3.07e-3, & ! - a0s = 0.0, & ! - a1s = 1.5 ! + a0r = 3.07e-3, & ! + a0s = 0.0, & ! + a1s = 1.5 ! real(kind_phys),dimension(:),allocatable :: b0r,b0s,b1s,c0r,c0s - real(kind_phys) :: & - radliq_lwrSW, & ! Liquid particle size lower bound for LUT interpolation - radliq_uprSW, & ! Liquid particle size upper bound for LUT interpolation - radice_lwrSW, & ! Ice particle size upper bound for LUT interpolation - radice_uprSW ! Ice particle size lower bound for LUT interpolation contains - -!>\defgroup rrtmgp_sw_cloud_optics_mod GFS RRTMGP-SW Cloud Optics Module -!> \section arg_table_rrtmgp_sw_cloud_optics_init -!! \htmlinclude rrtmgp_lw_cloud_optics.html -!! -!> \ingroup rrtmgp_sw_cloud_optics -!! -!! RRTMGP relies heavily on derived-data-types, which contain type-bound procedures -!! that are referenced frequently throughout the RRTMGP shortwave scheme. The data needed -!! to compute the shortwave cloud optical properties are initialized here and loaded into -!! the RRTMGP DDT, ty_cloud_optics. -!! -!! \section rrtmgp_sw_cloud_optics_init ! ###################################################################################### - subroutine rrtmgp_sw_cloud_optics_init(doG_cldoptics, doGP_cldoptics_PADE, & - doGP_cldoptics_LUT, nrghice, rrtmgp_root_dir, rrtmgp_sw_file_clouds, mpicomm, & - mpirank, mpiroot, errmsg, errflg) + ! SUBROUTINE sw_cloud_optics_init + ! ###################################################################################### + subroutine rrtmgp_sw_cloud_optics_init( rrtmgp_root_dir, rrtmgp_sw_file_clouds, & + doGP_cldoptics_PADE, doGP_cldoptics_LUT, nrghice, mpicomm, mpirank, mpiroot, & + errmsg, errflg) ! Inputs + character(len=128),intent(in) :: & + rrtmgp_root_dir, & ! RTE-RRTMGP root directory + rrtmgp_sw_file_clouds ! RRTMGP file containing cloud-optic data logical, intent(in) :: & - doG_cldoptics, & ! Use legacy RRTMG cloud-optics? - doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? - doGP_cldoptics_LUT ! Use RRTMGP cloud-optics: LUTs? + doGP_cldoptics_PADE,& ! Use RRTMGP cloud-optics: PADE approximation? + doGP_cldoptics_LUT ! Use RRTMGP cloud-optics: LUTs? integer, intent(inout) :: & nrghice ! Number of ice-roughness categories integer, intent(in) :: & mpicomm, & ! MPI communicator mpirank, & ! Current MPI rank mpiroot ! Master MPI rank - character(len=128),intent(in) :: & - rrtmgp_root_dir, & ! RTE-RRTMGP root directory - rrtmgp_sw_file_clouds ! RRTMGP file containing coefficients used to compute clouds optical properties ! Outputs character(len=*), intent(out) :: & @@ -120,8 +98,6 @@ subroutine rrtmgp_sw_cloud_optics_init(doG_cldoptics, doGP_cldoptics_PADE, errmsg = '' errflg = 0 - if (doG_cldoptics) return - ! Filenames are set in the physics_nml sw_cloud_props_file = trim(rrtmgp_root_dir)//trim(rrtmgp_sw_file_clouds) @@ -180,7 +156,7 @@ subroutine rrtmgp_sw_cloud_optics_init(doG_cldoptics, doGP_cldoptics_PADE, call mpi_bcast(nPairsSW, 1, MPI_INTEGER, mpiroot, mpicomm, mpierr) #endif - ! Has the number of ice-roughnesses provided from the namelist? + ! Has the number of ice-roughnes categories been provided from the namelist? ! If so, override nrghice from cloud-optics file if (nrghice .ne. 0) nrghice_fromfileSW = nrghice #ifdef MPI @@ -404,182 +380,4 @@ subroutine rrtmgp_sw_cloud_optics_init(doG_cldoptics, doGP_cldoptics_PADE, 0.970, 0.970, 0.970, 0.700, 0.700, 0.700, 0.700/) end subroutine rrtmgp_sw_cloud_optics_init - -!> \section arg_table_rrtmgp_sw_cloud_optics_run -!! \htmlinclude rrtmgp_sw_cloud_optics.html -!! -!> \ingroup rrtmgp_sw_cloud_optics -!! -!! Compute shortwave optical prperties (optical-depth, single-scattering albedo, -!! asymmetry parameter) for ALL cloud types visible to RRTMGP. -!! -!! \section rrtmgp_sw_gas_optics_run - ! ###################################################################################### - subroutine rrtmgp_sw_cloud_optics_run(doSWrad, doG_cldoptics, icliq_sw, icice_sw, & - doGP_cldoptics_PADE, doGP_cldoptics_LUT, do_mynnedmf, imfdeepcnv, imfdeepcnv_gf, & - imfdeepcnv_samf, nCol, nLev, nDay, nbndsGPsw, idxday, cld_frac, cld_lwp, cld_reliq, & - cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, precip_frac, & - cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_pbl_lwp, cld_pbl_reliq, & - cld_pbl_iwp, cld_pbl_reice, sw_optical_props_cloudsByBand, & - sw_optical_props_cnvcloudsByBand, sw_optical_props_precipByBand, & - sw_optical_props_MYNNcloudsByBand, cldtausw, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doSWrad, & ! Logical flag for shortwave radiation call - doG_cldoptics, & ! Use legacy RRTMG cloud-optics? - doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? - doGP_cldoptics_LUT, & ! Use RRTMGP cloud-optics: LUTs? - do_mynnedmf ! - integer, intent(in) :: & - nbndsGPsw, & ! Number of shortwave bands - nCol, & ! Number of horizontal gridpoints - nLev, & ! Number of vertical levels - nday, & ! Number of daylit points. - icliq_sw, & ! Choice of treatment of liquid cloud optical properties (RRTMG legacy) - icice_sw, & ! Choice of treatment of ice cloud optical properties (RRTMG legacy) - imfdeepcnv, & ! - imfdeepcnv_gf, & ! - imfdeepcnv_samf ! - integer,intent(in),dimension(:) :: & - idxday ! Indices for daylit points. - real(kind_phys), dimension(:,:),intent(in) :: & - cld_frac, & ! Total cloud fraction by layer - cld_lwp, & ! Cloud liquid water path - cld_reliq, & ! Cloud liquid effective radius - cld_iwp, & ! Cloud ice water path - cld_reice, & ! Cloud ice effective radius - cld_swp, & ! Cloud snow water path - cld_resnow, & ! Cloud snow effective radius - cld_rwp, & ! Cloud rain water path - cld_rerain, & ! Cloud rain effective radius - precip_frac, & ! Precipitation fraction by layer - cld_cnv_lwp, & ! Water path for convective liquid cloud-particles (microns) - cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles (microns) - cld_cnv_iwp, & ! Water path for convective ice cloud-particles (microns) - cld_cnv_reice, & ! Effective radius for convective ice cloud-particles (microns) - cld_pbl_lwp, & ! Water path for SGS PBL liquid cloud-particles - cld_pbl_reliq, & ! Effective radius for SGS PBL liquid cloud-particles - cld_pbl_iwp, & ! Water path for SGS PBL ice cloud-particles - cld_pbl_reice ! Effective radius for SGS PBL ice cloud-particles - ! Outputs - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - type(ty_optical_props_2str),intent(out) :: & - sw_optical_props_cloudsByBand, & ! RRTMGP DDT: Shortwave optical properties in each band (clouds) - sw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: Shortwave optical properties in each band (convective cloud) - sw_optical_props_MYNNcloudsByBand,& ! RRTMGP DDT: Shortwave optical properties in each band (MYNN PBL cloud) - sw_optical_props_precipByBand ! RRTMGP DDT: Shortwave optical properties in each band (cloud precipitation) - real(kind_phys), dimension(:,:), intent(out) :: & - cldtausw ! Approx 10.mu band layer cloud optical depth - - ! Local variables - integer :: iDay, iLay, iBand - real(kind_phys) :: tau_rain, tau_snow, ssa_rain, ssa_snow, asy_rain, asy_snow, & - tau_prec, asy_prec, ssa_prec, asyw, ssaw, za1, za2 - real(kind_phys), dimension(nday,nLev,nbndsGPsw) :: & - tau_cld, ssa_cld, asy_cld, tau_precip, ssa_precip, asy_precip - type(ty_optical_props_2str) :: sw_optical_props_cloudsByBand_daylit - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doSWrad) return - - ! Only process sunlit points... - if (nDay .gt. 0) then - - ! Compute cloud/precipitation optics. - if (doGP_cldoptics_PADE .or. doGP_cldoptics_LUT) then - ! i) Cloud-optics. - call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_cloudsByBand',& - sw_optical_props_cloudsByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) - - call check_error_msg('rrtmgp_sw_cloud_optics_run - clouds',sw_cloud_props%cloud_optics(& - cld_lwp(idxday(1:nday),:), & ! IN - Cloud liquid water path - cld_iwp(idxday(1:nday),:), & ! IN - Cloud ice water path - cld_reliq(idxday(1:nday),:), & ! IN - Cloud liquid effective radius - cld_reice(idxday(1:nday),:), & ! IN - Cloud ice effective radius - sw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT: Shortwave optical properties, - ! in each band (tau,ssa,g) - - ! ii) Convective cloud-optics - if (imfdeepcnv == imfdeepcnv_samf .or. imfdeepcnv == imfdeepcnv_gf) then - call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_cnvcloudsByBand',& - sw_optical_props_cnvcloudsByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) - - call check_error_msg('rrtmgp_sw_cloud_optics_run - convective clouds',sw_cloud_props%cloud_optics(& - cld_cnv_lwp(idxday(1:nday),:), & ! IN - Convective cloud liquid water path - cld_cnv_iwp(idxday(1:nday),:), & ! IN - Convective cloud ice water path - cld_cnv_reliq(idxday(1:nday),:), & ! IN - Convective cloud liquid effective radius - cld_cnv_reice(idxday(1:nday),:), & ! IN - Convective cloud ice effective radius - sw_optical_props_cnvcloudsByBand)) ! OUT - RRTMGP DDT: Shortwave optical properties, - ! in each band (tau,ssa,g) - endif - - ! iii) MYNN cloud-optics - if (do_mynnedmf) then - call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_MYNNcloudsByBand',& - sw_optical_props_MYNNcloudsByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) - - call check_error_msg('rrtmgp_sw_MYNNcloud_optics_run - MYNN-EDMF cloud',sw_cloud_props%cloud_optics(& - cld_pbl_lwp(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud liquid water path (g/m2) - cld_pbl_iwp(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud ice water path (g/m2) - cld_pbl_reliq(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud liquid effective radius (microns) - cld_pbl_reice(idxday(1:nday),:), & ! IN - MYNN-EDMF PBL cloud ice effective radius (microns) - sw_optical_props_MYNNcloudsByBand)) ! OUT - RRTMGP DDT containing MYNN-EDMF PBL cloud radiative properties - ! in each band - endif - - ! iv) Cloud precipitation optics: rain and snow(+groupel) - call check_error_msg('rrtmgp_sw_cloud_optics_run - sw_optical_props_precipByBand',& - sw_optical_props_precipByBand%alloc_2str(nday, nLev, sw_cloud_props%get_band_lims_wavenumber())) - sw_optical_props_precipByBand%tau(:,:,:) = 0._kind_phys - sw_optical_props_precipByBand%ssa(:,:,:) = 1._kind_phys - sw_optical_props_precipByBand%g(:,:,:) = 0._kind_phys - - do iDay=1,nDay - do iLay=1,nLev - if (cld_frac(idxday(iDay),iLay) .gt. 1.e-12_kind_phys) then - ! Rain/Snow optical depth (No band dependence) - tau_rain = cld_rwp(idxday(iDay),iLay)*a0r - if (cld_swp(idxday(iDay),iLay) .gt. 0. .and. cld_resnow(idxday(iDay),iLay) .gt. 10._kind_phys) then - tau_snow = cld_swp(idxday(iDay),iLay)*1.09087*(a0s + a1s/(1.0315*cld_resnow(idxday(iDay),iLay))) ! fu's formula - else - tau_snow = 0._kind_phys - endif - - ! Rain/Snow single-scattering albedo and asymmetry (Band dependent) - do iBand=1,nbndsGPsw - ! By species - ssa_rain = tau_rain*(1.-b0r(iBand)) - asy_rain = ssa_rain*c0r(iBand) - ssa_snow = tau_snow*(1.-(b0s(iBand)+b1s(iBand)*1.0315*cld_resnow(idxday(iDay),iLay))) - asy_snow = ssa_snow*c0s(iBand) - ! Combine - tau_prec = max(1.e-12_kind_phys, tau_rain + tau_snow) - ssa_prec = max(1.e-12_kind_phys, ssa_rain + ssa_snow) - asy_prec = max(1.e-12_kind_phys, asy_rain + asy_snow) - asyw = asy_prec/max(1.e-12_kind_phys, ssa_prec) - ssaw = min(1._kind_phys-0.000001, ssa_prec/tau_prec) - za1 = asyw * asyw - za2 = ssaw * za1 - sw_optical_props_precipByBand%tau(iDay,iLay,iBand) = (1._kind_phys - za2) * tau_prec - sw_optical_props_precipByBand%ssa(iDay,iLay,iBand) = (ssaw - za2) / (1._kind_phys - za2) - sw_optical_props_precipByBand%g(iDay,iLay,iBand) = asyw/(1+asyw) - enddo - endif - enddo - enddo - endif - - ! All-sky SW optical depth ~0.55microns (DJS asks: Move to cloud diagnostics?) - cldtausw(idxday(1:nDay),:) = sw_optical_props_cloudsByBand%tau(:,:,11) - endif - - end subroutine rrtmgp_sw_cloud_optics_run - end module rrtmgp_sw_cloud_optics diff --git a/physics/rrtmgp_sw_cloud_optics.meta b/physics/rrtmgp_sw_cloud_optics.meta deleted file mode 100644 index 064b7cf80..000000000 --- a/physics/rrtmgp_sw_cloud_optics.meta +++ /dev/null @@ -1,393 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_sw_cloud_optics - type = scheme - dependencies = machine.F,rrtmg_sw_cloud_optics.F90,radiation_tools.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_sw_cloud_optics_init - type = scheme -[doG_cldoptics] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMG - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_PADE] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_LUT] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[nrghice] - standard_name = number_of_ice_roughness_categories - long_name = number of ice-roughness categories in RRTMGP calculation - units = count - dimensions = () - type = integer - intent = inout -[rrtmgp_root_dir] - standard_name = directory_for_rte_rrtmgp_source_code - long_name = directory for rte+rrtmgp source code - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[rrtmgp_sw_file_clouds] - standard_name = filename_of_rrtmgp_shortwave_cloud_optics_coefficients - long_name = file containing coefficients for RRTMGP SW cloud optics - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[mpirank] - standard_name = mpi_rank - long_name = current MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpiroot] - standard_name = mpi_root - long_name = master MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpicomm] - standard_name = mpi_communicator - long_name = MPI communicator - units = index - dimensions = () - type = integer - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out -######################################################################## -[ccpp-arg-table] - name = rrtmgp_sw_cloud_optics_run - type = scheme -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = logical flags for sw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[doG_cldoptics] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMG - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[icliq_sw] - standard_name = control_for_shortwave_radiation_liquid_clouds - long_name = sw optical property for liquid clouds - units = flag - dimensions = () - type = integer - intent = in -[icice_sw] - standard_name = flag_for_optical_property_for_ice_clouds_for_shortwave_radiation - long_name = sw optical property for ice clouds - units = flag - dimensions = () - type = integer - intent = in -[doGP_cldoptics_PADE] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[doGP_cldoptics_LUT] - standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT - long_name = logical flag to control cloud optics scheme. - units = flag - dimensions = () - type = logical - intent = in -[do_mynnedmf] - standard_name = flag_for_mellor_yamada_nakanishi_niino_pbl_scheme - long_name = flag to activate MYNN-EDMF - units = flag - dimensions = () - type = logical - intent = in -[imfdeepcnv] - standard_name = control_for_deep_convection_scheme - long_name = flag for mass-flux deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_gf] - standard_name = identifier_for_grell_freitas_deep_convection - long_name = flag for Grell-Freitas deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_samf] - standard_name = identifer_for_scale_aware_mass_flux_deep_convection - long_name = flag for SAMF deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_lwp] - standard_name = cloud_liquid_water_path - long_name = layer cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_reliq] - standard_name = mean_effective_radius_for_liquid_cloud - long_name = mean effective radius for liquid cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_iwp] - standard_name = cloud_ice_water_path - long_name = layer cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_reice] - standard_name = mean_effective_radius_for_ice_cloud - long_name = mean effective radius for ice cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_swp] - standard_name = cloud_snow_water_path - long_name = layer cloud snow water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_resnow] - standard_name = mean_effective_radius_for_snow_flake - long_name = mean effective radius for snow cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_rwp] - standard_name = cloud_rain_water_path - long_name = layer cloud rain water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_rerain] - standard_name = mean_effective_radius_for_rain_drop - long_name = mean effective radius for rain cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[precip_frac] - standard_name = precipitation_fraction_by_layer - long_name = precipitation fraction in each layer - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_lwp] - standard_name = convective_cloud_liquid_water_path - long_name = layer convective cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_iwp] - standard_name = convective_cloud_ice_water_path - long_name = layer convective cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_reliq] - standard_name = mean_effective_radius_for_liquid_convective_cloud - long_name = mean effective radius for liquid convective cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_reice] - standard_name = mean_effective_radius_for_ice_convective_cloud - long_name = mean effective radius for ice convective cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_lwp] - standard_name = MYNN_SGS_cloud_liquid_water_path - long_name = layer convective cloud liquid water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_iwp] - standard_name = MYNN_SGS_cloud_ice_water_path - long_name = layer convective cloud ice water path - units = g m-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_reliq] - standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud - long_name = mean effective radius for liquid MYNN_SGS cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_pbl_reice] - standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud - long_name = mean effective radius for ice MYNN_SGS cloud - units = um - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[nbndsGPsw] - standard_name = number_of_shortwave_bands - long_name = number of sw bands used in RRTMGP - units = count - dimensions = () - type = integer - intent = in -[nday] - standard_name = daytime_points_dimension - long_name = daytime points dimension - units = count - dimensions = () - type = integer - intent = in -[idxday] - standard_name = daytime_points - long_name = daytime points - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[sw_optical_props_cloudsByBand] - standard_name = shortwave_optical_properties_for_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[sw_optical_props_cnvcloudsByBand] - standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[sw_optical_props_precipByBand] - standard_name = shortwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[sw_optical_props_MYNNcloudsByBand] - standard_name = shortwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[cldtausw] - standard_name = cloud_optical_depth_layers_at_0p55mu_band - long_name = approx .55mu band layer cloud optical depth - units = none - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_sw_cloud_sampling.F90 b/physics/rrtmgp_sw_cloud_sampling.F90 deleted file mode 100644 index 238ed7d1c..000000000 --- a/physics/rrtmgp_sw_cloud_sampling.F90 +++ /dev/null @@ -1,174 +0,0 @@ -!> \file rrtmgp_sw_cloud_sampling.F90 -!! -!> \defgroup rrtmgp_sw_cloud_sampling rrtmgp_sw_cloud_sampling.F90 -!! -module rrtmgp_sw_cloud_sampling - use machine, only: kind_phys, kind_dbl_prec - use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp - use mo_optical_props, only: ty_optical_props_2str - use rrtmgp_sampling, only: sampled_mask, draw_samples - use mersenne_twister, only: random_setseed, random_number, random_stat - use radiation_tools, only: check_error_msg - use rrtmgp_sw_gas_optics, only: sw_gas_props - use netcdf - - implicit none - -contains - -!>\defgroup rrtmgp_sw_cloud_sampling_mod GFS RRTMGP-SW Cloud Sampling Module -!> @{ -!> \section arg_table_rrtmgp_sw_cloud_sampling_run -!! \htmlinclude rrtmgp_sw_cloud_sampling.html -!! -!> \ingroup rrtmgp_sw_cloud_sampling -!! -!! \brief This routine performs the McICA cloud-sampling and maps the shortwave cloud- -!! optical properties, defined for each spectral band, to each spectral point (g-point). -!! -!! \section rrtmgp_sw_cloud_sampling_run - subroutine rrtmgp_sw_cloud_sampling_run(doSWrad, nCol, nDay, nLev, idxday, iovr, & - iovr_convcld, iovr_max, iovr_maxrand, iovr_rand, iovr_dcorr, iovr_exp, iovr_exprand, & - isubc_sw,icseed_sw, cld_frac, precip_frac, cloud_overlap_param, precip_overlap_param,& - imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, cnv_cloud_overlap_param, cld_cnv_frac, & - sw_optical_props_cnvcloudsByBand, sw_optical_props_cloudsByBand, & - sw_optical_props_precipByBand, sw_optical_props_clouds, sw_optical_props_cnvclouds, & - sw_optical_props_precip, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doSWrad ! Logical flag for shortwave radiation call - integer, intent(in) :: & - nCol, & ! Number of horizontal gridpoints - nDay, & ! Number of daylit points. - nLev, & ! Number of vertical layers - imfdeepcnv, & ! - imfdeepcnv_gf, & ! - imfdeepcnv_samf, & ! - iovr, & ! Choice of cloud-overlap method - iovr_convcld, & ! Choice of convective cloud-overlap method - iovr_max, & ! Flag for maximum cloud overlap method - iovr_maxrand, & ! Flag for maximum-random cloud overlap method - iovr_rand, & ! Flag for random cloud overlap method - iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method - iovr_exp, & ! Flag for exponential cloud overlap method - iovr_exprand, & ! Flag for exponential-random cloud overlap method - isubc_sw - integer,intent(in),dimension(:) :: & - idxday ! Indices for daylit points. - integer,intent(in),dimension(:) :: & - icseed_sw ! auxiliary special cloud related array when module - ! variable isubc_sw=2, it provides permutation seed - ! for each column profile that are used for generating - ! random numbers. when isubc_sw /=2, it will not be used. - real(kind_phys), dimension(:,:),intent(in) :: & - cld_frac, & ! Total cloud fraction by layer - cld_cnv_frac, & ! Convective cloud fraction by layer - precip_frac ! Precipitation fraction by layer - real(kind_phys), dimension(:,:), intent(in) :: & - cloud_overlap_param, & ! Cloud overlap parameter - cnv_cloud_overlap_param, & ! Convective cloud overlap parameter - precip_overlap_param ! Precipitation overlap parameter - type(ty_optical_props_2str),intent(in) :: & - sw_optical_props_cloudsByBand, & ! RRTMGP DDT: Shortwave optical properties in each band (clouds) - sw_optical_props_cnvcloudsByBand,& ! RRTMGP DDT: Shortwave optical properties in each band (convectivecloud) - sw_optical_props_precipByBand ! RRTMGP DDT: Shortwave optical properties in each band (precipitation) - - ! Outputs - character(len=*), intent(out) :: & - errmsg ! Error message - integer, intent(out) :: & - errflg ! Error flag - type(ty_optical_props_2str),intent(out) :: & - sw_optical_props_clouds, & ! RRTMGP DDT: Shortwave optical properties at each spectral point (clouds) - sw_optical_props_cnvclouds, & ! RRTMGP DDT: Shortwave optical properties at each spectral point (convectivecloud) - sw_optical_props_precip ! RRTMGP DDT: Shortwave optical properties at each spectral point (precipitation) - - ! Local variables - integer :: iday,iLay,iGpt - integer,dimension(nday) :: ipseed_sw - type(random_stat) :: rng_stat - real(kind_phys) :: tauloc,asyloc,ssaloc - real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt(),nLev,nday) :: rng3D,rng3D2 - real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt()*nLev) :: rng2D - real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt()) :: rng1D - logical, dimension(nday,nLev,sw_gas_props%get_ngpt()) :: maskMCICA - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doSWrad) return - if (nDay .gt. 0) then - ! ################################################################################# - ! First sample the clouds... - ! ################################################################################# - - ! Allocate space RRTMGP DDTs [nday,nLev,nGpt] - call check_error_msg('rrtmgp_sw_cloud_sampling_run', & - sw_optical_props_clouds%alloc_2str(nday, nLev, sw_gas_props)) - - ! Change random number seed value for each radiation invocation (isubc_sw =1 or 2). - if(isubc_sw == 1) then ! advance prescribed permutation seed - do iday = 1, nday - ipseed_sw(iday) = sw_gas_props%get_ngpt() + iday - enddo - elseif (isubc_sw == 2) then ! use input array of permutaion seeds - do iday = 1, nday - ipseed_sw(iday) = icseed_sw(idxday(iday)) - enddo - endif - - ! Call RNG. Mersennse Twister accepts 1D array, so loop over columns and collapse along G-points - ! and layers. ([nGpts,nLev,nDayumn]-> [nGpts*nLev]*nDayumn) - do iday=1,nday - call random_setseed(ipseed_sw(iday),rng_stat) - ! Use same rng for each layer - if (iovr == iovr_max) then - call random_number(rng1D,rng_stat) - do iLay=1,nLev - rng3D(:,iLay,iday) = rng1D - enddo - else - do iLay=1,nLev - call random_number(rng1D,rng_stat) - rng3D(:,iLay,iday) = rng1D - enddo - endif - enddo - - ! Cloud overlap. - ! Maximum-random, random, or maximum cloud overlap - if (iovr == iovr_maxrand .or. iovr == iovr_max .or. iovr == iovr_rand) then - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(idxday(1:nDay),:), maskMCICA) - endif - ! Decorrelation-length overlap - if (iovr == iovr_dcorr) then - do iday=1,nday - call random_setseed(ipseed_sw(iday),rng_stat) - call random_number(rng2D,rng_stat) - rng3D2(:,:,iday) = reshape(source = rng2D,shape=[sw_gas_props%get_ngpt(),nLev]) - enddo - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(idxday(1:nDay),:), maskMCICA, & - overlap_param = cloud_overlap_param(idxday(1:nDay),1:nLev-1), & - randoms2 = real(rng3D2, kind=kind_phys)) - endif - ! Exponential or exponential-random cloud overlap - if (iovr == iovr_exp .or. iovr == iovr_exprand) then - call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(idxday(1:nDay),:), maskMCICA, & - overlap_param = cloud_overlap_param(idxday(1:nDay),1:nLev-1)) - endif - - ! - ! Sampling. Map band optical depth to each g-point using McICA - ! - call check_error_msg('rrtmgp_sw_cloud_sampling_run_draw_samples', & - draw_samples(maskMCICA, .true., & - sw_optical_props_cloudsByBand, & - sw_optical_props_clouds)) - endif - - end subroutine rrtmgp_sw_cloud_sampling_run - -!> @} -end module rrtmgp_sw_cloud_sampling diff --git a/physics/rrtmgp_sw_cloud_sampling.meta b/physics/rrtmgp_sw_cloud_sampling.meta deleted file mode 100644 index 1415108f8..000000000 --- a/physics/rrtmgp_sw_cloud_sampling.meta +++ /dev/null @@ -1,240 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_sw_cloud_sampling - type = scheme - dependencies = machine.F,mersenne_twister.f,rrtmgp_sampling.F90,radiation_tools.F90 - -###################################################### -[ccpp-arg-table] - name = rrtmgp_sw_cloud_sampling_run - type = scheme -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = logical flags for sw radiation calls - units = flag - dimensions = () - type = logical - intent = in -[imfdeepcnv] - standard_name = control_for_deep_convection_scheme - long_name = flag for mass-flux deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_gf] - standard_name = identifier_for_grell_freitas_deep_convection - long_name = flag for Grell-Freitas deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[imfdeepcnv_samf] - standard_name = identifer_for_scale_aware_mass_flux_deep_convection - long_name = flag for SAMF deep convection scheme - units = flag - dimensions = () - type = integer - intent = in -[iovr_convcld] - standard_name = flag_for_convective_cloud_overlap_method_for_radiation - long_name = flag for convective cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nday] - standard_name = daytime_points_dimension - long_name = daytime points dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[isubc_sw] - standard_name = flag_for_sw_clouds_grid_approximation - long_name = flag for sw clouds sub-grid approximation - units = flag - dimensions = () - type = integer - intent = in -[idxday] - standard_name = daytime_points - long_name = daytime points - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[iovr] - standard_name = flag_for_cloud_overlap_method_for_radiation - long_name = max-random overlap clouds - units = flag - dimensions = () - type = integer - intent = in -[iovr_maxrand] - standard_name = flag_for_maximum_random_cloud_overlap_method - long_name = choice of maximum-random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_dcorr] - standard_name = flag_for_decorrelation_length_cloud_overlap_method - long_name = choice of decorrelation-length cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_exp] - standard_name = flag_for_exponential_cloud_overlap_method - long_name = choice of exponential cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_exprand] - standard_name = flag_for_exponential_random_cloud_overlap_method - long_name = choice of exponential-random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_rand] - standard_name = flag_for_random_cloud_overlap_method - long_name = choice of random cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[iovr_max] - standard_name = flag_for_maximum_cloud_overlap_method - long_name = choice of maximum cloud overlap method - units = flag - dimensions = () - type = integer - intent = in -[icseed_sw] - standard_name = random_number_seed_for_mcica_shortwave - long_name = seed for random number generation for shortwave radiation - units = none - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[cld_frac] - standard_name = total_cloud_fraction - long_name = layer total cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[precip_frac] - standard_name = precipitation_fraction_by_layer - long_name = precipitation fraction in each layer - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cld_cnv_frac] - standard_name = convective_cloud_fraction_for_RRTMGP - long_name = layer convective cloud fraction - units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cnv_cloud_overlap_param] - standard_name = convective_cloud_overlap_param - long_name = convective cloud overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[cloud_overlap_param] - standard_name = cloud_overlap_param - long_name = cloud overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[precip_overlap_param] - standard_name = precip_overlap_param - long_name = precipitation overlap parameter - units = km - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[sw_optical_props_cloudsByBand] - standard_name = shortwave_optical_properties_for_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_cnvcloudsByBand] - standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_precipByBand] - standard_name = shortwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_clouds] - standard_name = shortwave_optical_properties_for_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[sw_optical_props_cnvclouds] - standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[sw_optical_props_precip] - standard_name = shortwave_optical_properties_for_precipitation - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rrtmgp_sw_gas_optics.F90 b/physics/rrtmgp_sw_gas_optics.F90 index 4bafa56a4..f62a75e4b 100644 --- a/physics/rrtmgp_sw_gas_optics.F90 +++ b/physics/rrtmgp_sw_gas_optics.F90 @@ -2,11 +2,8 @@ !! !> \defgroup rrtmgp_sw_gas_optics rrtmgp_sw_gas_optics.F90 !! -!! \brief This module contains two routines: One to initialize the k-distribution data -!! and functions needed to compute the shortwave gaseous optical properties in RRTMGP. -!! The second routine is a ccpp scheme within the "radiation loop", where the shortwave -!! optical prperties (optical-depth, single-scattering albedo, asymmetry parameter) are -!! computed for clear-sky conditions (no aerosols) +!! \brief This module contains a routine to initialize the k-distribution data used +!! by the RRTMGP shortwave radiation scheme. !! module rrtmgp_sw_gas_optics use machine, only: kind_phys @@ -14,7 +11,6 @@ module rrtmgp_sw_gas_optics use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp use mo_gas_concentrations, only: ty_gas_concs use radiation_tools, only: check_error_msg - use mo_optical_props, only: ty_optical_props_2str use netcdf #ifdef MPI use mpi @@ -83,7 +79,7 @@ module rrtmgp_sw_gas_optics scale_by_complement_upperSW ! Absorption is scaled by concentration of scaling_gas (F) or its complement (T) contains - + ! ###################################################################################### !>\defgroup rrtmgp_sw_gas_optics_mod GFS RRTMGP-SW Gas Optics Module !> @{ !! \section arg_table_rrtmgp_sw_gas_optics_init @@ -100,19 +96,19 @@ module rrtmgp_sw_gas_optics !! \section rrtmgp_sw_gas_optics_init !> @{ ! ###################################################################################### - subroutine rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, & + subroutine rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, & active_gases_array, mpicomm, mpirank, mpiroot, errmsg, errflg) ! Inputs character(len=128),intent(in) :: & rrtmgp_root_dir, & ! RTE-RRTMGP root directory - rrtmgp_sw_file_gas ! RRTMGP file containing coefficients used to compute gaseous optical properties + rrtmgp_sw_file_gas ! RRTMGP file containing K-distribution data + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array integer,intent(in) :: & mpicomm, & ! MPI communicator mpirank, & ! Current MPI rank mpiroot ! Master MPI rank - character(len=*), dimension(:), intent(in) :: & - active_gases_array ! List of active gases from namelist as array ! Outputs character(len=*), intent(out) :: & @@ -121,11 +117,10 @@ subroutine rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, errflg ! CCPP error code ! Local variables - integer :: status, ncid, dimid, varID, iGas, mpierr, iChar + integer :: status, ncid, dimid, varID, mpierr, iChar integer,dimension(:),allocatable :: temp1, temp2, temp3, temp4 character(len=264) :: sw_gas_props_file - type(ty_gas_concs) :: gas_concentrations ! RRTMGP DDT containing active trace gases - + type(ty_gas_concs) :: gas_concs ! RRTMGP DDT containing active trace gases ! Initialize errmsg = '' @@ -488,129 +483,19 @@ subroutine rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, ! Initialize RRTMGP DDT's... ! ! ####################################################################################### - allocate(gas_concentrations%gas_name(1:size(active_gases_array))) - gas_concentrations%gas_name(:) = active_gases_array(:) - call check_error_msg('sw_gas_optics_init',sw_gas_props%load(gas_concentrations, & + call check_error_msg('rrtmgp_sw_gas_optics_init_gas_concs',gas_concs%init(active_gases_array)) + call check_error_msg('rrtmgp_sw_gas_optics_init_load',sw_gas_props%load(gas_concs, & gas_namesSW, key_speciesSW, band2gptSW, band_limsSW, press_refSW, press_ref_tropSW,& temp_refSW, temp_ref_pSW, temp_ref_tSW, vmr_refSW, kmajorSW, kminor_lowerSW, & kminor_upperSW, gas_minorSW, identifier_minorSW, minor_gases_lowerSW, & minor_gases_upperSW, minor_limits_gpt_lowerSW, minor_limits_gpt_upperSW, & minor_scales_with_density_lowerSW, minor_scales_with_density_upperSW, & scaling_gas_lowerSW, scaling_gas_upperSW, scale_by_complement_lowerSW, & - - scale_by_complement_upperSW, kminor_start_lowerSW, kminor_start_upperSW, & solar_quietSW, solar_facularSW, solar_sunspotSW, tsi_defaultSW, mg_defaultSW, & sb_defaultSW, rayl_lowerSW, rayl_upperSW)) end subroutine rrtmgp_sw_gas_optics_init - -!> @} - ! ###################################################################################### -!> \section arg_table_rrtmgp_sw_gas_optics_run -!! \htmlinclude rrtmgp_sw_gas_optics.html -!! -!> \ingroup rrtmgp_sw_gas_optics -!! -!! Compute shortwave optical prperties (optical-depth, single-scattering albedo, -!! asymmetry parameter) for clear-sky conditions. -!! -!! \section rrtmgp_sw_gas_optics_run -!> @{ - ! ###################################################################################### - subroutine rrtmgp_sw_gas_optics_run(doSWrad, nCol, nLev, ngptsGPsw, nday, idxday, p_lay, & - p_lev, toa_src_sw, t_lay, t_lev, active_gases_array, gas_concentrations, solcon, & - sw_optical_props_clrsky, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - doSWrad ! Flag to calculate SW irradiances - integer,intent(in) :: & - ngptsGPsw, & ! Number of spectral (g) points. - nDay, & ! Number of daylit points. - nCol, & ! Number of horizontal points - nLev ! Number of vertical levels - integer,intent(in),dimension(ncol) :: & - idxday ! Indices for daylit points. - real(kind_phys), dimension(ncol,nLev), intent(in) :: & - p_lay, & ! Pressure @ model layer-centers (Pa) - t_lay ! Temperature (K) - real(kind_phys), dimension(ncol,nLev+1), intent(in) :: & - p_lev, & ! Pressure @ model layer-interfaces (Pa) - t_lev ! Temperature @ model levels - type(ty_gas_concs),intent(inout) :: & - gas_concentrations ! RRTMGP DDT: trace gas concentrations (vmr) - real(kind_phys), intent(in) :: & - solcon ! Solar constant - - ! Output - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error code - type(ty_optical_props_2str),intent(out) :: & - sw_optical_props_clrsky ! RRTMGP DDT: clear-sky shortwave optical properties, spectral (tau,ssa,g) - real(kind_phys), dimension(nCol,ngptsGPsw), intent(out) :: & - toa_src_sw ! TOA incident spectral flux (W/m2) - character(len=*), dimension(:), intent(in) :: & - active_gases_array ! List of active gases from namelist as array - - ! Local variables - integer :: ij,iGas - real(kind_phys), dimension(ncol,nLev) :: vmrTemp - real(kind_phys), dimension(nday,ngptsGPsw) :: toa_src_sw_temp - type(ty_gas_concs) :: gas_concentrations_daylit - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doSWrad) return - - gas_concentrations%gas_name(:) = active_gases_array(:) - - toa_src_sw(:,:) = 0._kind_phys - if (nDay .gt. 0) then - ! Allocate space - call check_error_msg('rrtmgp_sw_gas_optics_run_alloc_2str',& - sw_optical_props_clrsky%alloc_2str(nday, nLev, sw_gas_props)) - - gas_concentrations_daylit%ncol = nDay - gas_concentrations_daylit%nlay = nLev - allocate(gas_concentrations_daylit%gas_name(gas_concentrations%get_num_gases())) - allocate(gas_concentrations_daylit%concs(gas_concentrations%get_num_gases())) - do iGas=1,gas_concentrations%get_num_gases() - allocate(gas_concentrations_daylit%concs(iGas)%conc(nDay, nLev)) - enddo - gas_concentrations_daylit%gas_name(:) = active_gases_array(:) - - ! Subset the gas concentrations. - do iGas=1,gas_concentrations%get_num_gases() - call check_error_msg('rrtmgp_sw_gas_optics_run_get_vmr',& - gas_concentrations%get_vmr(trim(gas_concentrations_daylit%gas_name(iGas)),vmrTemp)) - call check_error_msg('rrtmgp_sw_gas_optics_run_set_vmr',& - gas_concentrations_daylit%set_vmr(trim(gas_concentrations_daylit%gas_name(iGas)),vmrTemp(idxday(1:nday),:))) - enddo - - ! Call SW gas-optics - call check_error_msg('rrtmgp_sw_gas_optics_run',sw_gas_props%gas_optics(& - p_lay(idxday(1:nday),:), & ! IN - Pressure @ layer-centers (Pa) - p_lev(idxday(1:nday),:), & ! IN - Pressure @ layer-interfaces (Pa) - t_lay(idxday(1:nday),:), & ! IN - Temperature @ layer-centers (K) - gas_concentrations_daylit, & ! IN - RRTMGP DDT: trace gas volumne mixing-ratios - sw_optical_props_clrsky, & ! OUT - RRTMGP DDT: Shortwave optical properties, by - ! spectral point (tau,ssa,g) - toa_src_sw_temp)) ! OUT - TOA incident shortwave radiation (spectral) - toa_src_sw(idxday(1:nday),:) = toa_src_sw_temp - - ! Scale incident flux - do ij=1,nday - toa_src_sw(idxday(ij),:) = toa_src_sw(idxday(ij),:)*solcon/ & - sum(toa_src_sw(idxday(ij),:)) - enddo - endif - - end subroutine rrtmgp_sw_gas_optics_run !> @} end module rrtmgp_sw_gas_optics diff --git a/physics/rrtmgp_sw_gas_optics.meta b/physics/rrtmgp_sw_gas_optics.meta deleted file mode 100644 index 1fdbc946b..000000000 --- a/physics/rrtmgp_sw_gas_optics.meta +++ /dev/null @@ -1,201 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_sw_gas_optics - type = scheme - dependencies = machine.F,radiation_tools.F90,GFS_rrtmgp_pre.F90,rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90,rte-rrtmgp/rte/mo_rte_kind.F90,rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90,rte-rrtmgp/rte/mo_optical_props.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_sw_gas_optics_init - type = scheme -[rrtmgp_root_dir] - standard_name = directory_for_rte_rrtmgp_source_code - long_name = directory for rte+rrtmgp source code - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[rrtmgp_sw_file_gas] - standard_name = filename_of_rrtmgp_shortwave_k_distribution - long_name = file containing RRTMGP SW k-distribution - units = none - dimensions = () - type = character - intent = in - kind = len=128 -[active_gases_array] - standard_name = list_of_active_gases_used_by_RRTMGP - long_name = list of active gases used by RRTMGP - units = none - dimensions = (number_of_active_gases_used_by_RRTMGP) - type = character - kind = len=* - intent = in -[mpirank] - standard_name = mpi_rank - long_name = current MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpiroot] - standard_name = mpi_root - long_name = master MPI rank - units = index - dimensions = () - type = integer - intent = in -[mpicomm] - standard_name = mpi_communicator - long_name = MPI communicator - units = index - dimensions = () - type = integer - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_sw_gas_optics_run - type = scheme -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = flag to calculate SW irradiances - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[nday] - standard_name = daytime_points_dimension - long_name = daytime points dimension - units = count - dimensions = () - type = integer - intent = in -[idxday] - standard_name = daytime_points - long_name = daytime points - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[ngptsGPsw] - standard_name = number_of_shortwave_spectral_points - long_name = number of spectral points in RRTMGP SW calculation - units = count - dimensions = () - type = integer - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure layer - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[p_lev] - standard_name = air_pressure_at_interface_for_RRTMGP - long_name = air pressure level - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature layer - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[t_lev] - standard_name = air_temperature_at_interface_for_RRTMGP - long_name = air temperature level - units = K - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[toa_src_sw] - standard_name = toa_incident_sw_flux_by_spectral_point - long_name = TOA shortwave incident flux at each spectral points - units = W m-2 - dimensions = (horizontal_loop_extent,number_of_shortwave_spectral_points) - type = real - kind = kind_phys - intent = out -[active_gases_array] - standard_name = list_of_active_gases_used_by_RRTMGP - long_name = list of active gases used by RRTMGP - units = none - dimensions = (number_of_active_gases_used_by_RRTMGP) - type = character - kind = len=* - intent = in -[gas_concentrations] - standard_name = Gas_concentrations_for_RRTMGP_suite - long_name = DDT containing gas concentrations for RRTMGP radiation scheme - units = DDT - dimensions = () - type = ty_gas_concs - intent = inout -[solcon] - standard_name = solar_constant - long_name = solar constant - units = W m-2 - dimensions = () - type = real - kind = kind_phys - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out -[sw_optical_props_clrsky] - standard_name = shortwave_optical_properties_for_clear_sky - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = out diff --git a/physics/rrtmgp_sw_main.F90 b/physics/rrtmgp_sw_main.F90 new file mode 100644 index 000000000..b25e093e7 --- /dev/null +++ b/physics/rrtmgp_sw_main.F90 @@ -0,0 +1,683 @@ +! ########################################################################################### +! ########################################################################################### +module rrtmgp_sw_main + use machine, only: kind_phys, kind_dbl_prec + use mo_optical_props, only: ty_optical_props_2str + use mo_cloud_optics, only: ty_cloud_optics + use module_radsw_parameters, only: cmpfsw_type + use mo_rte_sw, only: rte_sw + use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp + use mo_gas_concentrations, only: ty_gas_concs + use mo_fluxes_byband, only: ty_fluxes_byband + use radiation_tools, only: check_error_msg + use rrtmgp_sw_gas_optics, only: sw_gas_props,rrtmgp_sw_gas_optics_init + use rrtmgp_sw_cloud_optics, only: sw_cloud_props, rrtmgp_sw_cloud_optics_init, a0r, a0s, & + a1s, b0r, b0s, b1s, c0r, c0s + use GFS_rrtmgp_pre, only: iStr_h2o, iStr_co2, iStr_o3, iStr_n2o, iStr_ch4, & + iStr_o2, iStr_ccl4, iStr_cfc11, iStr_cfc12, iStr_cfc22, & + eps, oneminus, ftiny + use mersenne_twister, only: random_setseed, random_number, random_stat + use rrtmgp_sampling, only: sampled_mask, draw_samples + implicit none + + type(ty_gas_concs) :: gas_concs + type(ty_optical_props_2str) :: sw_optical_props_accum, sw_optical_props_aerosol_local, & + sw_optical_props_cloudsByBand, sw_optical_props_cnvcloudsByBand, & + sw_optical_props_pblcloudsByBand, sw_optical_props_precipByBand, & + sw_optical_props_clouds + + public rrtmgp_sw_main_init, rrtmgp_sw_main_run + +contains + + ! ######################################################################################### + ! SUBROUTINE rrtmgp_sw_main_init + ! ######################################################################################### +!! \section arg_table_rrtmgp_sw_main_init +!! \htmlinclude rrtmgp_sw_main_init.html +!! + subroutine rrtmgp_sw_main_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, rrtmgp_sw_file_clouds,& + active_gases_array, doGP_cldoptics_PADE, doGP_cldoptics_LUT, doGP_sgs_pbl, & + doGP_sgs_cnv, nrghice, mpicomm, mpirank, mpiroot, nLay, rrtmgp_phys_blksz, & + errmsg, errflg) + + ! Inputs + character(len=128),intent(in) :: & + rrtmgp_root_dir, & ! RTE-RRTMGP root directory + rrtmgp_sw_file_clouds, & ! RRTMGP file containing K-distribution data + rrtmgp_sw_file_gas ! RRTMGP file containing cloud-optics data + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array) + logical, intent(in) :: & + doGP_cldoptics_PADE, & ! Use RRTMGP cloud-optics: PADE approximation? + doGP_cldoptics_LUT, & ! Use RRTMGP cloud-optics: LUTs? + doGP_sgs_pbl, & ! Flag to include sgs PBL clouds + doGP_sgs_cnv ! Flag to include sgs convective clouds + integer, intent(inout) :: & + nrghice ! Number of ice-roughness categories + integer,intent(in) :: & + mpicomm, & ! MPI communicator + mpirank, & ! Current MPI rank + mpiroot, & ! Master MPI rank + rrtmgp_phys_blksz, & ! Number of horizontal points to process at once. + nLay + ! Outputs + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error code + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + ! RRTMGP shortwave gas-optics (k-distribution) initialization + call rrtmgp_sw_gas_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_gas, active_gases_array,& + mpicomm, mpirank, mpiroot, errmsg, errflg) + + ! RRTMGP shortwave cloud-optics initialization + call rrtmgp_sw_cloud_optics_init(rrtmgp_root_dir, rrtmgp_sw_file_clouds, & + doGP_cldoptics_PADE, doGP_cldoptics_LUT, nrghice, mpicomm, mpirank, mpiroot, & + errmsg, errflg) + + ! DDTs + + ! ty_gas_concs + call check_error_msg('rrtmgp_sw_main_gas_concs_init',gas_concs%init(active_gases_array)) + + ! ty_optical_props + call check_error_msg('rrtmgp_sw_main_accumulated_optics_init',& + sw_optical_props_accum%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props)) + call check_error_msg('rrtmgp_sw_main_cloud_optics_init',& + sw_optical_props_cloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props%get_band_lims_wavenumber())) + call check_error_msg('rrtmgp_sw_main_precip_optics_init',& + sw_optical_props_precipByBand%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props%get_band_lims_wavenumber())) + call check_error_msg('rrtmgp_sw_mian_cloud_sampling_init', & + sw_optical_props_clouds%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props)) + call check_error_msg('rrtmgp_sw_main_aerosol_optics_init',& + sw_optical_props_aerosol_local%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props%get_band_lims_wavenumber())) + if (doGP_sgs_cnv) then + call check_error_msg('rrtmgp_sw_main_cnv_cloud_optics_init',& + sw_optical_props_cnvcloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props%get_band_lims_wavenumber())) + endif + if (doGP_sgs_pbl) then + call check_error_msg('rrtmgp_sw_main_pbl_cloud_optics_init',& + sw_optical_props_pblcloudsByBand%alloc_2str(rrtmgp_phys_blksz, nLay, sw_gas_props%get_band_lims_wavenumber())) + endif + end subroutine rrtmgp_sw_main_init + + ! ######################################################################################### + ! SUBROUTINE rrtmgp_sw_main_run + ! ######################################################################################### +!! \section arg_table_rrtmgp_sw_main_run +!! \htmlinclude rrtmgp_sw_main_run.html +!! + subroutine rrtmgp_sw_main_run(doSWrad, doSWclrsky, top_at_1, doGP_sgs_cnv, doGP_sgs_pbl, & + nCol, nDay, nLay, nGases, rrtmgp_phys_blksz, idx, icseed_sw, iovr, iovr_convcld, & + iovr_max, iovr_maxrand, iovr_rand, iovr_dcorr, iovr_exp, iovr_exprand, isubc_sw, & + iSFC, sfc_alb_nir_dir, sfc_alb_nir_dif, sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, coszen,& + p_lay, p_lev, t_lay, t_lev, vmr_o2, vmr_h2o, vmr_o3, vmr_ch4, vmr_n2o, vmr_co2, & + cld_frac, cld_lwp, cld_reliq, cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, & + cld_rerain, precip_frac, cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, & + cld_pbl_lwp, cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, cloud_overlap_param, & + active_gases_array, aersw_tau, aersw_ssa, aersw_g, solcon, scmpsw, & + fluxswUP_allsky, fluxswDOWN_allsky, fluxswUP_clrsky, fluxswDOWN_clrsky, cldtausw, & + errmsg, errflg) + + ! Inputs + logical, intent(in) :: & + doSWrad, & ! Flag to perform shortwave calculation + doSWclrsky, & ! Flag to compute clear-sky fluxes + top_at_1, & ! Flag for vertical ordering convention + doGP_sgs_pbl, & ! Flag to include sgs PBL clouds + doGP_sgs_cnv ! Flag to include sgs convective clouds + integer,intent(in) :: & + nCol, & ! Number of horizontal points + nDay, & ! Number of daytime points + nLay, & ! Number of vertical grid points. + nGases, & ! Number of active gases + rrtmgp_phys_blksz, & ! Number of horizontal points to process at once. + iovr, & ! Choice of cloud-overlap method + iovr_convcld, & ! Choice of convective cloud-overlap + iovr_max, & ! Flag for maximum cloud overlap method + iovr_maxrand, & ! Flag for maximum-random cloud overlap method + iovr_rand, & ! Flag for random cloud overlap method + iovr_dcorr, & ! Flag for decorrelation-length cloud overlap method + iovr_exp, & ! Flag for exponential cloud overlap method + iovr_exprand, & ! Flag for exponential-random cloud overlap method + isubc_sw, & ! + iSFC + integer,intent(in),dimension(:) :: & + idx, & ! Index array for daytime points + icseed_sw ! Seed for random number generation for shortwave radiation + real(kind_phys), dimension(:), intent(in) :: & + sfc_alb_nir_dir, & ! Surface albedo (direct) + sfc_alb_nir_dif, & ! Surface albedo (diffuse) + sfc_alb_uvvis_dir, & ! Surface albedo (direct) + sfc_alb_uvvis_dif, & ! Surface albedo (diffuse) + coszen ! Cosize of SZA + real(kind_phys), dimension(:,:), intent(in) :: & + p_lay, & ! Pressure @ model layer-centers (Pa) + t_lay, & ! Temperature (K) + p_lev, & ! Pressure @ model layer-interfaces (Pa) + t_lev, & ! Temperature @ model levels (K) + vmr_o2, & ! Molar-mixing ratio oxygen + vmr_h2o, & ! Molar-mixing ratio water vapor + vmr_o3, & ! Molar-mixing ratio ozone + vmr_ch4, & ! Molar-mixing ratio methane + vmr_n2o, & ! Molar-mixing ratio nitrous oxide + vmr_co2, & ! Molar-mixing ratio carbon dioxide + cld_frac, & ! Cloud-fraction for stratiform clouds + cld_lwp, & ! Water path for stratiform liquid cloud-particles + cld_reliq, & ! Effective radius for stratiform liquid cloud-particles + cld_iwp, & ! Water path for stratiform ice cloud-particles + cld_reice, & ! Effective radius for stratiform ice cloud-particles + cld_swp, & ! Water path for snow hydrometeors + cld_resnow, & ! Effective radius for snow hydrometeors + cld_rwp, & ! Water path for rain hydrometeors + cld_rerain, & ! Effective radius for rain hydrometeors + precip_frac, & ! Precipitation fraction + cld_cnv_lwp, & ! Water path for convective liquid cloud-particles + cld_cnv_reliq, & ! Effective radius for convective liquid cloud-particles + cld_cnv_iwp, & ! Water path for convective ice cloud-particles + cld_cnv_reice, & ! Effective radius for convective ice cloud-particles + cld_pbl_lwp, & ! Water path for PBL liquid cloud-particles + cld_pbl_reliq, & ! Effective radius for PBL liquid cloud-particles + cld_pbl_iwp, & ! Water path for PBL ice cloud-particles + cld_pbl_reice, & ! Effective radius for PBL ice cloud-particles + cloud_overlap_param ! + real(kind_phys), dimension(:,:,:), intent(in) :: & + aersw_tau, & ! Aerosol optical depth + aersw_ssa, & ! Aerosol single scattering albedo + aersw_g ! Aerosol asymmetry paramter + character(len=*), dimension(:), intent(in) :: & + active_gases_array ! List of active gases from namelist as array + real(kind_phys), intent(in) :: & + solcon ! Solar constant + + ! Outputs + character(len=*), intent(out) :: & + errmsg ! CCPP error message + integer, intent(out) :: & + errflg ! CCPP error flag + real(kind_phys), dimension(:,:), intent(inout) :: & + cldtausw ! Approx 10.mu band layer cloud optical depth + real(kind_phys), dimension(:,:), intent(inout) :: & + fluxswUP_allsky, & ! RRTMGP upward all-sky flux profiles (W/m2) + fluxswDOWN_allsky, & ! RRTMGP downward all-sky flux profiles (W/m2) + fluxswUP_clrsky, & ! RRTMGP upward clear-sky flux profiles (W/m2) + fluxswDOWN_clrsky ! RRTMGP downward clear-sky flux profiles (W/m2) + type(cmpfsw_type), dimension(:), intent(inout) :: & + scmpsw ! 2D surface fluxes, components: + ! uvbfc - total sky downward uv-b flux (W/m2) + ! uvbf0 - clear sky downward uv-b flux (W/m2) + ! nirbm - downward nir direct beam flux (W/m2) + ! nirdf - downward nir diffused flux (W/m2) + ! visbm - downward uv+vis direct beam flux (W/m2) + ! visdf - downward uv+vis diffused flux (W/m2) + + ! Local variables + type(cmpfsw_type), dimension(rrtmgp_phys_blksz) :: scmpsw_clrsky, scmpsw_allsky + type(ty_fluxes_byband) :: flux_allsky, flux_clrsky + real(kind_phys) :: tau_rain, tau_snow, ssa_rain, ssa_snow, asy_rain, asy_snow, & + tau_prec, asy_prec, ssa_prec, asyw, ssaw, za1, za2, flux_dir, flux_dif + real(kind_phys), dimension(rrtmgp_phys_blksz) :: zcf0, zcf1 + real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt()) :: rng1D + real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt(),nLay,rrtmgp_phys_blksz) :: rng3D,rng3D2 + real(kind_dbl_prec), dimension(sw_gas_props%get_ngpt()*nLay) :: rng2D + logical, dimension(rrtmgp_phys_blksz,nLay,sw_gas_props%get_ngpt()) :: maskMCICA + logical :: cloudy_column, clear_column + real(kind_phys), dimension(sw_gas_props%get_nband(),rrtmgp_phys_blksz) :: & + sfc_alb_dir, sfc_alb_dif + real(kind_phys), dimension(rrtmgp_phys_blksz,nLay+1,sw_gas_props%get_nband()),target :: & + fluxSW_up_allsky, fluxSW_up_clrsky, fluxSW_dn_dir_clrsky, fluxSW_dn_allsky, & + fluxSW_dn_clrsky, fluxSW_dn_dir_allsky + integer :: iBand, ibd, ibd_uv, iCol, iGas, iLay, ix, ix2, iblck + integer, dimension(rrtmgp_phys_blksz) :: ipseed_sw, iCols + type(random_stat) :: rng_stat + real(kind_phys), dimension(2,sw_gas_props%get_nband()) :: bandlimits + real(kind_phys), dimension(2), parameter :: & + nIR_uvvis_bnd = (/12850,16000/), & + uvb_bnd = (/29000,38000/) + real(kind_phys), dimension(rrtmgp_phys_blksz,sw_gas_props%get_ngpt()) :: toa_src_sw + + ! Initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + if (.not. doSWrad) return + + if (nDay .gt. 0) then + + bandlimits = sw_gas_props%get_band_lims_wavenumber() + ! ###################################################################################### + ! + ! Loop over all (daylit) columns... + ! + ! ###################################################################################### + do iCol=1,nDay,rrtmgp_phys_blksz + !ix = idx(iCol) + !ix2 = idx(iCol + rrtmgp_phys_blksz - 1) + iCols = idx(iCol:iCol + rrtmgp_phys_blksz - 1) + + ! Create clear/cloudy indicator + zcf0(:) = 1._kind_phys + zcf1(:) = 1._kind_phys + do iblck = 1, rrtmgp_phys_blksz + do iLay=1,nLay + zcf0(iblck) = min(zcf0(iblck), 1._kind_phys - cld_frac(iCols(iblck),iLay)) + enddo + if (zcf0(iblck) <= ftiny) zcf0(iblck) = 0._kind_phys + if (zcf0(iblck) > oneminus) zcf0(iblck) = 1._kind_phys + zcf1(iblck) = 1._kind_phys - zcf0(iblck) + enddo + cloudy_column = any(zcf1 .gt. eps) + clear_column = .true. + if (cloudy_column) clear_column = .false. + + ! ################################################################################### + ! + ! Initialize/reset + ! + ! ################################################################################### + sw_optical_props_clouds%tau = 0._kind_phys + sw_optical_props_clouds%ssa = 0._kind_phys + sw_optical_props_clouds%g = 0._kind_phys + sw_optical_props_accum%tau = 0._kind_phys + sw_optical_props_accum%ssa = 0._kind_phys + sw_optical_props_accum%g = 0._kind_phys + sw_optical_props_cloudsByBand%tau = 0._kind_phys + sw_optical_props_cloudsByBand%ssa = 0._kind_phys + sw_optical_props_cloudsByBand%g = 0._kind_phys + sw_optical_props_precipByBand%tau = 0._kind_phys + sw_optical_props_precipByBand%ssa = 0._kind_phys + sw_optical_props_precipByBand%g = 0._kind_phys + if (doGP_sgs_cnv) then + sw_optical_props_cnvcloudsByBand%tau = 0._kind_phys + sw_optical_props_cnvcloudsByBand%ssa = 0._kind_phys + sw_optical_props_cnvcloudsByBand%g = 0._kind_phys + endif + if (doGP_sgs_pbl) then + sw_optical_props_pblcloudsByBand%tau = 0._kind_phys + sw_optical_props_pblcloudsByBand%ssa = 0._kind_phys + sw_optical_props_pblcloudsByBand%g = 0._kind_phys + endif + scmpsw_clrsky= cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) + scmpsw_allsky= cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) + cldtausw = 0._kind_phys + + ! ty_fluxes_byband + fluxSW_up_allsky = 0._kind_phys + fluxSW_dn_allsky = 0._kind_phys + fluxSW_dn_dir_allsky = 0._kind_phys + fluxSW_up_clrsky = 0._kind_phys + fluxSW_dn_clrsky = 0._kind_phys + flux_allsky%bnd_flux_up => fluxSW_up_allsky + flux_allsky%bnd_flux_dn => fluxSW_dn_allsky + flux_allsky%bnd_flux_dn_dir => fluxSW_dn_dir_allsky + flux_clrsky%bnd_flux_up => fluxSW_up_clrsky + flux_clrsky%bnd_flux_dn => fluxSW_dn_clrsky + + ! ################################################################################### + ! + ! Set gas-concentrations + ! + ! ################################################################################### + call check_error_msg('rrtmgp_sw_main_set_vmr_o2', & + gas_concs%set_vmr(trim(active_gases_array(istr_o2)), vmr_o2(iCols,:))) + call check_error_msg('rrtmgp_sw_main_set_vmr_co2', & + gas_concs%set_vmr(trim(active_gases_array(istr_co2)),vmr_co2(iCols,:))) + call check_error_msg('rrtmgp_sw_main_set_vmr_ch4', & + gas_concs%set_vmr(trim(active_gases_array(istr_ch4)),vmr_ch4(iCols,:))) + call check_error_msg('rrtmgp_sw_main_set_vmr_n2o', & + gas_concs%set_vmr(trim(active_gases_array(istr_n2o)),vmr_n2o(iCols,:))) + call check_error_msg('rrtmgp_sw_main_set_vmr_h2o', & + gas_concs%set_vmr(trim(active_gases_array(istr_h2o)),vmr_h2o(iCols,:))) + call check_error_msg('rrtmgp_sw_main_set_vmr_o3', & + gas_concs%set_vmr(trim(active_gases_array(istr_o3)), vmr_o3(iCols,:))) + + ! ################################################################################### + ! + ! Compute gas-optics + ! + ! ################################################################################### + + call check_error_msg('rrtmgp_sw_main_gas_optics',sw_gas_props%gas_optics(& + p_lay(iCols,:), & ! IN - Pressure @ layer-centers (Pa) + p_lev(iCols,:), & ! IN - Pressure @ layer-interfaces (Pa) + t_lay(iCols,:), & ! IN - Temperature @ layer-centers (K) + gas_concs, & ! IN - RRTMGP DDT: trace gas volumne mixing-ratios + sw_optical_props_accum, & ! OUT - RRTMGP DDT: Shortwave optical properties, by + ! spectral point (tau,ssa,g) + toa_src_sw)) ! OUT - TOA incident shortwave radiation (spectral) + ! Scale incident flux + do iblck = 1, rrtmgp_phys_blksz + toa_src_sw(iblck,:) = toa_src_sw(iblck,:)*solcon / sum(toa_src_sw(iblck,:)) + enddo + + ! ################################################################################### + ! + ! Set surface albedo + ! + ! Use near-IR albedo for bands with wavenumbers extending to 12850cm-1 + ! Use uv-vis albedo for bands with wavenumbers greater than 16000cm-1 + ! For overlapping band, average near-IR and us-vis albedos. + ! + ! ################################################################################### + do iblck = 1, rrtmgp_phys_blksz + do iBand=1,sw_gas_props%get_nband() + if (bandlimits(1,iBand) .lt. nIR_uvvis_bnd(1)) then + sfc_alb_dir(iBand,iblck) = sfc_alb_nir_dir(iCols(iblck)) + sfc_alb_dif(iBand,iblck) = sfc_alb_nir_dif(iCols(iblck)) + endif + if (bandlimits(1,iBand) .eq. nIR_uvvis_bnd(1)) then + sfc_alb_dir(iBand,iblck) = 0.5_kind_phys*(sfc_alb_nir_dir(iCols(iblck)) + & + sfc_alb_uvvis_dir(iCols(iblck))) + sfc_alb_dif(iBand,iblck) = 0.5_kind_phys*(sfc_alb_nir_dif(iCols(iblck)) + & + sfc_alb_uvvis_dif(iCols(iblck))) + ibd = iBand + endif + if (bandlimits(1,iBand) .ge. nIR_uvvis_bnd(2)) then + sfc_alb_dir(iBand,iblck) = sfc_alb_uvvis_dir(iCols(iblck)) + sfc_alb_dif(iBand,iblck) = sfc_alb_uvvis_dif(iCols(iblck)) + endif + if (bandlimits(1,iBand) .eq. uvb_bnd(1)) ibd_uv = iBand + enddo + enddo + + ! ################################################################################### + ! + ! Compute optics for cloud(s) and precipitation, sample clouds... + ! + ! ################################################################################### + if (cloudy_column) then + ! Gridmean/mp-clouds + call check_error_msg('rrtmgp_sw_main_cloud_optics',sw_cloud_props%cloud_optics(& + cld_lwp(iCols,:), & ! IN - Cloud liquid water path + cld_iwp(iCols,:), & ! IN - Cloud ice water path + cld_reliq(iCols,:), & ! IN - Cloud liquid effective radius + cld_reice(iCols,:), & ! IN - Cloud ice effective radius + sw_optical_props_cloudsByBand)) ! OUT - RRTMGP DDT: Shortwave optical properties, + ! in each band (tau,ssa,g) + cldtausw(iCols,:) = sw_optical_props_cloudsByBand%tau(:,:,11) + + ! Include convective clouds? + if (doGP_sgs_cnv) then + ! Compute + call check_error_msg('rrtmgp_sw_main_cnv_cloud_optics',sw_cloud_props%cloud_optics(& + cld_cnv_lwp(iCols,:), & ! IN - Convective cloud liquid water path (g/m2) + cld_cnv_iwp(iCols,:), & ! IN - Convective cloud ice water path (g/m2) + cld_cnv_reliq(iCols,:), & ! IN - Convective cloud liquid effective radius (microns) + cld_cnv_reice(iCols,:), & ! IN - Convective cloud ice effective radius (microns) + sw_optical_props_cnvcloudsByBand)) ! OUT - RRTMGP DDT containing convective cloud radiative properties + ! in each band + ! Increment + call check_error_msg('rrtmgp_sw_main_increment_cnvclouds_to_clouds',& + sw_optical_props_cnvcloudsByBand%increment(sw_optical_props_cloudsByBand)) + endif + + ! Include PBL clouds? + if (doGP_sgs_pbl) then + ! Compute + call check_error_msg('rrtmgp_sw_main_pbl_cloud_optics',sw_cloud_props%cloud_optics(& + cld_pbl_lwp(iCols,:), & ! IN - PBL cloud liquid water path (g/m2) + cld_pbl_iwp(iCols,:), & ! IN - PBL cloud ice water path (g/m2) + cld_pbl_reliq(iCols,:), & ! IN - PBL cloud liquid effective radius (microns) + cld_pbl_reice(iCols,:), & ! IN - PBL cloud ice effective radius (microns) + sw_optical_props_pblcloudsByBand)) ! OUT - RRTMGP DDT containing PBL cloud radiative properties + ! in each band + ! Increment + call check_error_msg('rrtmgp_sw_main_increment_pblclouds_to_clouds',& + sw_optical_props_pblcloudsByBand%increment(sw_optical_props_cloudsByBand)) + endif + + ! Cloud precipitation optics: rain and snow(+groupel) + do iblck = 1, rrtmgp_phys_blksz + do iLay=1,nLay + if (cld_frac(iCols(iblck),iLay) .gt. ftiny) then + ! Rain/Snow optical depth (No band dependence) + tau_rain = cld_rwp(iCols(iblck),iLay)*a0r + if (cld_swp(iCols(iblck),iLay) .gt. 0. .and. cld_resnow(iCols(iblck),iLay) .gt. 10._kind_phys) then + tau_snow = cld_swp(iCols(iblck),iLay)*1.09087*(a0s + a1s/(1.0315*cld_resnow(iCols(iblck),iLay))) ! fu's formula + else + tau_snow = 0._kind_phys + endif + + ! Rain/Snow single-scattering albedo and asymmetry (Band dependent) + do iBand=1,sw_gas_props%get_nband() + ! By species + ssa_rain = tau_rain*(1.-b0r(iBand)) + asy_rain = ssa_rain*c0r(iBand) + ssa_snow = tau_snow*(1.-(b0s(iBand)+b1s(iBand)*1.0315*cld_resnow(iCols(iblck),iLay))) + asy_snow = ssa_snow*c0s(iBand) + ! Combine + tau_prec = max(1.e-12_kind_phys, tau_rain + tau_snow) + ssa_prec = max(1.e-12_kind_phys, ssa_rain + ssa_snow) + asy_prec = max(1.e-12_kind_phys, asy_rain + asy_snow) + asyw = asy_prec/max(1.e-12_kind_phys, ssa_prec) + ssaw = min(1._kind_phys-0.000001, ssa_prec/tau_prec) + za1 = asyw * asyw + za2 = ssaw * za1 + sw_optical_props_precipByBand%tau(iblck,iLay,iBand) = (1._kind_phys - za2) * tau_prec + sw_optical_props_precipByBand%ssa(iblck,iLay,iBand) = (ssaw - za2) / (1._kind_phys - za2) + sw_optical_props_precipByBand%g(iblck,iLay,iBand) = asyw/(1+asyw) + enddo + endif + enddo + enddo + ! Increment + call check_error_msg('rrtmgp_sw_main_increment_precip_to_clouds',& + sw_optical_props_precipByBand%increment(sw_optical_props_cloudsByBand)) + + ! ################################################################################### + ! + ! Cloud-sampling + ! + ! ################################################################################### + ! Change random number seed value for each radiation invocation (isubc_sw =1 or 2). + if(isubc_sw == 1) then ! advance prescribed permutation seed + do iblck = 1, rrtmgp_phys_blksz + ipseed_sw(iblck) = sw_gas_props%get_ngpt() + iCols(iblck) + enddo + elseif (isubc_sw == 2) then ! use input array of permutaion seeds + do iblck = 1, rrtmgp_phys_blksz + ipseed_sw(iblck) = icseed_sw(iCols(iblck)) + enddo + endif + + ! Call RNG + do iblck = 1, rrtmgp_phys_blksz + call random_setseed(ipseed_sw(iblck),rng_stat) + ! Use same rng for each layer + if (iovr == iovr_max) then + call random_number(rng1D,rng_stat) + do iLay=1,nLay + rng3D(:,iLay,iblck) = rng1D + enddo + else + do iLay=1,nLay + call random_number(rng1D,rng_stat) + rng3D(:,iLay,iblck) = rng1D + enddo + endif + enddo + + ! Cloud-overlap. + ! Maximum-random, random or maximum. + if (iovr == iovr_maxrand .or. iovr == iovr_rand .or. iovr == iovr_max) then + call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(iCols,:), maskMCICA) + endif + ! Exponential decorrelation length overlap + if (iovr == iovr_dcorr) then + do iblck = 1, rrtmgp_phys_blksz + ! Generate second RNG + call random_setseed(ipseed_sw(iblck),rng_stat) + call random_number(rng2D,rng_stat) + rng3D2(:,:,iblck) = reshape(source = rng2D,shape=[sw_gas_props%get_ngpt(),nLay]) + enddo + ! + call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(iCols,:), maskMCICA, & + overlap_param = cloud_overlap_param(iCols,1:nLay-1), randoms2 = real(rng3D2, kind=kind_phys)) + endif + ! Exponential or Exponential-random + if (iovr == iovr_exp .or. iovr == iovr_exprand) then + call sampled_mask(real(rng3D, kind=kind_phys), cld_frac(iCols,:), maskMCICA, & + overlap_param = cloud_overlap_param(iCols,1:nLay-1)) + endif + ! Sampling. Map band optical depth to each g-point using McICA + call check_error_msg('rrtmgp_sw_main_cloud_sampling',& + draw_samples(maskMCICA, .true., & + sw_optical_props_cloudsByBand, sw_optical_props_clouds)) + endif ! cloudy_column + + ! ################################################################################### + ! + ! Compute clear-sky fluxes (gaseous+aerosol) + ! + ! ################################################################################### + ! Increment optics (always) + sw_optical_props_aerosol_local%tau = aersw_tau(iCols,:,:) + sw_optical_props_aerosol_local%ssa = aersw_ssa(iCols,:,:) + sw_optical_props_aerosol_local%g = aersw_g(iCols,:,:) + call check_error_msg('rrtmgp_sw_main_increment_aerosol_to_clrsky', & + sw_optical_props_aerosol_local%increment(sw_optical_props_accum)) + + ! Compute clear-sky fluxes (Yes for no-clouds. Optional for cloudy scenes) + if (clear_column .or. doSWclrsky) then + call check_error_msg('rrtmgp_sw_main_rte_sw_clrsky',rte_sw( & + sw_optical_props_accum, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + coszen(iCols), & ! IN - Cosine of solar zenith angle + toa_src_sw, & ! IN - incident solar flux at TOA + sfc_alb_dir, & ! IN - Shortwave surface albedo (direct) + sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse) + flux_clrsky)) ! OUT - Fluxes, clear-sky, 3D (1,nLay,nBand) + + ! Store fluxes + fluxswUP_clrsky(iCols,:) = sum(flux_clrsky%bnd_flux_up, dim=3) + fluxswDOWN_clrsky(iCols,:) = sum(flux_clrsky%bnd_flux_dn, dim=3) + + ! Compute surface downward beam/diffused flux components + do iblck = 1, rrtmgp_phys_blksz + do iBand=1,sw_gas_props%get_nband() + flux_dir = flux_clrsky%bnd_flux_dn(iblck,iSFC,iBand) + flux_dif = 0._kind_phys + ! Near-IR bands + if (iBand < ibd) then + scmpsw_clrsky(iblck)%nirbm = scmpsw_clrsky(iblck)%nirbm + flux_dir + scmpsw_clrsky(iblck)%nirdf = scmpsw_clrsky(iblck)%nirdf + flux_dif + endif + ! Transition band + if (iBand == ibd) then + scmpsw_clrsky(iblck)%nirbm = scmpsw_clrsky(iblck)%nirbm + flux_dir*0.5_kind_phys + scmpsw_clrsky(iblck)%nirdf = scmpsw_clrsky(iblck)%nirdf + flux_dif*0.5_kind_phys + scmpsw_clrsky(iblck)%visbm = scmpsw_clrsky(iblck)%visbm + flux_dir*0.5_kind_phys + scmpsw_clrsky(iblck)%visdf = scmpsw_clrsky(iblck)%visdf + flux_dif*0.5_kind_phys + endif + ! UV-VIS bands + if (iBand > ibd) then + scmpsw_clrsky(iblck)%visbm = scmpsw_clrsky(iblck)%visbm + flux_dir + scmpsw_clrsky(iblck)%visdf = scmpsw_clrsky(iblck)%visdf + flux_dif + endif + ! uv-b surface downward flux + scmpsw_clrsky(iblck)%uvbfc = flux_clrsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + enddo + enddo + else + fluxswUP_clrsky(iCols,:) = 0._kind_phys + fluxswDOWN_clrsky(iCols,:) = 0._kind_phys + scmpsw = cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) + endif + + ! ################################################################################### + ! + ! All-sky fluxes (clear-sky + clouds + precipitation) + ! + ! ################################################################################### + if (cloudy_column) then + ! Delta scale + !call check_error_msg('rrtmgp_sw_main_delta_scale',sw_optical_props_clouds%delta_scale()) + + ! Increment + call check_error_msg('rrtmgp_sw_main_increment_clouds_to_clrsky', & + sw_optical_props_clouds%increment(sw_optical_props_accum)) + + ! Compute fluxes + call check_error_msg('rrtmgp_sw_main_rte_sw_allsky',rte_sw( & + sw_optical_props_accum, & ! IN - optical-properties + top_at_1, & ! IN - veritcal ordering flag + coszen(iCols), & ! IN - Cosine of solar zenith angle + toa_src_sw, & ! IN - incident solar flux at TOA + sfc_alb_dir, & ! IN - Shortwave surface albedo (direct) + sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse) + flux_allsky)) ! OUT - Fluxes, clear-sky, 3D (1,nLay,nBand) + + ! Store fluxes + fluxswUP_allsky(iCols,:) = sum(flux_allsky%bnd_flux_up, dim=3) + fluxswDOWN_allsky(iCols,:) = sum(flux_allsky%bnd_flux_dn, dim=3) + + ! Compute and store downward beam/diffused flux components + do iblck = 1, rrtmgp_phys_blksz + ! Loop over bands, sum fluxes... + do iBand=1,sw_gas_props%get_nband() + flux_dir = flux_allsky%bnd_flux_dn_dir(iblck,iSFC,iBand) + flux_dif = flux_allsky%bnd_flux_dn(iblck,iSFC,iBand) - flux_allsky%bnd_flux_dn_dir(iblck,iSFC,iBand) + ! Near-IR bands + if (iBand < ibd) then + scmpsw_allsky(iblck)%nirbm = scmpsw_allsky(iblck)%nirbm + flux_dir + scmpsw_allsky(iblck)%nirdf = scmpsw_allsky(iblck)%nirdf + flux_dif + endif + ! Transition band + if (iBand == ibd) then + scmpsw_allsky(iblck)%nirbm = scmpsw_allsky(iblck)%nirbm + flux_dir*0.5_kind_phys + scmpsw_allsky(iblck)%nirdf = scmpsw_allsky(iblck)%nirdf + flux_dif*0.5_kind_phys + scmpsw_allsky(iblck)%visbm = scmpsw_allsky(iblck)%visbm + flux_dir*0.5_kind_phys + scmpsw_allsky(iblck)%visdf = scmpsw_allsky(iblck)%visdf + flux_dif*0.5_kind_phys + endif + ! UV-VIS bands + if (iBand > ibd) then + scmpsw_allsky(iblck)%visbm = scmpsw_allsky(iblck)%visbm + flux_dir + scmpsw_allsky(iblck)%visdf = scmpsw_allsky(iblck)%visdf + flux_dif + endif + ! uv-b surface downward flux + scmpsw_allsky(iblck)%uvbfc = flux_allsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + enddo + ! Store surface downward beam/diffused flux components + if (zcf1(iblck) .gt. eps) then + scmpsw(iCols(iblck))%nirbm = scmpsw_allsky(iblck)%nirbm + scmpsw(iCols(iblck))%nirdf = scmpsw_allsky(iblck)%nirdf + scmpsw(iCols(iblck))%visbm = scmpsw_allsky(iblck)%visbm + scmpsw(iCols(iblck))%visdf = scmpsw_allsky(iblck)%visdf + scmpsw(iCols(iblck))%uvbfc = flux_allsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + else + scmpsw(iCols(iblck))%nirbm = scmpsw_clrsky(iblck)%nirbm + scmpsw(iCols(iblck))%nirdf = scmpsw_clrsky(iblck)%nirdf + scmpsw(iCols(iblck))%visbm = scmpsw_clrsky(iblck)%visbm + scmpsw(iCols(iblck))%visdf = scmpsw_clrsky(iblck)%visdf + scmpsw(iCols(iblck))%uvbfc = flux_clrsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + endif + scmpsw(iCols(iblck))%uvbf0 = flux_clrsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + enddo + else ! No clouds + fluxswUP_allsky(iCols,:) = sum(flux_clrsky%bnd_flux_up, dim=3) + fluxswDOWN_allsky(iCols,:) = sum(flux_clrsky%bnd_flux_dn, dim=3) + do iblck = 1, rrtmgp_phys_blksz + scmpsw(iCols(iblck))%nirbm = scmpsw_clrsky(iblck)%nirbm + scmpsw(iCols(iblck))%nirdf = scmpsw_clrsky(iblck)%nirdf + scmpsw(iCols(iblck))%visbm = scmpsw_clrsky(iblck)%visbm + scmpsw(iCols(iblck))%visdf = scmpsw_clrsky(iblck)%visdf + scmpsw(iCols(iblck))%uvbfc = flux_clrsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + scmpsw(iCols(iblck))%uvbf0 = flux_clrsky%bnd_flux_dn(iblck,iSFC,ibd_uv) + enddo + endif + ! + enddo ! nday + else + fluxswUP_allsky(:,:) = 0._kind_phys + fluxswDOWN_allsky(:,:) = 0._kind_phys + fluxswUP_clrsky(:,:) = 0._kind_phys + fluxswDOWN_clrsky(:,:) = 0._kind_phys + scmpsw = cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) + endif + end subroutine rrtmgp_sw_main_run +end module rrtmgp_sw_main diff --git a/physics/rrtmgp_sw_main.meta b/physics/rrtmgp_sw_main.meta new file mode 100644 index 000000000..dbb93a5df --- /dev/null +++ b/physics/rrtmgp_sw_main.meta @@ -0,0 +1,664 @@ +[ccpp-table-properties] + name = rrtmgp_sw_main + type = scheme + dependencies = machine.F,radiation_tools.F90,GFS_rrtmgp_pre.F90,rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90 + dependencies = rte-rrtmgp/rte/mo_rte_kind.F90,rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90,rte-rrtmgp/rte/mo_optical_props.F90 + dependencies = rte-rrtmgp/rte/mo_rte_sw.F90,rte-rrtmgp/rte/mo_fluxes.F90 + dependencies = rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90, rte-rrtmgp/rte/kernels/mo_rte_solver_kernels.F90 + dependencies = mersenne_twister.f,rrtmgp_sampling.F90,rte-rrtmgp/extensions/mo_fluxes_byband.F90 + dependencies = rrtmgp_sw_gas_optics.F90, rrtmgp_sw_cloud_optics.F90 + +######################################################################## +[ccpp-arg-table] + name = rrtmgp_sw_main_init + type = scheme +[rrtmgp_root_dir] + standard_name = directory_for_rte_rrtmgp_source_code + long_name = directory for rte+rrtmgp source code + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[rrtmgp_sw_file_gas] + standard_name = filename_of_rrtmgp_shortwave_k_distribution + long_name = file containing RRTMGP SW k-distribution + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[rrtmgp_sw_file_clouds] + standard_name = filename_of_rrtmgp_shortwave_cloud_optics_coefficients + long_name = file containing coefficients for RRTMGP SW cloud optics + units = none + dimensions = () + type = character + intent = in + kind = len=128 +[doGP_cldoptics_PADE] + standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_PADE + long_name = logical flag to control cloud optics scheme. + units = flag + dimensions = () + type = logical + intent = in +[doGP_cldoptics_LUT] + standard_name = flag_to_calc_lw_cld_optics_using_RRTMGP_LUT + long_name = logical flag to control cloud optics scheme. + units = flag + dimensions = () + type = logical + intent = in +[nrghice] + standard_name = number_of_ice_roughness_categories + long_name = number of ice-roughness categories in RRTMGP calculation + units = count + dimensions = () + type = integer + intent = inout +[doGP_sgs_cnv] + standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP + long_name = logical flag to control sgs convective cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_pbl] + standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP + long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[rrtmgp_phys_blksz] + standard_name = number_of_columns_per_RRTMGP_SW_block + long_name = number of columns to process at a time by RRTMGP SW scheme + units = count + dimensions = () + type = integer + intent = in +[nLay] + standard_name = vertical_layer_dimension + long_name = number of vertical levels + units = count + dimensions = () + type = integer + intent = in +[mpirank] + standard_name = mpi_rank + long_name = current MPI rank + units = index + dimensions = () + type = integer + intent = in +[mpiroot] + standard_name = mpi_root + long_name = master MPI rank + units = index + dimensions = () + type = integer + intent = in +[mpicomm] + standard_name = mpi_communicator + long_name = MPI communicator + units = index + dimensions = () + type = integer + intent = in +[active_gases_array] + standard_name = list_of_active_gases_used_by_RRTMGP + long_name = list of active gases used by RRTMGP + units = none + dimensions = (number_of_active_gases_used_by_RRTMGP) + type = character + kind = len=* + intent = in +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out + +######################################################################## +[ccpp-arg-table] + name = rrtmgp_sw_main_run + type = scheme +[doSWrad] + standard_name = flag_for_calling_shortwave_radiation + long_name = logical flags for sw radiation calls + units = flag + dimensions = () + type = logical + intent = in +[doSWclrsky] + standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_shortwave_heating_on_radiation_timestep_assuming_clear_sky + long_name = flag to output sw heating rate (Radtend%swhc) + units = flag + dimensions = () + type = logical + intent = in +[top_at_1] + standard_name = flag_for_vertical_ordering_in_radiation + long_name = flag for vertical ordering in radiation + units = flag + dimensions = () + type = logical + intent = in +[iSFC] + standard_name = vertical_index_for_surface_in_RRTMGP + long_name = index for surface layer in RRTMGP + units = flag + dimensions = () + type = integer + intent = in +[doGP_sgs_cnv] + standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP + long_name = logical flag to control sgs convective cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[doGP_sgs_pbl] + standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP + long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in +[ncol] + standard_name = horizontal_loop_extent + long_name = horizontal dimension + units = count + dimensions = () + type = integer + intent = in +[nLay] + standard_name = vertical_layer_dimension + long_name = number of vertical levels + units = count + dimensions = () + type = integer + intent = in +[rrtmgp_phys_blksz] + standard_name = number_of_columns_per_RRTMGP_SW_block + long_name = number of columns to process at a time by RRTMGP SW scheme + units = count + dimensions = () + type = integer + intent = in +[nGases] + standard_name = number_of_active_gases_used_by_RRTMGP + long_name = number of gases available used by RRTMGP (Model%nGases) + units = count + dimensions = () + type = integer + intent = in +[nday] + standard_name = daytime_points_dimension + long_name = daytime points dimension + units = count + dimensions = () + type = integer + intent = in +[idx] + standard_name = daytime_points + long_name = daytime points + units = index + dimensions = (horizontal_loop_extent) + type = integer + intent = in +[coszen] + standard_name = cosine_of_solar_zenith_angle_for_daytime_points_on_radiation_timestep + long_name = mean cos of zenith angle over rad call period + units = none + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[isubc_sw] + standard_name = flag_for_sw_clouds_grid_approximation + long_name = flag for sw clouds sub-grid approximation + units = flag + dimensions = () + type = integer + intent = in +[iovr] + standard_name = flag_for_cloud_overlap_method_for_radiation + long_name = max-random overlap clouds + units = flag + dimensions = () + type = integer + intent = in +[iovr_maxrand] + standard_name = flag_for_maximum_random_cloud_overlap_method + long_name = choice of maximum-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_dcorr] + standard_name = flag_for_decorrelation_length_cloud_overlap_method + long_name = choice of decorrelation-length cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exp] + standard_name = flag_for_exponential_cloud_overlap_method + long_name = choice of exponential cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_exprand] + standard_name = flag_for_exponential_random_cloud_overlap_method + long_name = choice of exponential-random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_rand] + standard_name = flag_for_random_cloud_overlap_method + long_name = choice of random cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_max] + standard_name = flag_for_maximum_cloud_overlap_method + long_name = choice of maximum cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[iovr_convcld] + standard_name = flag_for_convective_cloud_overlap_method_for_radiation + long_name = flag for convective cloud overlap method + units = flag + dimensions = () + type = integer + intent = in +[icseed_sw] + standard_name = random_number_seed_for_mcica_shortwave + long_name = seed for random number generation for shortwave radiation + units = none + dimensions = (horizontal_loop_extent) + type = integer + intent = in +[p_lay] + standard_name = air_pressure_at_layer_for_RRTMGP + long_name = air pressure at vertical layer for radiation calculation + units = Pa + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[p_lev] + standard_name = air_pressure_at_interface_for_RRTMGP + long_name = air pressure at vertical interface for radiation calculation + units = Pa + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[t_lay] + standard_name = air_temperature_at_layer_for_RRTMGP + long_name = air temperature at vertical layer for radiation calculation + units = K + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[t_lev] + standard_name = air_temperature_at_interface_for_RRTMGP + long_name = air temperature at vertical interface for radiation calculation + units = K + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[vmr_o2] + standard_name = volume_mixing_ratio_for_o2 + long_name = molar mixing ratio of o2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_h2o] + standard_name = volume_mixing_ratio_for_h2o + long_name = molar mixing ratio of h2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_o3] + standard_name = volume_mixing_ratio_for_o3 + long_name = molar mixing ratio of o3 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_ch4] + standard_name = volume_mixing_ratio_for_ch4 + long_name = molar mixing ratio of ch4 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_n2o] + standard_name = volume_mixing_ratio_for_n2o + long_name = molar mixing ratio of n2o in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[vmr_co2] + standard_name = volume_mixing_ratio_for_co2 + long_name = molar mixing ratio of co2 in with respect to dry air + units = 1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_frac] + standard_name = total_cloud_fraction + long_name = layer total cloud fraction + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_lwp] + standard_name = cloud_liquid_water_path + long_name = layer cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_reliq] + standard_name = mean_effective_radius_for_liquid_cloud + long_name = mean effective radius for liquid cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_iwp] + standard_name = cloud_ice_water_path + long_name = layer cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_reice] + standard_name = mean_effective_radius_for_ice_cloud + long_name = mean effective radius for ice cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_swp] + standard_name = cloud_snow_water_path + long_name = layer cloud snow water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_resnow] + standard_name = mean_effective_radius_for_snow_flake + long_name = mean effective radius for snow cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_rwp] + standard_name = cloud_rain_water_path + long_name = layer cloud rain water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_rerain] + standard_name = mean_effective_radius_for_rain_drop + long_name = mean effective radius for rain cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[precip_frac] + standard_name = precipitation_fraction_by_layer + long_name = precipitation fraction in each layer + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_lwp] + standard_name = convective_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_iwp] + standard_name = convective_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reliq] + standard_name = mean_effective_radius_for_liquid_convective_cloud + long_name = mean effective radius for liquid convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_cnv_reice] + standard_name = mean_effective_radius_for_ice_convective_cloud + long_name = mean effective radius for ice convective cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_lwp] + standard_name = MYNN_SGS_cloud_liquid_water_path + long_name = layer convective cloud liquid water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_iwp] + standard_name = MYNN_SGS_cloud_ice_water_path + long_name = layer convective cloud ice water path + units = g m-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reliq] + standard_name = mean_effective_radius_for_liquid_MYNN_SGS_cloud + long_name = mean effective radius for liquid MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cld_pbl_reice] + standard_name = mean_effective_radius_for_ice_MYNN_SGS_cloud + long_name = mean effective radius for ice MYNN_SGS cloud + units = um + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[cloud_overlap_param] + standard_name = cloud_overlap_param + long_name = cloud overlap parameter + units = km + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[sfc_alb_nir_dir] + standard_name = surface_albedo_due_to_near_IR_direct + long_name = surface albedo due to near IR direct beam + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[sfc_alb_nir_dif] + standard_name = surface_albedo_due_to_near_IR_diffused + long_name = surface albedo due to near IR diffused beam + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[sfc_alb_uvvis_dir] + standard_name = surface_albedo_due_to_UV_and_VIS_direct + long_name = surface albedo due to UV+VIS direct beam + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[sfc_alb_uvvis_dif] + standard_name = surface_albedo_due_to_UV_and_VIS_diffused + long_name = surface albedo due to UV+VIS diffused beam + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[active_gases_array] + standard_name = list_of_active_gases_used_by_RRTMGP + long_name = list of active gases used by RRTMGP + units = none + dimensions = (number_of_active_gases_used_by_RRTMGP) + type = character + kind = len=* + intent = in +[aersw_tau] + standard_name = aerosol_optical_depth_for_shortwave_bands_01_16 + long_name = aerosol optical depth for shortwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = in +[aersw_ssa] + standard_name = aerosol_single_scattering_albedo_for_shortwave_bands_01_16 + long_name = aerosol single scattering albedo for shortwave bands 01-16 + units = frac + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = in +[aersw_g] + standard_name = aerosol_asymmetry_parameter_for_shortwave_bands_01_16 + long_name = aerosol asymmetry parameter for shortwave bands 01-16 + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_aerosol_bands_for_shortwave_radiation) + type = real + kind = kind_phys + intent = in +[solcon] + standard_name = solar_constant + long_name = solar constant + units = W m-2 + dimensions = () + type = real + kind = kind_phys + intent = in +[scmpsw] + standard_name = components_of_surface_downward_shortwave_fluxes + long_name = derived type for special components of surface downward shortwave fluxes + units = W m-2 + dimensions = (horizontal_loop_extent) + type = cmpfsw_type + intent = inout +[fluxswUP_allsky] + standard_name = RRTMGP_sw_flux_profile_upward_allsky + long_name = RRTMGP upward shortwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxswDOWN_allsky] + standard_name = RRTMGP_sw_flux_profile_downward_allsky + long_name = RRTMGP downward shortwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxswUP_clrsky] + standard_name = RRTMGP_sw_flux_profile_upward_clrsky + long_name = RRTMGP upward shortwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[fluxswDOWN_clrsky] + standard_name = RRTMGP_sw_flux_profile_downward_clrsky + long_name = RRTMGP downward shortwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_loop_extent,vertical_interface_dimension) + type = real + kind = kind_phys + intent = inout +[cldtausw] + standard_name = cloud_optical_depth_layers_at_0p55mu_band + long_name = approx .55mu band layer cloud optical depth + units = none + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out diff --git a/physics/rrtmgp_sw_rte.F90 b/physics/rrtmgp_sw_rte.F90 deleted file mode 100644 index 521aae2c1..000000000 --- a/physics/rrtmgp_sw_rte.F90 +++ /dev/null @@ -1,219 +0,0 @@ -!> \file rrtmgp_sw_rte.F90 -!! -!> \defgroup rrtmgp_sw_rte rrtmgp_sw_rte.F90 -!! -!! \brief This module contains the main rte shortwave driver. -module rrtmgp_sw_rte - use machine, only: kind_phys - use mo_optical_props, only: ty_optical_props_2str - use mo_rte_sw, only: rte_sw - use mo_fluxes_byband, only: ty_fluxes_byband - use module_radsw_parameters, only: cmpfsw_type - use radiation_tools, only: check_error_msg - use rrtmgp_sw_gas_optics, only: sw_gas_props - implicit none - - public rrtmgp_sw_rte_run - -contains -!>\defgroup rrtmgp_sw_rte_mod GFS RRTMGP-SW RTE Module -!> \section arg_table_rrtmgp_sw_rte_run -!! \htmlinclude rrtmgp_sw_rte.html -!! -!> \ingroup rrtmgp_sw_rte -!! -!! \brief This routine takes all of the shortwave optical properties ,ty_optical_props_2str, -!! and computes the shortwave radiative fluxes for cloudy and clear-sky conditions. -!! -!! \section rrtmgp_sw_rte_run Main Driver -!> @{ - ! ###################################################################################### - subroutine rrtmgp_sw_rte_run(doSWrad, doSWclrsky, nCol, nLev, nDay, idxday, coszen, p_lay,& - t_lay, top_at_1, doGP_sgs_cnv, doGP_sgs_mynn, iSFC, sfc_alb_nir_dir, sfc_alb_nir_dif,& - sfc_alb_uvvis_dir, sfc_alb_uvvis_dif, toa_src_sw, sw_optical_props_clrsky, & - sw_optical_props_clouds, sw_optical_props_precipByBand, & - sw_optical_props_cnvcloudsByBand, sw_optical_props_MYNNcloudsByBand, & - sw_optical_props_aerosol, scmpsw, fluxswUP_allsky, fluxswDOWN_allsky, & - fluxswUP_clrsky, fluxswDOWN_clrsky, errmsg, errflg) - - ! Inputs - logical, intent(in) :: & - top_at_1, & ! Vertical ordering flag - doGP_sgs_mynn, & ! Flag for MYNN-EDMF PBL cloud scheme - doGP_sgs_cnv, & ! Flag for sgs convective clouds scheme - doSWrad, & ! Flag to calculate SW irradiances - doSWclrsky ! Compute clear-sky fluxes? - integer, intent(in) :: & - nCol, & ! Number of horizontal gridpoints - nday, & ! Number of daytime points - nLev, & ! Number of vertical levels - iSFC ! Vertical index for surface-level - integer, intent(in), dimension(:) :: & - idxday ! Index array for daytime points - real(kind_phys),intent(in), dimension(:) :: & - sfc_alb_nir_dir, & ! Surface albedo (direct) - sfc_alb_nir_dif, & ! Surface albedo (diffuse) - sfc_alb_uvvis_dir, & ! Surface albedo (direct) - sfc_alb_uvvis_dif, & ! Surface albedo (diffuse) - coszen ! Cosize of SZA - real(kind_phys), dimension(:,:), intent(in) :: & - p_lay, & ! Pressure @ model layer-centers (Pa) - t_lay, & ! Temperature (K) - toa_src_sw ! TOA incident spectral flux (W/m2) - type(ty_optical_props_2str),intent(inout) :: & - sw_optical_props_clrsky ! RRTMGP DDT: shortwave clear-sky radiative properties - type(ty_optical_props_2str),intent(in) :: & - sw_optical_props_clouds, & ! RRTMGP DDT: shortwave cloud optical properties - sw_optical_props_cnvcloudsByBand, & ! RRTMGP DDT: shortwave convecive cloud optical properties - sw_optical_props_MYNNcloudsByBand, & ! RRTMGP DDT: shortwave MYNN-EDMF PBL cloud optical properties - sw_optical_props_precipByBand, & ! RRTMGP DDT: shortwave precipitation optical properties - sw_optical_props_aerosol ! RRTMGP DDT: shortwave aerosol optical properties - - ! Outputs - character(len=*), intent(out) :: & - errmsg ! CCPP error message - integer, intent(out) :: & - errflg ! CCPP error flag - real(kind_phys), dimension(:,:), intent(inout) :: & - fluxswUP_allsky, & ! RRTMGP upward all-sky flux profiles (W/m2) - fluxswDOWN_allsky, & ! RRTMGP downward all-sky flux profiles (W/m2) - fluxswUP_clrsky, & ! RRTMGP upward clear-sky flux profiles (W/m2) - fluxswDOWN_clrsky ! RRTMGP downward clear-sky flux profiles (W/m2) - type(cmpfsw_type), dimension(:), intent(inout) :: & - scmpsw ! 2D surface fluxes, components: - ! uvbfc - total sky downward uv-b flux (W/m2) - ! uvbf0 - clear sky downward uv-b flux (W/m2) - ! nirbm - downward nir direct beam flux (W/m2) - ! nirdf - downward nir diffused flux (W/m2) - ! visbm - downward uv+vis direct beam flux (W/m2) - ! visdf - downward uv+vis diffused flux (W/m2) - - ! Local variables - real(kind_phys), dimension(sw_gas_props%get_nband(),nday) :: & - sfc_alb_dir,sfc_alb_dif - type(ty_fluxes_byband) :: & - flux_allsky, & ! All-sky flux (W/m2) - flux_clrsky ! Clear-sky flux (W/m2) - real(kind_phys), dimension(nday,NLev+1,sw_gas_props%get_nband()),target :: & - fluxSW_up_allsky, fluxSW_up_clrsky, fluxSW_dn_allsky, fluxSW_dn_clrsky, fluxSW_dn_dir_allsky - real(kind_phys), dimension(ncol,NLev) :: vmrTemp - integer :: iBand, iDay,ibd - real(kind_phys), dimension(2,sw_gas_props%get_nband()) :: bandlimits - real(kind_phys), dimension(2), parameter :: nIR_uvvis_bnd = (/12850,16000/) - - ! Initialize CCPP error handling variables - errmsg = '' - errflg = 0 - - if (.not. doSWrad) return - - if (nDay .gt. 0) then - - ! Initialize RRTMGP DDT containing 2D(3D) fluxes - flux_allsky%bnd_flux_up => fluxSW_up_allsky - flux_allsky%bnd_flux_dn => fluxSW_dn_allsky - flux_allsky%bnd_flux_dn_dir => fluxSW_dn_dir_allsky - flux_clrsky%bnd_flux_up => fluxSW_up_clrsky - flux_clrsky%bnd_flux_dn => fluxSW_dn_clrsky - - ! Use near-IR albedo for bands with wavenumbers extending to 12850cm-1 - ! Use uv-vis albedo for bands with wavenumbers greater than 16000cm-1 - ! For overlapping band, average near-IR and us-vis albedos. - bandlimits = sw_gas_props%get_band_lims_wavenumber() - do iBand=1,sw_gas_props%get_nband() - if (bandlimits(1,iBand) .lt. nIR_uvvis_bnd(1)) then - sfc_alb_dir(iBand,:) = sfc_alb_nir_dir(idxday(1:nday)) - sfc_alb_dif(iBand,:) = sfc_alb_nir_dif(idxday(1:nday)) - endif - if (bandlimits(1,iBand) .eq. nIR_uvvis_bnd(1)) then - sfc_alb_dir(iBand,:) = 0.5_kind_phys*(sfc_alb_nir_dir(idxday(1:nday)) + sfc_alb_uvvis_dir(idxday(1:nday))) - sfc_alb_dif(iBand,:) = 0.5_kind_phys*(sfc_alb_nir_dif(idxday(1:nday)) + sfc_alb_uvvis_dif(idxday(1:nday))) - ibd = iBand - endif - if (bandlimits(1,iBand) .ge. nIR_uvvis_bnd(2)) then - sfc_alb_dir(iBand,:) = sfc_alb_uvvis_dir(idxday(1:nday)) - sfc_alb_dif(iBand,:) = sfc_alb_uvvis_dif(idxday(1:nday)) - endif - enddo - - ! - ! Compute clear-sky fluxes (if requested) - ! - - ! Clear-sky fluxes (gas+aerosol) - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_aerosol%increment(sw_optical_props_clrsky)) - ! Delta-scale optical properties - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_clrsky%delta_scale()) - if (doSWclrsky) then - call check_error_msg('rrtmgp_sw_rte_run',rte_sw( & - sw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - coszen(idxday(1:nday)), & ! IN - Cosine of solar zenith angle - toa_src_sw(idxday(1:nday),:), & ! IN - incident solar flux at TOA - sfc_alb_dir, & ! IN - Shortwave surface albedo (direct) - sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse) - flux_clrsky)) ! OUT - Fluxes, clear-sky, 3D (nCol,NLev,nBand) - ! Store fluxes - fluxswUP_clrsky(idxday(1:nday),:) = sum(flux_clrsky%bnd_flux_up,dim=3) - fluxswDOWN_clrsky(idxday(1:nday),:) = sum(flux_clrsky%bnd_flux_dn,dim=3) - endif - - ! - ! Compute all-sky fluxes - ! - - ! Include convective cloud? - if (doGP_sgs_cnv) then - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_cnvcloudsByBand%increment(sw_optical_props_clrsky)) - endif - - ! Include MYNN-EDMF PBL cloud? - if (doGP_sgs_mynn) then - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_MYNNcloudsByBand%increment(sw_optical_props_clrsky)) - endif - - ! All-sky fluxes (clear-sky + clouds + precipitation) - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_precipByBand%increment(sw_optical_props_clrsky)) - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_clouds%increment(sw_optical_props_clrsky)) - - ! Delta-scale optical properties - call check_error_msg('rrtmgp_sw_rte_run',sw_optical_props_clrsky%delta_scale()) - call check_error_msg('rrtmgp_sw_rte_run',rte_sw( & - sw_optical_props_clrsky, & ! IN - optical-properties - top_at_1, & ! IN - veritcal ordering flag - coszen(idxday(1:nday)), & ! IN - Cosine of solar zenith angle - toa_src_sw(idxday(1:nday),:), & ! IN - incident solar flux at TOA - sfc_alb_dir, & ! IN - Shortwave surface albedo (direct) - sfc_alb_dif, & ! IN - Shortwave surface albedo (diffuse) - flux_allsky)) ! OUT - Fluxes, clear-sky, 3D (nCol,NLev,nBand) - - ! Store fluxes - fluxswUP_allsky(idxday(1:nday),:) = sum(flux_allsky%bnd_flux_up,dim=3) - fluxswDOWN_allsky(idxday(1:nday),:) = sum(flux_allsky%bnd_flux_dn,dim=3) - do iDay=1,nDay - ! Near IR - scmpsw(idxday(iDay))%nirbm = sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,1:ibd-1)) + & - flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2. - scmpsw(idxday(iDay))%nirdf = (sum(flux_allsky%bnd_flux_dn(iDay,iSFC,1:ibd-1)) + & - flux_allsky%bnd_flux_dn(iDay,iSFC,ibd)/2.) - & - (sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,1:ibd-1)) + & - flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2.) - ! UV-VIS - scmpsw(idxday(iDay))%visbm = sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd+1:sw_gas_props%get_nband())) + & - flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2. - scmpsw(idxday(iDay))%visdf = (sum(flux_allsky%bnd_flux_dn(iDay,iSFC,ibd+1:sw_gas_props%get_nband())) + & - flux_allsky%bnd_flux_dn(iDay,iSFC,ibd)/2. ) - & - (sum(flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd+1:sw_gas_props%get_nband())) + & - flux_allsky%bnd_flux_dn_dir(iDay,iSFC,ibd)/2.) - enddo - else - fluxswUP_allsky(:,:) = 0._kind_phys - fluxswDOWN_allsky(:,:) = 0._kind_phys - fluxswUP_clrsky(:,:) = 0._kind_phys - fluxswDOWN_clrsky(:,:) = 0._kind_phys - scmpsw = cmpfsw_type( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) - endif - - end subroutine rrtmgp_sw_rte_run -!> @} -end module rrtmgp_sw_rte diff --git a/physics/rrtmgp_sw_rte.meta b/physics/rrtmgp_sw_rte.meta deleted file mode 100644 index 9ab24c8b3..000000000 --- a/physics/rrtmgp_sw_rte.meta +++ /dev/null @@ -1,240 +0,0 @@ -[ccpp-table-properties] - name = rrtmgp_sw_rte - type = scheme - dependencies = machine.F,radsw_param.f,rte-rrtmgp/rte/mo_rte_sw.F90,rte-rrtmgp/rte/mo_fluxes.F90,rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90,radiation_tools.F90 - dependencies = rte-rrtmgp/rte/kernels/mo_rte_solver_kernels.F90,rte-rrtmgp/extensions/mo_fluxes_byband.F90 - -######################################################################## -[ccpp-arg-table] - name = rrtmgp_sw_rte_run - type = scheme -[doSWrad] - standard_name = flag_for_calling_shortwave_radiation - long_name = flag to calculate SW irradiances - units = flag - dimensions = () - type = logical - intent = in -[doSWclrsky] - standard_name = flag_for_output_of_tendency_of_air_temperature_due_to_shortwave_heating_on_radiation_timestep_assuming_clear_sky - long_name = flag to output sw heating rate (Radtend%swhc) - units = flag - dimensions = () - type = logical - intent = in -[ncol] - standard_name = horizontal_loop_extent - long_name = horizontal dimension - units = count - dimensions = () - type = integer - intent = in -[nLev] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[nday] - standard_name = daytime_points_dimension - long_name = daytime points dimension - units = count - dimensions = () - type = integer - intent = in -[idxday] - standard_name = daytime_points - long_name = daytime points - units = index - dimensions = (horizontal_loop_extent) - type = integer - intent = in -[coszen] - standard_name = cosine_of_solar_zenith_angle_for_daytime_points_on_radiation_timestep - long_name = mean cos of zenith angle over rad call period - units = none - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[p_lay] - standard_name = air_pressure_at_layer_for_RRTMGP - long_name = air pressure layer - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[top_at_1] - standard_name = flag_for_vertical_ordering_in_RRTMGP - long_name = flag for vertical ordering in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[doGP_sgs_cnv] - standard_name = flag_to_include_sgs_convective_cloud_in_RRTMGP - long_name = logical flag to control sgs convective cloud in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[doGP_sgs_mynn] - standard_name = flag_to_include_sgs_MYNN_EDMF_cloud_in_RRTMGP - long_name = logical flag to control MYNN-EDMF PBL cloud in RRTMGP - units = flag - dimensions = () - type = logical - intent = in -[iSFC] - standard_name = vertical_index_for_surface_in_RRTMGP - long_name = index for surface layer in RRTMGP - units = flag - dimensions = () - type = integer - intent = in -[t_lay] - standard_name = air_temperature_at_layer_for_RRTMGP - long_name = air temperature layer - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[sw_optical_props_clrsky] - standard_name = shortwave_optical_properties_for_clear_sky - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = inout -[sw_optical_props_clouds] - standard_name = shortwave_optical_properties_for_cloudy_atmosphere - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_precipByBand] - standard_name = shortwave_optical_properties_for_precipitation_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_cnvcloudsByBand] - standard_name = shortwave_optical_properties_for_convective_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_MYNNcloudsByBand] - standard_name = shortwave_optical_properties_for_MYNN_EDMF_PBL_cloudy_atmosphere_by_band - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sw_optical_props_aerosol] - standard_name = shortwave_optical_properties_for_aerosols - long_name = Fortran DDT containing RRTMGP optical properties - units = DDT - dimensions = () - type = ty_optical_props_2str - intent = in -[sfc_alb_nir_dir] - standard_name = surface_albedo_due_to_near_IR_direct - long_name = surface albedo due to near IR direct beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_nir_dif] - standard_name = surface_albedo_due_to_near_IR_diffused - long_name = surface albedo due to near IR diffused beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_uvvis_dir] - standard_name = surface_albedo_due_to_UV_and_VIS_direct - long_name = surface albedo due to UV+VIS direct beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[sfc_alb_uvvis_dif] - standard_name = surface_albedo_due_to_UV_and_VIS_diffused - long_name = surface albedo due to UV+VIS diffused beam - units = frac - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[toa_src_sw] - standard_name = toa_incident_sw_flux_by_spectral_point - long_name = TOA shortwave incident flux at each spectral points - units = W m-2 - dimensions = (horizontal_loop_extent,number_of_shortwave_spectral_points) - type = real - kind = kind_phys - intent = in -[scmpsw] - standard_name = components_of_surface_downward_shortwave_fluxes - long_name = derived type for special components of surface downward shortwave fluxes - units = W m-2 - dimensions = (horizontal_loop_extent) - type = cmpfsw_type - intent = inout -[fluxswUP_allsky] - standard_name = RRTMGP_sw_flux_profile_upward_allsky - long_name = RRTMGP upward shortwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxswDOWN_allsky] - standard_name = RRTMGP_sw_flux_profile_downward_allsky - long_name = RRTMGP downward shortwave all-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxswUP_clrsky] - standard_name = RRTMGP_sw_flux_profile_upward_clrsky - long_name = RRTMGP upward shortwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[fluxswDOWN_clrsky] - standard_name = RRTMGP_sw_flux_profile_downward_clrsky - long_name = RRTMGP downward shortwave clr-sky flux profile - units = W m-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = inout -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out diff --git a/physics/rte-rrtmgp b/physics/rte-rrtmgp index 7f01618c9..0dc54f5ec 160000 --- a/physics/rte-rrtmgp +++ b/physics/rte-rrtmgp @@ -1 +1 @@ -Subproject commit 7f01618c92409658bddd3afa9acb004c608f6a0d +Subproject commit 0dc54f5ecaeb1e1e342efd1e02d0bcd41737bde2 diff --git a/physics/samfdeepcnv.f b/physics/samfdeepcnv.f index 4ba887353..2a3c256a9 100644 --- a/physics/samfdeepcnv.f +++ b/physics/samfdeepcnv.f @@ -238,7 +238,7 @@ subroutine samfdeepcnv_run (im,km,first_time_step,restart, & ! parameter(cinacrmx=-120.,cinacrmn=-120.) parameter(cinacrmx=-120.,cinacrmn=-80.) parameter(bet1=1.875,cd1=.506,f1=2.0,gam1=.5) - parameter(betaw=.03,dxcrtuf=15.e3) + parameter(betaw=.03) ! ! local variables and arrays @@ -2468,8 +2468,10 @@ subroutine samfdeepcnv_run (im,km,first_time_step,restart, & ! if(progsigma)then dxcrtas=30.e3 + dxcrtuf=10.e3 else dxcrtas=8.e3 + dxcrtuf=15.e3 endif @@ -3519,9 +3521,13 @@ subroutine samfdeepcnv_run (im,km,first_time_step,restart, & if(k > kb(i) .and. k < ktop(i)) then tem = 0.5 * (eta(i,k-1) + eta(i,k)) * xmb(i) tem1 = pfld(i,k) * 100. / (rd * t1(i,k)) - sigmagfm(i) = max(sigmagfm(i), betaw) - ptem = tem / (sigmagfm(i) * tem1) - qtr(i,k,ntk)=qtr(i,k,ntk)+0.5*sigmagfm(i)*ptem*ptem + if(progsigma)then + tem2 = sigmab(i) + else + tem2 = max(sigmagfm(i), betaw) + endif + ptem = tem / (tem2 * tem1) + qtr(i,k,ntk)=qtr(i,k,ntk)+0.5*tem2*ptem*ptem endif endif enddo @@ -3533,9 +3539,13 @@ subroutine samfdeepcnv_run (im,km,first_time_step,restart, & if(k > 1 .and. k <= jmin(i)) then tem = 0.5*edto(i)*(etad(i,k-1)+etad(i,k))*xmb(i) tem1 = pfld(i,k) * 100. / (rd * t1(i,k)) - sigmagfm(i) = max(sigmagfm(i), betaw) - ptem = tem / (sigmagfm(i) * tem1) - qtr(i,k,ntk)=qtr(i,k,ntk)+0.5*sigmagfm(i)*ptem*ptem + if(progsigma)then + tem2 = sigmab(i) + else + tem2 = max(sigmagfm(i), betaw) + endif + ptem = tem / (tem2 * tem1) + qtr(i,k,ntk)=qtr(i,k,ntk)+0.5*tem2*ptem*ptem endif endif enddo diff --git a/physics/samfshalcnv.f b/physics/samfshalcnv.f index 1b648c109..645024536 100644 --- a/physics/samfshalcnv.f +++ b/physics/samfshalcnv.f @@ -188,7 +188,7 @@ subroutine samfshalcnv_run(im,km,itc,ntc,cliq,cp,cvap, & parameter(cinacrmx=-120.,shevf=2.0) parameter(dtmax=10800.,dtmin=600.) parameter(bet1=1.875,cd1=.506,f1=2.0,gam1=.5) - parameter(betaw=.03,dxcrt=15.e3,dxcrtc0=9.e3) + parameter(betaw=.03,dxcrtc0=9.e3) parameter(h1=0.33333333) ! progsigma parameter(dxcrtas=30.e3) @@ -258,6 +258,12 @@ subroutine samfshalcnv_run(im,km,itc,ntc,cliq,cp,cvap, & cinacrmn=-80. endif + if (progsigma) then + dxcrt=10.e3 + else + dxcrt=15.e3 + endif + c----------------------------------------------------------------------- if (.not.hwrf_samfshal) then !> ## Determine whether to perform aerosol transport @@ -2449,9 +2455,13 @@ subroutine samfshalcnv_run(im,km,itc,ntc,cliq,cp,cvap, & if(k > kb(i) .and. k < ktop(i)) then tem = 0.5 * (eta(i,k-1) + eta(i,k)) * xmb(i) tem1 = pfld(i,k) * 100. / (rd * t1(i,k)) - sigmagfm(i) = max(sigmagfm(i), betaw) - ptem = tem / (sigmagfm(i) * tem1) - qtr(i,k,ntk)=qtr(i,k,ntk)+0.5*sigmagfm(i)*ptem*ptem + if(progsigma)then + tem2 = sigmab(i) + else + tem2 = max(sigmagfm(i), betaw) + endif + ptem = tem / (tem2 * tem1) + qtr(i,k,ntk)=qtr(i,k,ntk)+0.5*tem2*ptem*ptem endif endif enddo diff --git a/physics/satmedmfvdifq.F b/physics/satmedmfvdifq.F index 1c524b800..08876f8f0 100644 --- a/physics/satmedmfvdifq.F +++ b/physics/satmedmfvdifq.F @@ -20,6 +20,12 @@ module satmedmfvdifq !! Updated version of satmedmfvdif.f (May 2019) to have better low level !! inversion, to reduce the cold bias in lower troposphere, !! and to reduce the negative wind speed bias in upper troposphere +!! +!! Incorporate the LES-based changes for TC simulation +!! (Chen et al.,2022, https://doi.org/10.1175/WAF-D-21-0168.1) +!! with additional improvements on MF working with Cu schemes +!! Xiaomin Chen, 5/2/2022 +!! !> \section arg_table_satmedmfvdifq_init Argument Table !! \htmlinclude satmedmfvdifq_init.html !! @@ -75,7 +81,7 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & & prsi,del,prsl,prslk,phii,phil,delt, & & dspheat,dusfc,dvsfc,dtsfc,dqsfc,hpbl,dkt,dku, & & kinver,xkzm_m,xkzm_h,xkzm_s,dspfac,bl_upfr,bl_dnfr, & - & rlmx,elmx,sfc_rlm, & + & rlmx,elmx,sfc_rlm,tc_pbl, & & ntqv,dtend,dtidx,index_of_temperature,index_of_x_wind, & & index_of_y_wind,index_of_process_pbl,gen_tend,ldiag3d, & & errmsg,errflg) @@ -89,6 +95,7 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & integer, intent(in) :: im, km, ntrac, ntcw, ntrw, ntiw, & & ntke, ntqv integer, intent(in) :: sfc_rlm + integer, intent(in) :: tc_pbl integer, intent(in) :: kinver(:) integer, intent(out) :: kpbl(:) logical, intent(in) :: gen_tend,ldiag3d,progsigma @@ -242,7 +249,10 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & real(kind=kind_phys) qlcr, zstblmax, hcrinv ! real(kind=kind_phys) h1 + + real(kind=kind_phys) bfac, mffac !! + parameter(bfac=100.) parameter(wfac=7.0,cfac=4.5) parameter(gamcrt=3.,gamcrq=0.,sfcfrac=0.1) parameter(vk=0.4,rimin=-100.,slfac=0.1) @@ -259,10 +269,19 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & parameter(qlcr=3.5e-5,zstblmax=2500.) parameter(xkinv1=0.15,xkinv2=0.3) parameter(h1=0.33333333,hcrinv=250.) - parameter(ck0=0.4,ck1=0.15,ch0=0.4,ch1=0.15) - parameter(ce0=0.4,cs0=0.2) + parameter(ck1=0.15,ch1=0.15) + parameter(cs0=0.2) parameter(rchck=1.5,ndt=20) + if (tc_pbl == 0) then + ck0 = 0.4 + ch0 = 0.4 + ce0 = 0.4 + else if (tc_pbl == 1) then + ck0 = 0.55 + ch0 = 0.55 + ce0 = 0.12 + endif gravi = 1.0 / grav g = grav gocp = g / cp @@ -600,11 +619,18 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & do i = 1, im if(.not.flg(i)) then rbdn(i) = rbup(i) - spdk2 = max((u1(i,k)**2+v1(i,k)**2),1.) -! rbup(i) = (thvx(i,k)-thermal(i))* -! & (g*zl(i,k)/thvx(i,1))/spdk2 - rbup(i) = (thlvx(i,k)-thermal(i))* - & (g*zl(i,k)/thlvx(i,1))/spdk2 + if (tc_pbl == 0) then + spdk2 = max((u1(i,k)**2+v1(i,k)**2),1.) +! rbup(i) = (thvx(i,k)-thermal(i))* +! & (g*zl(i,k)/thvx(i,1))/spdk2 + rbup(i) = (thlvx(i,k)-thermal(i))* + & (g*zl(i,k)/thlvx(i,1))/spdk2 + else if (tc_pbl == 1) then + spdk2 = max((u1(i,k)-u1(i,1))**2+(v1(i,k)-v1(i,1))**2,1.) + & + bfac*ustar(i)**2 + rbup(i) = (thlvx(i,k)-thermal(i))* + & (g*(zl(i,k)-zl(i,1))/thlvx(i,1))/spdk2 + endif kpblx(i) = k flg(i) = rbup(i) > crb(i) endif @@ -674,11 +700,18 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & do i = 1, im if(.not.flg(i) .and. k > kb1(i)) then rbdn(i) = rbup(i) - spdk2 = max((u1(i,k)**2+v1(i,k)**2),1.) -! rbup(i) = (thvx(i,k)-thermal(i))* -! & (g*zl(i,k)/thvx(i,1))/spdk2 - rbup(i) = (thlvx(i,k)-thermal(i))* - & (g*zl(i,k)/thlvx(i,1))/spdk2 + if (tc_pbl == 0) then + spdk2 = max((u1(i,k)**2+v1(i,k)**2),1.) +! rbup(i) = (thvx(i,k)-thermal(i))* +! & (g*zl(i,k)/thvx(i,1))/spdk2 + rbup(i) = (thlvx(i,k)-thermal(i))* + & (g*zl(i,k)/thlvx(i,1))/spdk2 + else if (tc_pbl == 1) then + spdk2 = max((u1(i,k)-u1(i,1))**2+(v1(i,k)-v1(i,1))**2,1.) + & + bfac*ustar(i)**2 + rbup(i) = (thlvx(i,k)-thermal(i))* + & (g*(zl(i,k)-zl(i,1))/thlvx(i,1))/spdk2 + endif kpblx(i) = k flg(i) = rbup(i) > crb(i) endif @@ -796,9 +829,16 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & do i = 1, im if(.not.flg(i) .and. k > kb1(i)) then rbdn(i) = rbup(i) - spdk2 = max((u1(i,k)**2+v1(i,k)**2),1.) - rbup(i) = (thlvx(i,k)-thermal(i))* - & (g*zl(i,k)/thlvx(i,1))/spdk2 + if (tc_pbl == 0) then + spdk2 = max((u1(i,k)**2+v1(i,k)**2),1.) + rbup(i) = (thlvx(i,k)-thermal(i))* + & (g*zl(i,k)/thlvx(i,1))/spdk2 + else if (tc_pbl == 1) then + spdk2 = max((u1(i,k)-u1(i,1))**2+(v1(i,k)-v1(i,1))**2,1.) + & + bfac*ustar(i)**2 + rbup(i) = (thlvx(i,k)-thermal(i))* + & (g*(zl(i,k)-zl(i,1))/thlvx(i,1))/spdk2 + endif kpbl(i) = k flg(i) = rbup(i) > crb(i) endif @@ -929,6 +969,26 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & & thlx,thvx,thlvx,gdx,thetae, & krad,mrad,radmin,buod,xmfd, & tcdo,qcdo,ucdo,vcdo,xlamde,bl_dnfr) + + if (tc_pbl == 1) then +!> - unify mass fluxes with Cu + do i=1,im + if(zol(i) > -0.5) then + do k = 1, km + xmf(i,k) = 0.0 + end do + end if + end do +!> - taper off MF in high-wind conditions + do i = 1,im + tem = sqrt(u10m(i)**2+v10m(i)**2) + mffac = (1. - MIN(MAX(tem - 20.0, 0.0), 10.0)/10.) + do k = 1, km + xmf(i,k) = xmf(i,k)*mffac + xmfd(i,k) = xmfd(i,k)*mffac + enddo + enddo + endif ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -1013,10 +1073,15 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & tem3=((u1(i,n+1)-u1(i,n))/dz)**2 tem3=tem3+((v1(i,n+1)-v1(i,n))/dz)**2 tem3=cs0*sqrt(tem3)*sqrt(tke(i,k)) - ptem = (gotvx(i,n)*(thvx(i,n+1)-thvx(i,k))+tem3)*dz -! ptem = (gotvx(i,n)*(thlvx(i,n+1)-thlvx(i,k)+tem3)*dz -! ptem = (gotvx(i,n)*(tem1-thvx(i,k))+tem3)*dz -!! ptem = (gotvx(i,n)*(tem1-thlvx(i,k)+tem3)*dz + if (tc_pbl == 0) then + ptem = (gotvx(i,n)*(thvx(i,n+1)-thvx(i,k))+tem3)*dz +! ptem = (gotvx(i,n)*(thlvx(i,n+1)-thlvx(i,k)+tem3)*dz +! ptem = (gotvx(i,n)*(tem1-thvx(i,k))+tem3)*dz +!! ptem = (gotvx(i,n)*(tem1-thlvx(i,k)+tem3)*dz + else if (tc_pbl == 1) then + tem1 = 0.5*(thvx(i,n+1)+thvx(i,n)) + ptem = (gotvx(i,n)*(tem1-thvx(i,k))+tem3)*dz + endif bsum = bsum + ptem zlup = zlup + dz if(bsum >= tke(i,k)) then @@ -1047,10 +1112,14 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & tem3 = cs0*sqrt(tem3)*sqrt(tke(i,1)) else dz = zl(i,n) - zl(i,n-1) - tem1 = thvx(i,n-1) -! tem1 = thlvx(i,n-1) -! tem1 = 0.5 * (thvx(i,n-1) + thvx(i,n)) -!! tem1 = 0.5 * (thlvx(i,n-1) + thlvx(i,n)) + if (tc_pbl == 0) then + tem1 = thvx(i,n-1) +! tem1 = thlvx(i,n-1) +! tem1 = 0.5 * (thvx(i,n-1) + thvx(i,n)) +!! tem1 = 0.5 * (thlvx(i,n-1) + thlvx(i,n)) + else if (tc_pbl == 1) then + tem1 = 0.5*(thvx(i,n)+thvx(i,n-1)) + endif tem3 = ((u1(i,n)-u1(i,n-1))/dz)**2 tem3 = tem3+((v1(i,n)-v1(i,n-1))/dz)**2 tem3 = cs0*sqrt(tem3)*sqrt(tke(i,k)) @@ -1117,19 +1186,29 @@ subroutine satmedmfvdifq_run(im,km,progsigma,ntrac,ntcw,ntrw, & else ptem = 1. + 2.7 * zol(i) zk = tem / ptem - endif - elm(i,k) = zk*rlam(i,k)/(rlam(i,k)+zk) + endif + if (tc_pbl == 0) then + elm(i,k) = zk*rlam(i,k)/(rlam(i,k)+zk) !> - If sfc_rlm=1, use zk for elm within surface layer - if ( sfc_rlm == 1 ) then - if ( sfcflg(i) .and. - & zl(i,k) < min(100.0,hpbl(i)*0.05) ) elm(i,k)=zk + if ( sfc_rlm == 1 ) then + if ( sfcflg(i) .and. + & zl(i,k) < min(100.0,hpbl(i)*0.05) ) elm(i,k)=zk + endif + else if (tc_pbl == 1) then + ! new blending method for mixing length + elm(i,k) = sqrt( 1.0/( 1.0/(zk**2)+1.0/(rlam(i,k)**2) ) ) endif -! + dz = zi(i,k+1) - zi(i,k) tem = max(gdx(i),dz) elm(i,k) = min(elm(i,k), tem) - ele(i,k) = min(ele(i,k), tem) + + if (tc_pbl == 0) then + ele(i,k) = min(ele(i,k), tem) + else if (tc_pbl == 1) then + ele(i,k) = elm(i,k) + endif ! enddo enddo diff --git a/physics/satmedmfvdifq.meta b/physics/satmedmfvdifq.meta index 8538c6aa7..d9ab8c859 100644 --- a/physics/satmedmfvdifq.meta +++ b/physics/satmedmfvdifq.meta @@ -588,6 +588,13 @@ dimensions = () type = integer intent = in +[tc_pbl] + standard_name = control_for_TC_applications_in_the_PBL_scheme + long_name = control for TC applications in the PBL scheme + units = none + dimensions = () + type = integer + intent = in [ntqv] standard_name = index_of_specific_humidity_in_tracer_concentration_array long_name = tracer index for water vapor (specific humidity) diff --git a/physics/set_soilveg.f b/physics/set_soilveg.f index efef0f24b..37f2c2a73 100644 --- a/physics/set_soilveg.f +++ b/physics/set_soilveg.f @@ -13,11 +13,13 @@ module set_soilveg_mod !> \ingroup Noah_LSM !! This subroutine initializes soil and vegetation. - subroutine set_soilveg(me,isot,ivet,nlunit) + subroutine set_soilveg(me,isot,ivet,nlunit,errmsg,errflg) use namelist_soilveg implicit none integer, intent(in) :: me,isot,ivet,nlunit + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg !my begin locals !for 20 igbp veg type and 19 stasgo soil type integer i @@ -385,16 +387,22 @@ subroutine set_soilveg(me,isot,ivet,nlunit) ! CLOSE(59) IF (DEFINED_SOIL .GT. MAX_SOILTYP) THEN - WRITE(0,*) 'Warning: DEFINED_SOIL too large in namelist' - STOP 222 + errflg = 222 + errmsg = 'ERROR(set_soilveg): DEFINED_SOIL too large in '// & + & 'namelist' + return ENDIF IF (DEFINED_VEG .GT. MAX_VEGTYP) THEN - WRITE(0,*) 'Warning: DEFINED_VEG too large in namelist' - STOP 222 + errflg = 222 + errmsg = 'ERROR(set_soilveg): DEFINED_VEG too large in '// & + & 'namelist' + return ENDIF IF (DEFINED_SLOPE .GT. MAX_SLOPETYP) THEN - WRITE(0,*) 'Warning: DEFINED_SLOPE too large in namelist' - STOP 222 + errflg = 222 + errmsg = 'ERROR(set_soilveg): DEFINED_SLOPE too large in '//& + & 'namelist' + return ENDIF SMLOW = SMLOW_DATA diff --git a/physics/set_soilveg_ruc.F90 b/physics/set_soilveg_ruc.F90 index cac4fd1e7..c03e6fc5f 100644 --- a/physics/set_soilveg_ruc.F90 +++ b/physics/set_soilveg_ruc.F90 @@ -17,9 +17,11 @@ module set_soilveg_ruc_mod !>\ingroup lsm_ruc_group !! This subroutine specifies vegetation and soil parameters for a given !! soil and land-use classification. - subroutine set_soilveg_ruc(me,isot,ivet,nlunit) + subroutine set_soilveg_ruc(me,isot,ivet,nlunit,errmsg,errflg) integer, intent(in) :: isot,ivet,nlunit + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg integer me integer i @@ -35,6 +37,10 @@ subroutine set_soilveg_ruc(me,isot,ivet,nlunit) & WLTSMC, QTZ, mosaic_soil, mosaic_lu, & & REFSMCnoah, WLTSMCnoah, MAXSMCnoah + ! Initialize error-handling + errflg = 0 + errmsg = '' + if(ivet.eq.2) then ! Using umd veg classification slope_data =(/0.1, 0.6, 1.0, 0.35, 0.55, 0.8, & @@ -415,15 +421,21 @@ subroutine set_soilveg_ruc(me,isot,ivet,nlunit) IF (DEFINED_SOIL .GT. MAX_SOILTYP) THEN WRITE(0,*) 'Warning: DEFINED_SOIL too large in namelist' - STOP 222 + errflg = 1 + errmsg = 'ERROR(set_soilveg_ruc): DEFINED_SOIL too large in namelist' + return ENDIF IF (DEFINED_VEG .GT. MAX_VEGTYP) THEN WRITE(0,*) 'Warning: DEFINED_VEG too large in namelist' - STOP 222 + errflg = 1 + errmsg = 'ERROR(set_soilveg_ruc): DEFINED_VEG too large in namelist' + return ENDIF IF (DEFINED_SLOPE .GT. MAX_SLOPETYP) THEN WRITE(0,*) 'Warning: DEFINED_SLOPE too large in namelist' - STOP 222 + errflg = 1 + errmsg = 'ERROR(set_soilveg_ruc): DEFINED_SLOPE too large in namelist' + return ENDIF ! if (me == 0) write(6,soil_veg_ruc) diff --git a/physics/sfc_diff.f b/physics/sfc_diff.f index 9bc7e6d0a..01294bb31 100644 --- a/physics/sfc_diff.f +++ b/physics/sfc_diff.f @@ -376,7 +376,9 @@ subroutine sfc_diff_run (im,rvrdm1,eps,epsm1,grav, & !intent(in) call znot_t_v7(wind10m, ztmax_wat(i)) ! 10-m wind,m/s, ztmax(m) else if (sfc_z0_type > 0) then write(0,*)'no option for sfc_z0_type=',sfc_z0_type - stop + errflg = 1 + errmsg = 'ERROR(sfc_diff_run): no option for sfc_z0_type' + return endif ! call stability diff --git a/physics/sflx.f b/physics/sflx.f index a020e217a..b2fb38ae1 100644 --- a/physics/sflx.f +++ b/physics/sflx.f @@ -116,6 +116,7 @@ subroutine gfssflx &! --- input & swdn, swnet, lwdn, sfcems, sfcprs, sfctmp, & & sfcspd, prcp, q2, q2sat, dqsdt2, th2, ivegsrc, & & vegtyp, soiltyp, slopetyp, shdmin, alb, snoalb, & + & rhonewsn, exticeden, & & bexpp, xlaip, & ! sfc-perts, mgehne & lheatstrg, &! --- input/outputs: & tbot, cmc, t1, stc, smc, sh2o, sneqv, ch, cm,z0, &! --- outputs: @@ -123,7 +124,8 @@ subroutine gfssflx &! --- input & edir, et, ett, esnow, drip, dew, beta, etp, ssoil, & & flx1, flx2, flx3, runoff1, runoff2, runoff3, & & snomlt, sncovr, rc, pc, rsmin, xlai, rcs, rct, rcq, & - & rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax) + & rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax, & + & errmsg, errflg ) ! ===================================================================== ! ! description: ! @@ -310,9 +312,9 @@ subroutine gfssflx &! --- input real (kind=kind_phys), intent(in) :: ffrozp, dt, zlvl, lwdn, & & sldpth(nsoil), swdn, swnet, sfcems, sfcprs, sfctmp, & & sfcspd, prcp, q2, q2sat, dqsdt2, th2, shdmin, alb, snoalb, & - & bexpp, xlaip & !sfc-perts, mgehne + & bexpp, xlaip, rhonewsn & !sfc-perts, mgehne - logical, intent(in) :: lheatstrg + logical, intent(in) :: lheatstrg, exticeden ! --- input/outputs: real (kind=kind_phys), intent(inout) :: tbot, cmc, t1, sneqv, & @@ -327,6 +329,8 @@ subroutine gfssflx &! --- input & runoff1, runoff2, runoff3, rc, pc, rsmin, xlai, rcs, & & rct, rcq, rcsoil, soilw, soilm, smcwlt, smcdry, smcref, & & smcmax + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! --- locals: ! real (kind=kind_phys) :: df1h, @@ -346,6 +350,10 @@ subroutine gfssflx &! --- input ! !===> ... begin here ! +! Initialize CCPP error-handling + errflg = 0 + errmsg = '' + ! --- ... initialization runoff1 = 0.0 @@ -411,7 +419,7 @@ subroutine gfssflx &! --- input !> - Call redprm() to set the land-surface paramters, !! including soil-type and veg-type dependent parameters. - call redprm + call redprm(errmsg, errflg) if(ivegsrc == 1) then !only igbp type has urban !urban @@ -564,7 +572,7 @@ subroutine gfssflx &! --- input !! using old and new snow. call snow_new ! --- inputs: ! -! ( sfctmp, sn_new, ! +! ( sfctmp, sn_new, rhonewsn, exticeden, ! ! --- input/outputs: ! ! snowh, sndens ) ! @@ -877,7 +885,11 @@ subroutine gfssflx &! --- input ! smc, ssoil, runoff1, runoff2, runoff3, edir, ec, et, ! ! ett, snomlt, drip, dew, flx1, flx3, esnow ) ! +! run-total accumulated snow based on snowfall and snowmelt in [m] + endif + + !> - Noah LSM post-processing: !> - Calculate sensible heat (h) for return to parent model. @@ -1668,7 +1680,7 @@ end subroutine penman !> This subroutine internally sets default values or optionally read-in !! via namelist i/o, all soil and vegetation parateters requied for the execusion !! of the Noah LSM. - subroutine redprm + subroutine redprm(errmsg, errflg) !................................... ! --- inputs: ! & ( nsoil, vegtyp, soiltyp, slopetyp, sldpth, zsoil, & @@ -1855,7 +1867,8 @@ subroutine redprm ! & frzx, psisat, slope, snup, salp, bexp, dksat, dwsat, & ! & smcmax, smcwlt, smcref, smcdry, f1, quartz, fxexp, z0, & ! & czil, xlai, csoil, rtdis(nsoil) - + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg ! integer, intent(out) :: nroot ! --- locals: @@ -1866,20 +1879,30 @@ subroutine redprm ! !===> ... begin here ! +! Initialize CCPP error-handling + errflg = 0 + errmsg = '' + if (soiltyp > defined_soil) then write(*,*) 'warning: too many soil types,soiltyp=',soiltyp, & & 'defined_soil=',defined_soil - stop 333 + errflg = 1 + errmsg = 'ERROR(sflx.f): too many soil types' + return endif if (vegtyp > defined_veg) then write(*,*) 'warning: too many veg types' - stop 333 + errflg = 1 + errmsg = 'ERROR(sflx.f): too many veg types' + return endif if (slopetyp > defined_slope) then write(*,*) 'warning: too many slope types' - stop 333 + errflg = 1 + errmsg = 'ERROR(sflx.f): too many slope types' + return endif ! --- ... set-up universal parameters (not dependent on soiltyp, vegtyp @@ -1936,7 +1959,9 @@ subroutine redprm if (nroot > nsoil) then write(*,*) 'warning: too many root layers' - stop 333 + errflg = 1 + errmsg = 'ERROR(sflx.f): too many root layers' + return endif ! --- ... calculate root distribution. present version assumes uniform @@ -2851,7 +2876,7 @@ end subroutine snopac subroutine snow_new !................................... ! --- inputs: -! & ( sfctmp, sn_new, & +! & ( sfctmp, sn_new, rhonewsn, exticeden, & ! --- input/outputs: ! & snowh, sndens & ! & ) @@ -2900,10 +2925,14 @@ subroutine snow_new ! snowcovered and glacierized basin', 6th nordic hydrological ! conference, vemadolen, sweden, 1980, 172-177pp. - if (tempc <= -15.0) then - dsnew = 0.05 + if(.not. exticeden) then + if (tempc <= -15.0) then + dsnew = 0.05 + else + dsnew = 0.05 + 0.0017*(tempc + 15.0)**1.5 + endif else - dsnew = 0.05 + 0.0017*(tempc + 15.0)**1.5 + dsnew = rhonewsn*0.001 endif ! --- ... adjustment of snow density depending on new snowfall diff --git a/physics/sgscloud_radpre.F90 b/physics/sgscloud_radpre.F90 index ae0f39dde..05ca1af2a 100644 --- a/physics/sgscloud_radpre.F90 +++ b/physics/sgscloud_radpre.F90 @@ -35,7 +35,7 @@ module sgscloud_radpre !! !>\section sgscloud_radpre_mod SGS Cloud Scheme Pre General Algorithm subroutine sgscloud_radpre_run( & - im,dt,levs, & + im,dt,fhswr,levs, & flag_init,flag_restart, & con_g, con_pi, eps, epsm1, & r_v, cpv, rcp, & @@ -43,8 +43,9 @@ subroutine sgscloud_radpre_run( & do_mynnedmf, & qc, qi, qv, T3D, P3D, exner, & qr, qs, qg, & - qci_conv,ud_mf, & + qci_conv,qlc,qli,ud_mf, & imfdeepcnv, imfdeepcnv_gf, & + imfdeepcnv_sas, & qc_save, qi_save, qs_save, & qc_bl,qi_bl,cldfra_bl, & delp,clouds1,clouds2,clouds3, & @@ -53,6 +54,7 @@ subroutine sgscloud_radpre_run( & nlay, plyr, xlat, dz,de_lgth, & cldsa,mtopa,mbota, & imp_physics, imp_physics_gfdl,& + imp_physics_fa, & iovr, & errmsg, errflg ) @@ -67,17 +69,18 @@ subroutine sgscloud_radpre_run( & real(kind=kind_phys), intent(in) :: con_g, con_pi, eps, epsm1 real(kind=kind_phys), intent(in) :: r_v, cpv, rcp real(kind=kind_phys), intent(in) :: xlv, xlf, cp - real(kind=kind_phys), intent(in) :: dt + real(kind=kind_phys), intent(in) :: dt,fhswr real :: xls, xlvcp, xlscp !derived below real(kind=kind_phys) :: gfac integer, intent(in) :: im, levs, imfdeepcnv, imfdeepcnv_gf, & - & nlay, imp_physics, imp_physics_gfdl + & nlay, imfdeepcnv_sas, imp_physics, imp_physics_gfdl, imp_physics_fa logical, intent(in) :: flag_init, flag_restart, do_mynnedmf real(kind=kind_phys), dimension(:,:), intent(inout) :: qc, qi real(kind=kind_phys), dimension(:,:), intent(inout) :: qr, qs, qg - ! qci_conv only allocated if GF is used + ! note: qci_conv only allocated if GF is used real(kind=kind_phys), dimension(:,:), intent(inout) :: qci_conv + real(kind=kind_phys), dimension(:,:), intent(inout) :: qlc, qli !for SAS real(kind=kind_phys), dimension(:,:), intent(in) :: ud_mf real(kind=kind_phys), dimension(:,:), intent(in) :: T3D,delp real(kind=kind_phys), dimension(:,:), intent(in) :: qv,P3D,exner @@ -112,7 +115,8 @@ subroutine sgscloud_radpre_run( & real :: rhgrid,h2oliq,qsat,tem1,tem2,clwt,es,onemrh,value !Chaboureau and Bechtold (2002 and 2005) - real :: a, f, sigq, qmq, qt, xl, tlk, th, thl, rsl, cpm, cb_cf + real :: a, f, sigq, qmq, qt, xl, th, thl, rsl, cpm, cb_cf + real(kind=kind_phys) :: tlk !Option to convective cloud fraction integer, parameter :: conv_cf_opt = 0 !0: C-B, 1: X-R @@ -188,7 +192,7 @@ subroutine sgscloud_radpre_run( & !endif if (qc(i,k) < 1.e-6 .and. cldfra_bl(i,k)>0.001) then - qc(i,k) = qc_bl(i,k)*cldfra_bl(i,k) + qc(i,k) = qc_bl(i,k) !eff radius cloud water (microns) from Miles et al. (2007) if (nint(slmsk(i)) == 1) then !land @@ -206,8 +210,8 @@ subroutine sgscloud_radpre_run( & !~700 mb and decrease snow to zero by ~300 mb snow_frac = min(0.5, max((p3d(i,k)-30000.0),0.0)/140000.0) ice_frac = 1.0 - snow_frac - if (qi(i,k) < 1.e-8 .and. cldfra_bl(i,k)>0.001) then - qi(i,k) = ice_frac*qi_bl(i,k)*cldfra_bl(i,k) + if (qi(i,k) < 1.e-9 .and. cldfra_bl(i,k)>0.001) then + qi(i,k) = ice_frac*qi_bl(i,k) !eff radius cloud ice (microns), from Mishra et al. (2014, JGR Atmos, fig 6b) if(qi(i,k)>1.E-8)clouds5(i,k)=max(173.45 + 2.14*Tc, 20.) @@ -219,8 +223,8 @@ subroutine sgscloud_radpre_run( & clouds4(i,k) = max(0.0, qi(i,k) * gfac * delp(i,k)) endif - if (qs(i,k) < 1.e-8 .and. cldfra_bl(i,k)>0.001) then - qs(i,k) = snow_frac*qi_bl(i,k)*cldfra_bl(i,k) + if (qs(i,k) < 1.e-9 .and. cldfra_bl(i,k)>0.001) then + qs(i,k) = snow_frac*qi_bl(i,k) !eff radius cloud ice (microns), from Mishra et al. (2014, JGR Atmos, fig 6b) if(qs(i,k)>1.E-8)clouds9(i,k)=max(2.*(173.45 + 2.14*Tc), 50.) @@ -270,7 +274,6 @@ subroutine sgscloud_radpre_run( & if (imfdeepcnv == imfdeepcnv_gf) then do k = 1, levs do i = 1, im - !if ( qci_conv(i,k) > 0. .AND. (qi(i,k) < 1E-7 .AND. qc(i,k) < 1E-7 ) ) then if ( qci_conv(i,k) > 0. ) then Tk = T3D(i,k) Tc = Tk - 273.15 @@ -321,10 +324,15 @@ subroutine sgscloud_radpre_run( & sigq = SQRT(sigq**2 + 1e-10) ! combined conv + background components qmq = a * (qt - qsat) ! saturation deficit/excess; ! the numerator of Q1 - cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.01),0.99) + cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.0),0.99) + if (qci_conv(i,k) .lt. 1e-9) cb_cf = 0.0 if (do_mynnedmf .and. qmq .ge. 0.0) then ! leverage C-B stratus clouds from MYNN in saturated conditions - clouds1(i,k) = 0.5*(clouds1(i,k) + cb_cf) + if (cb_cf .gt. 0.0) then + clouds1(i,k) = 0.5*(clouds1(i,k) + cb_cf) + else + !default to MYNN clouds - already specified + endif else ! unsaturated clouds1(i,k) = cb_cf endif @@ -354,7 +362,101 @@ subroutine sgscloud_radpre_run( & endif ! qci_conv enddo enddo - endif ! imfdeepcnv_gf + + elseif (imfdeepcnv == imfdeepcnv_sas) then + + do k = 1, levs + do i = 1, im + h2oliq = qlc(i,k)+qli(i,k) + if ( h2oliq > 0. ) then + Tk = T3D(i,k) + Tc = Tk - 273.15 + + !Partition the convective clouds into water & frozen species + liqfrac = min(1., max(0., (Tk-244.)/29.)) + + qc(i,k) = qc(i,k)+qlc(i,k) + !split ice & snow 50-50% + qi(i,k) = qi(i,k)+0.5*qli(i,k) + qs(i,k) = qs(i,k)+0.5*qli(i,k) + + !eff radius cloud water (microns) + if (nint(slmsk(i)) == 1) then !land + if(qc(i,k)>1.E-8)clouds3(i,k)=5.4 + else + !from Miles et al. + if(qc(i,k)>1.E-8)clouds3(i,k)=9.6 + endif + !from Mishra et al. (2014, JGR Atmos), assume R_sno = 2*R_ice + if(qi(i,k)>1.e-8)clouds5(i,k)=max( 173.45 + 2.14*Tc , 20.) + if(qs(i,k)>1.e-8)clouds9(i,k)=max(2.0*(173.45 + 2.14*Tc), 50.) + + if ( conv_cf_opt .eq. 0 ) then + !print *,'Chab-Bechtold cloud fraction used' + !Alternatively, use Chaboureau-Bechtold (CB) convective component + !Based on both CB2002 and CB2005. + xl = xlv*liqfrac + xls*(1.-liqfrac) ! blended heat capacity + tlk = t3d(i,k) - xlvcp/exner(i,k)*qc(i,k) & + & - xlscp/exner(i,k)*qi(i,k)! liquid temp + ! get saturation water vapor mixing ratio at tl and p + es = min( p3d(i,k), fpvs( tlk ) ) ! fpvs and prsl in pa + qsat= max( QMIN, eps*es / (p3d(i,k) + epsm1*es) ) + rsl = xl*qsat / (r_v*tlk**2) ! slope of C-C curve at t = tl + ! CB02, Eqn. 4 + qt = qc(i,k) + qi(i,k) + qv(i,k) !total water + cpm = cp + qt*cpv ! CB02, sec. 2, para. 1 + a = 1./(1. + xl*rsl/cpm) ! CB02 variable "a" + !Now calculate convective component of the cloud fraction: + if (a > 0.0) then + f = min(1.0/a, 4.0) ! f is the vertical profile + else ! scaling function (CB2005) + f = 1.0 + endif + sigq = 1.5E-3 * ud_mf(i,k)/dt * f + !sigq = 3.E-3 * ud_mf(i,k)/dt * f + sigq = SQRT(sigq**2 + 1e-10) ! combined conv + background components + qmq = a * (qt - qsat) ! saturation deficit/excess; + ! the numerator of Q1 + cb_cf= min(max(0.5 + 0.36 * atan(1.55*(qmq/sigq)),0.0),0.99) + if (h2oliq .lt. 1e-9) cb_cf = 0.0 + if (do_mynnedmf .and. qmq .ge. 0.0) then + ! leverage C-B stratus clouds from MYNN in saturated conditions + if (cb_cf .gt. 0.0) then + clouds1(i,k) = 0.5*(clouds1(i,k) + cb_cf) + else + !default to MYNN clouds - already specified + endif + else ! unsaturated + clouds1(i,k) = cb_cf + endif + else + !print *,'SAS with Xu-Randall cloud fraction' + ! Xu-Randall (1996) cloud fraction + es = min( p3d(i,k), fpvs( t3d(i,k) ) ) ! fpvs and prsl in pa + qsat = max( QMIN, eps*es / (p3d(i,k) + epsm1*es) ) + rhgrid = max( 0., min( 1.00, qv(i,k)/qsat ) ) + h2oliq = qc(i,k) + qi(i,k) + qr(i,k) + qs(i,k) + qg(i,k) ! g/kg + clwt = 1.0e-6 * (p3d(i,k)*0.00001) + + if (h2oliq > clwt) then + onemrh= max( 1.e-10, 1.0-rhgrid ) + tem1 = min(max((onemrh*qsat)**0.49,0.0001),1.0) !jhan + tem1 = 100.0 / tem1 + value = max( min( tem1*(h2oliq-clwt), 50.0 ), 0.0 ) + tem2 = sqrt( sqrt(rhgrid) ) + + clouds1(i,k) = max( tem2*(1.0-exp(-value)), 0.0 ) + else + clouds1(i,k) = 0.0 + endif + !print*,"XuRandla- cf:",clouds1(i,k)," rh:",rhgrid," qt:",h2oliq + !print*,"XuRandlb- clwt:",clwt," qsat:",qsat," p:",p3d(i,k) + endif ! end convective cf choice + endif ! qlc/qli check + enddo + enddo + + endif ! convection scheme check endif ! timestep > 1 diff --git a/physics/sgscloud_radpre.meta b/physics/sgscloud_radpre.meta index 28c1b7da6..887ea0b45 100644 --- a/physics/sgscloud_radpre.meta +++ b/physics/sgscloud_radpre.meta @@ -29,6 +29,14 @@ dimensions = () type = integer intent = in +[fhswr] + standard_name = period_of_shortwave_radiation_calls + long_name = frequency for shortwave radiation + units = s + dimensions = () + type = real + kind = kind_phys + intent = in [flag_init] standard_name = flag_for_first_timestep long_name = flag signaling first time step for time integration loop @@ -218,6 +226,22 @@ type = real kind = kind_phys intent = inout +[qlc] + standard_name = cloud_condensed_water_mixing_ratio_convective_transport_tracer + long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) in the convectively transported tracer array + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[qli] + standard_name = ice_water_mixing_ratio_convective_transport_tracer + long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) in the convectively transported tracer array + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout [imfdeepcnv] standard_name = control_for_deep_convection_scheme long_name = flag for mass-flux deep convection scheme @@ -232,6 +256,13 @@ dimensions = () type = integer intent = in +[imfdeepcnv_sas] + standard_name = identifier_for_simplified_arakawa_schubert_deep_convection + long_name = flag for SAS deep convection scheme + units = flag + dimensions = () + type = integer + intent = in [qc_save] standard_name = cloud_condensed_water_mixing_ratio_save long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) before entering a physics scheme @@ -427,6 +458,13 @@ dimensions = () type = integer intent = in +[imp_physics_fa] + standard_name = identifier_for_fer_hires_microphysics_scheme + long_name = choice of Ferrier-Aligo microphysics scheme + units = flag + dimensions = () + type = integer + intent = in [iovr] standard_name = flag_for_cloud_overlap_method_for_radiation long_name = max-random overlap clouds diff --git a/physics/smoke_dust/coarsepm_settling_mod.F90 b/physics/smoke_dust/coarsepm_settling_mod.F90 new file mode 100755 index 000000000..9061840c3 --- /dev/null +++ b/physics/smoke_dust/coarsepm_settling_mod.F90 @@ -0,0 +1,274 @@ +module coarsepm_settling_mod + + use machine , only : kind_phys + use dust_data_mod, only : dyn_visc !den_dust, reff_dust, dyn_visc + + implicit none + +CONTAINS + + +SUBROUTINE coarsepm_settling_driver(dt,t_phy,rel_hum, & + chem,rho_phy,dz8w,p8w,p_phy,sedim, & + area,g,num_chem, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) + + IMPLICIT NONE + + INTEGER, INTENT(IN ) :: & + num_chem, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte + REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ),INTENT(INOUT ) :: chem + REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & + INTENT(IN ) :: t_phy,p_phy,dz8w,p8w,rho_phy,rel_hum + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ),INTENT(IN ) :: area + REAL(kind_phys), INTENT(IN ) :: dt,g + + REAL(kind_phys), DIMENSION( ims:ime, jms:jme, num_chem ), INTENT(OUT ) :: sedim + + integer :: nv,i,j,k,kk,lmx,idust + real(kind_phys), DIMENSION (1,1,kte-kts+1) :: tmp,airden,airmas,p_mid,delz,rh + real(kind_phys), DIMENSION (1,1,kte-kts+1,1) :: dust + real(kind_phys), DIMENSION (ime,jme,kme,num_chem) :: chem_before +! +! bstl is for budgets +! +! real(kind_phys), DIMENSION (5), PARAMETER :: den_dust(5)=(/2500.,2650.,2650.,2650.,2650./) +! real(kind_phys), DIMENSION (5), PARAMETER :: reff_dust(5)=(/0.73D-6,1.4D-6,2.4D-6,4.5D-6,8.0D-6/) + real(kind_phys), DIMENSION (1), PARAMETER :: den_dust (1)=(/2650. /) + real(kind_phys), DIMENSION (1), PARAMETER :: reff_dust(1)=(/2.4D-6/) + real(kind_phys), DIMENSION (1) :: bstl_dust + real(kind_phys) conver,converi + real(kind_phys),parameter::max_default=0. + + sedim = 0. + conver=1.e-9 + converi=1.e9 + lmx=kte-kts+1 +! + do j=jts,jte + do i=its,ite +! +! initialize some met stuff +! + kk=0 + bstl_dust(:)=0. + do k=kts,kte + kk=kk+1 + p_mid(1,1,kk)=.01*p_phy(i,kte-k+kts,j) + delz(1,1,kk)=dz8w(i,kte-k+kts,j) + airmas(1,1,kk)=-(p8w(i,k+1,j)-p8w(i,k,j))*area(i,j)/g + airden(1,1,kk)=rho_phy(i,k,j) + tmp(1,1,kk)=t_phy(i,k,j) + rh(1,1,kk) = rel_hum(i,k,j) ! hli + do nv = 1, num_chem + chem_before(i,j,k,nv) = chem(i,k,j,nv) + enddo + enddo +! +! max dust in column +! + idust=1 + kk=0 + do k=kts,kte + kk=kk+1 + dust(1,1,kk,1)=chem(i,k,j,1)*conver + enddo + + + call settling(1, 1, lmx, 1,g,dyn_visc, & + dust, tmp, p_mid, delz, airmas, & + den_dust, reff_dust, dt, bstl_dust, rh, idust, airden) + + kk = 0 + do k = kts,kte + kk = kk+1 + chem(i,k,j,1)=dust(1,1,kk,1)*converi ! coarse dust [ug/kg] + enddo +! +! +! + do nv = 1, num_chem + do k = kts,kte + sedim(i,j,nv) = sedim(i,j,nv)+(chem_before(i,j,k,nv) - chem(i,k,j,nv))*p8w(i,k,j)/g + enddo + sedim(i,j,nv) = sedim(i,j,nv) / dt !ug/m2/s + enddo +! +! +! + enddo + enddo +! +! +! +END SUBROUTINE coarsepm_settling_driver + + + subroutine settling(imx,jmx, lmx, nmx,g0,dyn_visc, & + tc, tmp, p_mid, delz, airmas, & + den, reff, dt, bstl, rh, idust, airden) +! **************************************************************************** +! * * +! * Calculate the loss by settling, using an implicit method * +! * * +! * Input variables: * +! * SIGE(k) - sigma coordinate of the vertical edges * +! * PS(i,j) - Surface pressure (mb) * +! * TMP(i,j,k) - Air temperature (K) * +! * CT(i,j) - Surface exchange coeff for moisture +! * * +! **************************************************************************** + + + IMPLICIT NONE + + INTEGER, INTENT(IN) :: imx, jmx, lmx, nmx,idust + INTEGER :: ntdt + REAL(kind_phys), INTENT(IN) :: dt,g0,dyn_visc + REAL(kind_phys), INTENT(IN) :: tmp(imx,jmx,lmx), delz(imx,jmx,lmx), & + airmas(imx,jmx,lmx), rh(imx,jmx,lmx), & + den(nmx), reff(nmx),p_mid(imx,jmx,lmx),& + airden(imx,jmx,lmx) + REAL(kind_phys), INTENT(INOUT) :: tc(imx,jmx,lmx,nmx) + REAL(kind_phys), INTENT(OUT) :: bstl(imx,jmx,nmx) + + REAL(kind_phys) :: tc1(imx,jmx,lmx,nmx), dt_settl(nmx), rcm(nmx), rho(nmx) + INTEGER :: ndt_settl(nmx) + REAL(kind_phys) :: dzmin, vsettl, dtmax, rhb, rwet(nmx), ratio_r(nmx) + REAL(kind_phys) :: c_stokes, free_path, c_cun, viscosity, growth_fac + REAL(kind_phys) :: vd_cor(lmx),vd_wk1 + INTEGER :: k, n, i, j, l, l2 + REAL(kind_phys) :: transfer_to_below_level,temp_tc + + ! for OMP: + REAL(kind_phys) :: rwet_priv(nmx), rho_priv(nmx) + + ! executable statements + + bstl = 0._kind_phys + + if(idust.ne.1.)return + +!!! WHERE (tc(:,:,:,:) < 0.0) tc(:,:,:,:) = 1.0E-32 + + dzmin = MINVAL(delz(:,:,:)) + IF (idust == 1) growth_fac = 1.0 + + DO k = 1,nmx + + ! Settling velocity (m/s) for each tracer (Stokes Law) + ! DEN density (kg/m3) + ! REFF effective radius (m) + ! dyn_visc dynamic viscosity (kg/m/s) + ! g0 gravity (m/s2) + ! 3.0 corresponds to a growth of a factor 3 of radius with 100% RH + ! 0.5 upper limit with temp correction + + tc1(:,:,:,k) = tc(:,:,:,k) + vsettl = 2.0/9.0 * g0 * den(k) * (growth_fac*reff(k))**2 / & + (0.5*dyn_visc) + + ! Determine the maximum time-step satisying the CFL condition: + ! dt <= (dz)_min / v_settl + ntdt=INT(dt) + dtmax = dzmin / vsettl + ndt_settl(k) = MAX( 1, INT( ntdt /dtmax) ) + ! limit maximum number of iterations + IF (ndt_settl(k) > 12) ndt_settl(k) = 12 + dt_settl(k) = REAL(ntdt) / REAL(ndt_settl(k)) + + ! Particles radius in centimeters + IF (idust.eq.1)then + rwet(k) = reff(k) + ratio_r(k) = 1.0 + rho(k) = den(k) + endif + END DO + + ! Solve the bidiagonal matrix (l,l) + +!$OMP PARALLEL DO & +!$OMP DEFAULT( SHARED ) & +!$OMP PRIVATE( i, j, l, l2, n, k, rhb, rwet_priv, ratio_r, c_stokes)& +!$OMP PRIVATE( free_path, c_cun, viscosity, rho_priv, vd_cor ) + + ! Loop over latitudes + DO j = 1,jmx + + DO k = 1,nmx + IF (idust.eq.1) THEN + rwet_priv(k) = rwet(k) + rho_priv(k) = rho(k) + END IF + + DO n = 1,ndt_settl(k) + + ! Solve each vertical layer successively (layer l) + transfer_to_below_level=0 + + DO l = lmx,1,-1 + l2 = lmx - l + 1 + +! DO j = 1,jmx + DO i = 1,imx + + ! Dynamic viscosity + c_stokes = 1.458E-6 * tmp(i,j,l)**1.5/(tmp(i,j,l) + 110.4) + + ! Mean free path as a function of pressure (mb) and + ! temperature (K) + ! order of p_mid is top->sfc + free_path = 1.1E-3/p_mid(i,j,l2)/SQRT(tmp(i,j,l)) +!!! free_path = 1.1E-3/p_edge(i,j,l2)/SQRT(tmp(i,j,l)) + + ! Slip Correction Factor + c_cun = 1.0+ free_path/rwet_priv(k)* & + (1.257 + 0.4*EXP(-1.1*rwet_priv(k)/free_path)) + + ! Corrected dynamic viscosity (kg/m/s) + viscosity = c_stokes / c_cun + + ! Settling velocity + + vd_cor(l) = 2.0/9.0*g0*rho_priv(k)*rwet_priv(k)**2/viscosity + + ! Update mixing ratio; order of delz: top->sfc + temp_tc=tc(i,j,l,k) !temp_tc - for temporal storage [ug/kg] + vd_wk1 = dt_settl(k)*vd_cor(l)/delz(i,j,l2) !fraction to leave level + + tc(i,j,l,k) = tc(i,j,l,k)*(1.- vd_wk1)+transfer_to_below_level ! [ug/kg] + + if (l.gt.1) transfer_to_below_level =(temp_tc*vd_wk1)*((delz(i,j,l2) & + *airden(i,j,l))/(delz(i,j,l2+1)*airden(i,j,l-1))) ! [ug/kg] + + END DO !i +! END DO !j + END DO !l + + END DO !n + END DO !k + + END DO !j +!$OMP END PARALLEL DO + + DO n = 1,nmx + DO i = 1,imx + DO j = 1,jmx + bstl(i,j,n) = 0._kind_phys + DO l = 1,lmx + IF (tc(i,j,l,n) < 0.0) tc(i,j,l,n) = 1.0D-32 + bstl(i,j,n) = bstl(i,j,n) + & + (tc(i,j,l,n) - tc1(i,j,l,n)) * airmas(i,j,l) + END DO + END DO + END DO + END DO + +END SUBROUTINE settling + +end module coarsepm_settling_mod diff --git a/physics/smoke_dust/dep_dry_mod.F90 b/physics/smoke_dust/dep_dry_mod.F90 new file mode 100755 index 000000000..ea7dd9963 --- /dev/null +++ b/physics/smoke_dust/dep_dry_mod.F90 @@ -0,0 +1,69 @@ +!>\file dep_dry_mod.F90 +!! This file is for the dry depostion driver. + +module dep_dry_mod + + use machine , only : kind_phys + + implicit none + + private + + public :: dry_dep_driver + +contains + + subroutine dry_dep_driver(rmol,ust,ndvel,ddvel,rel_hum, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) +!---------------------------------------------------------------------- + IMPLICIT NONE + + INTEGER, INTENT(IN ) :: ndvel, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) , & + INTENT(INOUT) :: ust, rmol + REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & + INTENT(IN ) :: rel_hum + + REAL(kind_phys), PARAMETER :: kpart=500. + REAL(kind_phys) :: dvpart + +! +! Output array + REAL(kind_phys), DIMENSION( its:ite, jts:jte, ndvel ), INTENT(INOUT) :: ddvel + + + integer :: i,j,k,nv +! +! necessary for aerosols (module dependent) +! +! .. Intrinsic Functions .. + INTRINSIC max, min + +! compute dry deposition velocities = ddvel + + ddvel(:,:,:) = 0.0 + do nv = 1, ndvel + do j = jts, jte + do i = its, ite + dvpart = ust(i,j)/kpart + + IF (rmol(i,j)<0.) THEN ! UNSTABLE LAYERING CORRECTION + dvpart = dvpart*(1.+(-300.*rmol(i,j))**0.66667) + ENDIF + + IF (rel_hum(i,1,j)>0.8) THEN ! HIGH RELATIVE HUMIDITY CORRECTION + dvpart = dvpart*(1.+0.37*exp((rel_hum(i,1,j)-0.8)/0.2)) + END IF + ddvel(i,j,nv) = MIN(0.50,dvpart) ! m/s + enddo + enddo + enddo + +end subroutine dry_dep_driver + +end module dep_dry_mod diff --git a/smoke/dust_data_mod.F90 b/physics/smoke_dust/dust_data_mod.F90 similarity index 97% rename from smoke/dust_data_mod.F90 rename to physics/smoke_dust/dust_data_mod.F90 index 9e9713e22..a710701f1 100755 --- a/smoke/dust_data_mod.F90 +++ b/physics/smoke_dust/dust_data_mod.F90 @@ -3,7 +3,6 @@ module dust_data_mod - use rrfs_smoke_data use machine , only : kind_phys use rrfs_smoke_config, only : p_dust_1, p_dust_2, p_dust_3, p_dust_4, p_dust_5, & p_edust1, p_edust2, p_edust3, p_edust4, p_edust5 @@ -80,8 +79,8 @@ module dust_data_mod ! -- FENGSHA uses precalculated drag partition from ASCAT. See: Prigent et al. (2012,2015) integer, parameter :: dust_calcdrag = 1 - real(kind_phys), parameter :: dust_alpha = 2.2 - real(kind_phys), parameter :: dust_gamma = 1.0 + real(kind_phys) :: dust_alpha = 2.2 + real(kind_phys) :: dust_gamma = 1.0 ! -- sea salt parameters diff --git a/physics/smoke_dust/dust_fengsha_mod.F90 b/physics/smoke_dust/dust_fengsha_mod.F90 new file mode 100755 index 000000000..54a64239d --- /dev/null +++ b/physics/smoke_dust/dust_fengsha_mod.F90 @@ -0,0 +1,585 @@ +!>\file dust_fengsha_mod.F90 +!! This file contains the FENGSHA dust scheme. + +module dust_fengsha_mod +! +! This module developed by Barry Baker (NOAA ARL) +! For serious questions contact barry.baker@noaa.gov +! +! 07/16/2019 - Adapted for NUOPC/GOCART, R. Montuoro +! 02/01/2020 - Adapted for FV3/CCPP, Haiqin Li + + use machine , only : kind_phys + use dust_data_mod + + implicit none + + private + + public :: gocart_dust_fengsha_driver + +contains + + subroutine gocart_dust_fengsha_driver(dt, & + chem,rho_phy,smois,p8w,ssm, & + isltyp,vegfra,snowh,xland,area,g,emis_dust, & + ust,znt,clay,sand,rdrag,uthr, & + num_emis_dust,num_chem,num_soil_layers, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte) + IMPLICIT NONE + INTEGER, INTENT(IN ) :: & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte, & + num_emis_dust,num_chem,num_soil_layers + + ! 2d input variables + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: ssm ! Sediment supply map + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: vegfra ! vegetative fraction (-) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: snowh ! snow height (m) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: xland ! dominant land use type + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: area ! area of grid cell + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: ust ! friction velocity + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: znt ! Surface Roughness length (m) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: clay ! Clay Fraction (-) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: sand ! Sand Fraction (-) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: rdrag ! Drag Partition (-) + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: uthr ! Dry Threshold Velocity (m/s) + + INTEGER, DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: isltyp ! soil type + + ! 3d input variables + REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN) :: p8w + REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN) :: rho_phy + REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), INTENT(INOUT) :: chem + REAL(kind_phys), DIMENSION( ims:ime, 1, jms:jme,num_emis_dust),OPTIONAL, INTENT(INOUT) :: emis_dust + REAL(kind_phys), DIMENSION( ims:ime, num_soil_layers, jms:jme ), INTENT(IN) :: smois + + !0d input variables + REAL(kind_phys), INTENT(IN) :: dt ! time step + REAL(kind_phys), INTENT(IN) :: g ! gravity (m/s**2) + + ! Local variables + integer :: nmx,i,j,k,imx,jmx,lmx + integer :: ilwi + real(kind_phys) :: airden ! air density + REAL(kind_phys) :: airmas ! dry air mass + real(kind_phys) :: dxy + real(kind_phys) :: conver,converi ! conversion values + real(kind_phys) :: R ! local drag partition + real(kind_phys) :: ustar + real(kind_phys), DIMENSION (num_emis_dust) :: tc + real(kind_phys), DIMENSION (num_emis_dust) :: bems + real(kind_phys), DIMENSION (num_emis_dust) :: distribution + real(kind_phys), dimension (3) :: massfrac + real(kind_phys) :: erodtot + + ! conversion values + conver=1.e-9 + converi=1.e9 + + ! Number of dust bins + + imx=1 + jmx=1 + lmx=1 + nmx=ndust + + k=kts + do j=jts,jte + do i=its,ite + + ! Don't do dust over water!!! + + ilwi=0 + if(xland(i,j).lt.1.5)then + ilwi=1 + + ! Total concentration at lowest model level. This is still hardcoded for 5 bins. + + ! if(config_flags%chem_opt == 2 .or. config_flags%chem_opt == 11 ) then + ! tc(:)=1.e-16*conver + ! else + tc(1)=chem(i,kts,j,p_dust_1)*conver + tc(2)=chem(i,kts,j,p_dust_2)*conver + tc(3)=chem(i,kts,j,p_dust_3)*conver + tc(4)=chem(i,kts,j,p_dust_4)*conver + tc(5)=chem(i,kts,j,p_dust_5)*conver + ! endif + + ! Air mass and density at lowest model level. + + airmas=-(p8w(i,kts+1,j)-p8w(i,kts,j))*area(i,j)/g + airden=rho_phy(i,kts,j) + ustar=ust(i,j) + dxy=area(i,j) + + ! Mass fractions of clay, silt, and sand. + massfrac(1)=clay(i,j) + massfrac(2)=1-(clay(i,j)+sand(i,j)) + massfrac(3)=sand(i,j) + + + ! Total erodibility. + + erodtot = ssm(i,j) ! SUM(erod(i,j,:)) + + ! Don't allow roughness lengths greater than 20 cm to be lofted. + ! This kludge accounts for land use types like urban areas and + ! forests which would otherwise show up as high dust emitters. + ! This is a placeholder for a more widely accepted kludge + ! factor in the literature, which reduces lofting for rough areas. + ! Forthcoming... + + IF (znt(i,j) .gt. 0.2) then + ilwi=0 + endif + + ! limit where there is lots of vegetation + if (vegfra(i,j) .gt. .17) then + ilwi = 0 + endif + + ! limit where there is snow on the ground + if (snowh(i,j) .gt. 0) then + ilwi = 0 + endif + + ! Do not allow areas with bedrock, lava, or land-ice to loft + + IF (isltyp(i,j) .eq. 15 .or. isltyp(i,j) .eq. 16. .or. & + isltyp(i,j) .eq. 18) then + ilwi=0 + ENDIF + IF (isltyp(i,j) .eq. 0)then + ilwi=0 + endif + if(ilwi == 0 ) cycle + + ! get drag partition + ! FENGSHA uses the drag partition correction of MacKinnon et al 2004 + ! doi:10.1016/j.geomorph.2004.03.009 + if (dust_calcdrag .ne. 1) then + call fengsha_drag(znt(i,j),R) + else + ! use the precalculated version derived from ASCAT; Prigent et al. (2012,2015) + ! doi:10.1109/TGRS.2014.2338913 & doi:10.5194/amt-5-2703-2012 + ! pick only valid values + if (rdrag(i,j) > 0.) then + R = real(rdrag(i,j), kind=kind_phys) + else + cycle + endif + endif + + ! Call dust emission routine. + + call source_dust(imx,jmx, lmx, nmx, dt, tc, ustar, massfrac, & + erodtot, dxy, smois(i,1,j), airden, airmas, bems, g, dust_alpha, dust_gamma, & + R, uthr(i,j)) + + ! convert back to concentration + + chem(i,kts,j,p_dust_1)=tc(1)*converi + chem(i,kts,j,p_dust_2)=tc(2)*converi + chem(i,kts,j,p_dust_3)=tc(3)*converi + chem(i,kts,j,p_dust_4)=tc(4)*converi + chem(i,kts,j,p_dust_5)=tc(5)*converi + + ! For output diagnostics + + emis_dust(i,1,j,p_edust1)=bems(1) + emis_dust(i,1,j,p_edust2)=bems(2) + emis_dust(i,1,j,p_edust3)=bems(3) + emis_dust(i,1,j,p_edust4)=bems(4) + emis_dust(i,1,j,p_edust5)=bems(5) + endif + enddo + enddo + ! + + end subroutine gocart_dust_fengsha_driver + + + subroutine source_dust(imx, jmx, lmx, nmx, dt1, tc, ustar, massfrac, & + erod, dxy, smois, airden, airmas, bems, g0, alpha, gamma, & + R, uthres) + + ! **************************************************************************** + ! * Evaluate the source of each dust particles size bin by soil emission + ! * + ! * Input: + ! * EROD Fraction of erodible grid cell (-) + ! * smois Volumetric soil moisture (m3/m3) + ! * ALPHA Constant to fudge the total emission of dust (1/m) + ! * GAMMA Tuning constant for erodibility (-) + ! * DXY Surface of each grid cell (m2) + ! * AIRMAS Mass of air for each grid box (kg) + ! * AIRDEN Density of air for each grid box (kg/m3) + ! * USTAR Friction velocity (m/s) + ! * DT1 Time step (s) + ! * NMX Number of dust bins (-) + ! * IMX Number of I points (-) + ! * JMX Number of J points (-) + ! * LMX Number of L points (-) + ! * R Drag Partition (-) + ! * UTHRES FENGSHA Dry Threshold Velocities (m/s) + ! * + ! * Data: + ! * MASSFRAC Fraction of mass in each of 3 soil classes (-) (clay silt sand) + ! * DEN_DUST Dust density (kg/m3) + ! * DEN_SALT Saltation particle density (kg/m3) + ! * REFF_SALT Reference saltation particle diameter (m) + ! * REFF_DUST Reference dust particle diameter (m) + ! * LO_DUST Lower diameter limits for dust bins (m) + ! * UP_DUST Upper diameter limits for dust bins (m) + ! * FRAC_SALT Soil class mass fraction for saltation bins (-) + ! * + ! * Parameters: + ! * CMB Constant of proportionality (-) + ! * MMD_DUST Mass median diameter of dust (m) + ! * GSD_DUST Geometric standard deviation of dust (-) + ! * LAMBDA Side crack propagation length (m) + ! * CV Normalization constant (-) + ! * G0 Gravitational acceleration (m/s2) + ! * + ! * Working: + ! * RHOA Density of air in cgs (g/cm3) + ! * DS_REL Saltation surface area distribution (-) + ! * DLNDP Dust bin width (-) + ! * EMIT Total vertical mass flux (kg/m2/s) + ! * EMIT_VOL Total vertical volume flux (m/s) + ! * DSRC Mass of emitted dust (kg/timestep/cell) + ! * + ! * Output: + ! * TC Total concentration of dust (kg/kg/timestep/cell) + ! * BEMS Source of each dust type (kg/timestep/cell) + ! * + ! **************************************************************************** + implicit none + + ! Input + INTEGER, INTENT(IN) :: imx,jmx,lmx,nmx + REAL(kind_phys), INTENT(IN) :: dt1 + REAL(kind_phys), INTENT(IN) :: ustar + REAL(kind_phys), INTENT(IN) :: massfrac(3) + REAL(kind_phys), INTENT(IN) :: erod + REAL(kind_phys), INTENT(IN) :: dxy + REAL(kind_phys), INTENT(IN) :: smois + REAL(kind_phys), INTENT(IN) :: airden + REAL(kind_phys), INTENT(IN) :: airmas + REAL(kind_phys), INTENT(IN) :: g0 + REAL(kind_phys), INTENT(IN) :: alpha + REAL(kind_phys), INTENT(IN) :: gamma + REAL(kind_phys), INTENT(IN) :: R + REAL(kind_phys), INTENT(IN) :: uthres + + ! Output + REAL(kind_phys), INTENT(INOUT) :: tc(nmx) + + ! Local Variables + REAL(kind_phys), INTENT(OUT) :: bems(nmx) + + REAL(kind_phys) :: dvol(nmx) + REAL(kind_phys) :: distr_dust(nmx) + REAL(kind_phys) :: dlndp(nmx) + REAL(kind_phys) :: dsrc + REAL(kind_phys) :: dvol_tot + REAL(kind_phys) :: emit + REAL(kind_phys) :: emit_vol + REAL(kind_phys) :: rhoa + INTEGER :: i, j, n + + ! Constant of proportionality from Marticorena et al, 1997 (unitless) + ! Arguably more ~consistent~ fudge than alpha, which has many walnuts + ! sprinkled throughout the literature. - GC + + REAL(kind_phys), PARAMETER :: cmb=1.0 + REAL(kind_phys), PARAMETER :: kvhmax=2.0e-4 + + ! Parameters used in Kok distribution function. Advise not to play with + ! these without the expressed written consent of someone who knows what + ! they're doing. - GC + + REAL(kind_phys), PARAMETER :: mmd_dust=3.4D-6 ! median mass diameter (m) + REAL(kind_phys), PARAMETER :: gsd_dust=3.0 ! geom. std deviation + REAL(kind_phys), PARAMETER :: lambda=12.0D-6 ! crack propagation length (m) + REAL(kind_phys), PARAMETER :: cv=12.62D-6 ! normalization constant + REAL(kind_phys), PARAMETER :: RHOSOIL=2650. + + + ! calculate the total vertical dust flux + + emit = 0.0 + + call DustEmissionFENGSHA(smois,massfrac(1),massfrac(3), massfrac(2), & + erod, R, airden, ustar, uthres, alpha, gamma, kvhmax, & + g0, RHOSOIL, emit) + + ! Now that we have the total dust emission, distribute into dust bins using + ! lognormal distribution (Dr. Jasper Kok, in press), and + ! calculate total mass emitted over the grid box over the timestep. + ! + ! In calculating the Kok distribution, we assume upper and lower limits to each bin. + ! For reff_dust=(/0.73D-6,1.4D-6,2.4D-6,4.5D-6,8.0D-6/) (default), + ! lower limits were ASSUMED at lo_dust=(/0.1D-6,1.0D-6,1.8D-6,3.0D-6,6.0D-6/) + ! upper limits were ASSUMED at up_dust=(/1.0D-6,1.8D-6,3.0D-6,6.0D-6,10.0D-6/) + ! These may be changed within module_data_gocart_dust.F, but make sure it is + ! consistent with reff_dust values. These values were taken from the original + ! GOCART bin configuration. We use them here to calculate dust bin width, dlndp. + ! dVol is the volume distribution. You know...if you were wondering. GC + + dvol_tot=0. + DO n=1,nmx + dlndp(n)=LOG(up_dust(n)/lo_dust(n)) + dvol(n)=(2.0*reff_dust(n)/cv)*(1.+ERF(LOG(2.0*reff_dust(n)/mmd_dust)/(SQRT(2.)*LOG(gsd_dust))))*& + EXP(-(2.0*reff_dust(n)/lambda)**3.0)*dlndp(n) + dvol_tot=dvol_tot+dvol(n) + ! Convert mass flux to volume flux + !emit_vol=emit/den_dust(n) ! (m s^-1) + END DO + DO n=1,nmx + distr_dust(n)=dvol(n)/dvol_tot + !print *,"distr_dust(",n,")=",distr_dust(n) + END DO + + ! Now distribute total vertical emission into dust bins and update concentration. + + DO n=1,nmx + ! Calculate total mass emitted + dsrc = emit*distr_dust(n)*dxy*dt1 ! (kg) + IF (dsrc < 0.0) dsrc = 0.0 + + ! Update dust mixing ratio at first model level. + tc(n) = tc(n) + dsrc / airmas ! (kg/kg) + ! bems(i,j,n) = dsrc ! diagnostic + !bems(i,j,n) = 1000.*dsrc/(dxy(j)*dt1) ! diagnostic (g/m2/s) + bems(n) = 1.e+9*dsrc/(dxy*dt1) ! diagnostic (ug/m2/s) !lzhang + + END DO + tc(1)=tc(1)+0.286*tc(2) ! This is just for RRFS-SD. DO NOT use in other models!!! + tc(5)=0.714*tc(2)+tc(3)+tc(4) ! This is just for RRFS-SD. DO NOT use in other models!!! + + END SUBROUTINE source_dust + + + subroutine fengsha_drag(z0,R) + implicit none + + real(kind_phys), intent(in) :: z0 + real(kind_phys), intent(out) :: R + real(kind_phys), parameter :: z0s = 1.0e-04 !Surface roughness for ideal bare surface [m] + ! ------------------------------------------------------------------------ + ! Function: Calculates the MacKinnon et al. 2004 Drag Partition Correction + ! + ! R = 1.0 - log(z0 / z0s) / log( 0.7 * (12255./z0s) ** 0.8) + ! + !-------------------------------------------------------------------------- + ! Drag partition correction. See MacKinnon et al. (2004), + ! doi:10.1016/j.geomorph.2004.03.009 + R = 1.0 - log(z0 / z0s) / log( 0.7 * (12255./z0s) ** 0.8) + + ! Drag partition correction. See Marticorena et al. (1997), + ! doi:10.1029/96JD02964 + !R = 1.0 - log(z0 / z0s) / log( 0.7 * (10./z0s) ** 0.8) + + return + end subroutine fengsha_drag + + subroutine DustEmissionFENGSHA(slc, clay, sand, silt, & + ssm, rdrag, airdens, ustar, uthrs, alpha, gamma, & + kvhmax, grav, rhop, emissions) + + ! !USES: + implicit NONE + +! !INPUT PARAMETERS: + REAL(kind_phys), intent(in) :: slc ! liquid water content of soil layer, volumetric fraction [1] + REAL(kind_phys), intent(in) :: clay ! fractional clay content [1] + REAL(kind_phys), intent(in) :: sand ! fractional sand content [1] + REAL(kind_phys), intent(in) :: silt ! fractional silt content [1] + REAL(kind_phys), intent(in) :: ssm ! erosion map [1] + REAL(kind_phys), intent(in) :: rdrag ! drag partition [1/m] + REAL(kind_phys), intent(in) :: airdens ! air density at lowest level [kg/m^3] + REAL(kind_phys), intent(in) :: ustar ! friction velocity [m/sec] + REAL(kind_phys), intent(in) :: uthrs ! threshold velocity [m/2] + REAL(kind_phys), intent(in) :: alpha ! scaling factor [1] + REAL(kind_phys), intent(in) :: gamma ! scaling factor [1] + REAL(kind_phys), intent(in) :: kvhmax ! max. vertical to horizontal mass flux ratio [1] + REAL(kind_phys), intent(in) :: grav ! gravity [m/sec^2] + REAL(kind_phys), intent(in) :: rhop ! soil class density [kg/m^3] + + ! !OUTPUT PARAMETERS: + REAL(kind_phys), intent(inout) :: emissions ! binned surface emissions [kg/(m^2 sec)] + + ! !DESCRIPTION: Compute dust emissions using NOAA/ARL FENGSHA model + ! + ! !REVISION HISTORY: + ! + ! 22Feb2020 B.Baker/NOAA - Original implementation + ! 29Mar2021 R.Montuoro/NOAA - Refactored for process library + ! 09Aug2022 B.Baker/NOAA - Adapted for CCPP-Physics + + ! !Local Variables + real(kind_phys) :: alpha_grav + real(kind_phys) :: h + real(kind_phys) :: kvh + real(kind_phys) :: q + real(kind_phys) :: rustar + real(kind_phys) :: total_emissions + real(kind_phys) :: u_sum, u_thresh + +!EOP +!------------------------------------------------------------------------- +! Begin + +! Initialize emissions +! -------------------- + emissions = 0. + +! Prepare scaling factor +! ---------------------- + alpha_grav = alpha / grav + + ! Compute vertical-to-horizontal mass flux ratio + ! ---------------------------------------------- + kvh = DustFluxV2HRatioMB95(clay, kvhmax) + + ! Compute total emissions + ! ----------------------- + emissions = alpha_grav * (ssm ** gamma) * airdens * kvh + + ! Compute threshold wind friction velocity using drag partition + ! ------------------------------------------------------------- + rustar = rdrag * ustar + + ! Now compute size-dependent total emission flux + ! ---------------------------------------------- + ! Fecan moisture correction + ! ------------------------- + h = moistureCorrectionFecan(slc, sand, clay, rhop) + + ! Adjust threshold + ! ---------------- + u_thresh = uthrs * h + + u_sum = rustar + u_thresh + + ! Compute Horizontal Saltation Flux according to Eq (9) in Webb et al. (2020) + ! --------------------------------------------------------------------------- + q = max(0., rustar - u_thresh) * u_sum * u_sum + + ! Distribute emissions to bins and convert to mass flux (kg s-1) + ! -------------------------------------------------------------- + emissions = emissions * q + + + end subroutine DustEmissionFENGSHA +!----------------------------------------------------------------- + real function soilMoistureConvertVol2Grav(vsoil, sandfrac, rhop) + +! !USES: + implicit NONE + +! !INPUT PARAMETERS: + REAL(kind_phys), intent(in) :: vsoil ! volumetric soil moisture fraction [1] + REAL(kind_phys), intent(in) :: sandfrac ! fractional sand content [1] + REAL(kind_phys), intent(in) :: rhop ! dry dust density [kg m-3] + +! !DESCRIPTION: Convert soil moisture fraction from volumetric to gravimetric. +! +! !REVISION HISTORY: +! +! 02Apr2020, B.Baker/NOAA - Original implementation +! 01Apr2020, R.Montuoro/NOAA - Adapted for GOCART process library + +! !Local Variables + real :: vsat + +! !CONSTANTS: + REAL(kind_phys), parameter :: rhow = 1000. ! density of water [kg m-3] + +!EOP +!------------------------------------------------------------------------- +! Begin... + +! Saturated volumetric water content (sand-dependent) ! [m3 m-3] + vsat = 0.489 - 0.00126 * ( 100. * sandfrac ) + +! Gravimetric soil content + soilMoistureConvertVol2Grav = vsoil * rhow / (rhop * (1. - vsat)) + + end function soilMoistureConvertVol2Grav +!---------------------------------------------------------------- + real function moistureCorrectionFecan(slc, sand, clay, rhop) + +! !USES: + implicit NONE + +! !INPUT PARAMETERS: + REAL(kind_phys), intent(in) :: slc ! liquid water content of top soil layer, volumetric fraction [1] + REAL(kind_phys), intent(in) :: sand ! fractional sand content [1] + REAL(kind_phys), intent(in) :: clay ! fractional clay content [1] + REAL(kind_phys), intent(in) :: rhop ! dry dust density [kg m-3] + +! !DESCRIPTION: Compute correction factor to account for Fecal soil moisture +! +! !REVISION HISTORY: +! +! 02Apr2020, B.Baker/NOAA - Original implementation +! 01Apr2020, R.Montuoro/NOAA - Adapted for GOCART process library + +! !Local Variables + real :: grvsoilm + real :: drylimit + +!EOP +!--------------------------------------------------------------- +! Begin... + +! Convert soil moisture from volumetric to gravimetric + grvsoilm = soilMoistureConvertVol2Grav(slc, sand, 2650.) + +! Compute fecan dry limit + drylimit = clay * (14.0 * clay + 17.0) + +! Compute soil moisture correction + moistureCorrectionFecan = sqrt(1.0 + 1.21 * max(0., grvsoilm - drylimit)**0.68) + + end function moistureCorrectionFecan +!--------------------------------------------------------------- + real function DustFluxV2HRatioMB95(clay, kvhmax) + +! !USES: + implicit NONE + +! !INPUT PARAMETERS: + REAL(kind_phys), intent(in) :: clay ! fractional clay content [1] + REAL(kind_phys), intent(in) :: kvhmax ! maximum flux ratio [1] + +! !CONSTANTS: + REAL(kind_phys), parameter :: clay_thresh = 0.2 ! clay fraction above which the maximum flux ratio is returned + +! !DESCRIPTION: Computes the vertical-to-horizontal dust flux ratio according to +! B.Marticorena, G.Bergametti, J.Geophys.Res., 100(D8), 164! doi:10.1029/95JD00690 +! +! !REVISION HISTORY: +! +! 22Feb2020 B.Baker/NOAA - Original implementation +! 01Apr2021 R.Montuoro/NOAA - Adapted for GOCART process library +! +!EOP +!------------------------------------------------------------------------- +! Begin... + + if (clay > clay_thresh) then + DustFluxV2HRatioMB95 = kvhmax + else + DustFluxV2HRatioMB95 = 10.0**(13.4*clay-6.0) + end if + + end function DustFluxV2HRatioMB95 + +end module dust_fengsha_mod diff --git a/smoke/module_add_emiss_burn.F90 b/physics/smoke_dust/module_add_emiss_burn.F90 similarity index 90% rename from smoke/module_add_emiss_burn.F90 rename to physics/smoke_dust/module_add_emiss_burn.F90 index da35535f7..6cdd2e071 100755 --- a/smoke/module_add_emiss_burn.F90 +++ b/physics/smoke_dust/module_add_emiss_burn.F90 @@ -4,15 +4,14 @@ module module_add_emiss_burn !RAR: significantly modified for the new BB emissions use machine , only : kind_phys - use rrfs_smoke_data use rrfs_smoke_config CONTAINS - subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & + subroutine add_emis_burn(dtstep,dz8w,rho_phy,rel_hum, & chem,julday,gmt,xlat,xlong, & !luf_igbp,lu_fire1, & vegtype,vfrac,peak_hr, & time_int,ebu, & ! RAR - r_q,fhist,aod3d_smoke,aod3d_dust, & + r_q,fhist,ext3d_smoke,ext3d_dust, & ! nwfa,nifa, & rainc,rainnc, swdown,smoke_forecast, & ids,ide, jds,jde, kds,kde, & @@ -22,11 +21,10 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & ! USE module_configure, only: grid_config_rec_type ! USE module_state_description IMPLICIT NONE - type(smoke_data), intent(inout) :: data ! TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags - INTEGER, INTENT(IN ) :: ktau, julday, & + INTEGER, INTENT(IN ) :: julday, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte @@ -40,7 +38,7 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(IN) :: xlat,xlong, rainc,rainnc,swdown, peak_hr, vfrac real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(OUT) :: r_q ! RAR: real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(INOUT) :: fhist ! RAR: - real(kind_phys), DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(OUT) :: aod3d_smoke, aod3d_dust ! RAR: + real(kind_phys), DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(OUT) :: ext3d_smoke, ext3d_dust ! RAR: integer, DIMENSION(ims:ime,jms:jme), INTENT(IN) :: vegtype real(kind_phys), DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(IN) :: dz8w,rho_phy,rel_hum @@ -51,14 +49,14 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & real(kind_phys), INTENT(IN) :: dtstep, gmt real(kind_phys), INTENT(IN) :: time_int ! RAR: time in seconds since start of simulation - logical, INTENT(IN) :: smoke_forecast + integer, INTENT(IN) :: smoke_forecast integer :: i,j,k,n,m real(kind_phys) :: conv_rho, conv, ext2, dm_smoke, daero_num_wfa, daero_num_ifa !, lu_sum1_5, lu_sum12_14 !real(kind_phys) :: ebumax ! CHARACTER (LEN=80) :: message - INTEGER, PARAMETER :: kfire_max=35 ! max vertical level for BB plume rise + INTEGER, PARAMETER :: kfire_max=51 ! max vertical level for BB plume rise ! Diameters and standard deviations for emissions ! the diameters are the volume (mass) geometric mean diameters, following MADE_SORGAM real(kind_phys), PARAMETER :: dgvem_i= 0.08E-6 !0.03E-6 ! [ m ] @@ -148,7 +146,7 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & ! r_q(i,j)= fhist(i,j) ! no diurnal cycle !END IF - !IF (.NOT. smoke_forecast) THEN + !IF (smoke_forecast == 0) THEN r_q(i,j)= 1. !END IF @@ -174,21 +172,19 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & chem(i,k,j,p_smoke) = chem(i,k,j,p_smoke) + dm_smoke chem(i,k,j,p_smoke) = MIN(chem(i,k,j,p_smoke),5.e+3) - if (ktau<1000 .and. dbg_opt) then ! if ( k==kts ) then - ! WRITE(6,*) 'add_emiss_burn: ktau,gmt,dtstep,time_int ',ktau,gmt,dtstep,time_int + ! WRITE(6,*) 'add_emiss_burn: gmt,dtstep,time_int ',gmt,dtstep,time_int ! WRITE(*,*) 'add_emiss_burn: i,j,xlat(i,j),xlong(i,j) ',i,j,xlat(i,j),xlong(i,j) !WRITE(*,*) 'add_emiss_burn: luf_igbp(i,:,j) ',luf_igbp(i,:,j) !WRITE(*,*) 'add_emiss_burn: lu_fire1(i,j) ',lu_fire1(i,j) ! WRITE(6,*) 'add_emiss_burn: timeq,peak_hr(i,j),fhist(i,j),r_q(i,j) ',timeq,peak_hr(i,j),fhist(i,j),r_q(i,j) ! WRITE(*,*) 'add_emiss_burn: rainc(i,j),rainnc(i,j) ', rainc(i,j),rainnc(i,j) ! endif - if ( k==kts .OR. k==kfire_max ) then + if ( dbg_opt .and. (k==kts .OR. k==kfire_max) ) then WRITE(6,*) 'add_emiss_burn: i,j,k ',i,j,k WRITE(6,*) 'add_emiss_burn: rho_phy(i,k,j),dz8w(i,k,j),conv ',rho_phy(i,k,j),dz8w(i,k,j),conv WRITE(6,*) 'add_emiss_burn: ebu(i,k,j),dm_smoke ', ebu(i,k,j),dm_smoke endif - endif enddo enddo @@ -204,17 +200,17 @@ subroutine add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum, & chem(i,k,j,p_smoke)=1.e-16 END IF - aod3d_smoke(i,k,j)= 1.e-6* ext2* chem(i,k,j,p_smoke )*rho_phy(i,k,j)*dz8w(i,k,j) - aod3d_dust (i,k,j)= 1.e-6* ext2* chem(i,k,j,p_dust_1)*rho_phy(i,k,j)*dz8w(i,k,j) + ext3d_smoke(i,k,j)= 1.e-6* ext2* chem(i,k,j,p_smoke )*rho_phy(i,k,j)*dz8w(i,k,j) + ext3d_dust (i,k,j)= 1.e-6* ext2* chem(i,k,j,p_dust_1)*rho_phy(i,k,j)*dz8w(i,k,j) enddo enddo enddo - IF ( ktau<2000 .and. dbg_opt ) then + IF ( dbg_opt ) then WRITE(*,*) 'add_emis_burn: i,j,k,ext2 ',i,j,k,ext2 WRITE(*,*) 'add_emis_burn: rel_hum(its,kts,jts),rel_hum(ite,kfire_max,jte) ',rel_hum(its,kts,jts),rel_hum(ite,kfire_max,jte) - WRITE(*,*) 'add_emis_burn: aod3d_smoke(its,kts,jts),aod3d_smoke(ite,kfire_max,jte) ',aod3d_smoke(its,kts,jts),aod3d_smoke(ite,kfire_max,jte) - WRITE(*,*) 'add_emis_burn: aod3d_dust(its,kts,jts),aod3d_dust(ite,kfire_max,jte) ',aod3d_dust(its,kts,jts),aod3d_dust(ite,kfire_max,jte) + WRITE(*,*) 'add_emis_burn: ext3d_smoke(its,kts,jts),ext3d_smoke(ite,kfire_max,jte) ',ext3d_smoke(its,kts,jts),ext3d_smoke(ite,kfire_max,jte) + WRITE(*,*) 'add_emis_burn: ext3d_dust(its,kts,jts),ext3d_dust(ite,kfire_max,jte) ',ext3d_dust(its,kts,jts),ext3d_dust(ite,kfire_max,jte) END IF ! CASE DEFAULT diff --git a/smoke/module_plumerise1.F90 b/physics/smoke_dust/module_plumerise1.F90 similarity index 91% rename from smoke/module_plumerise1.F90 rename to physics/smoke_dust/module_plumerise1.F90 index 47bb4e74a..3c23faa6a 100755 --- a/smoke/module_plumerise1.F90 +++ b/physics/smoke_dust/module_plumerise1.F90 @@ -3,7 +3,6 @@ module module_plumerise1 - use rrfs_smoke_data use machine , only : kind_phys real(kind=kind_phys),parameter :: p1000mb = 100000. ! p at 1000mb (pascals) !- Implementing the fire radiative power (FRP) methodology for biomass burning @@ -35,10 +34,10 @@ module module_plumerise1 ! 'aggr' /) ! grassland CONTAINS -subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & +subroutine ebu_driver ( flam_frac,ebb_smoke,ebu, & t_phy,q_vap, & ! RAR: moist is replaced with q_vap rho_phy,vvel,u_phy,v_phy,p_phy, & - z_at_w,z,ktau,g,con_cp,con_rd, & ! scale_fire_emiss is part of config_flags + z_at_w,z,g,con_cp,con_rd, & ! scale_fire_emiss is part of config_flags plume_frp, k_min, k_max, & ! RAR: ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & @@ -49,7 +48,6 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & USE module_zero_plumegen_coms USE module_smoke_plumerise IMPLICIT NONE - type(smoke_data), intent(inout) :: data REAL(kind_phys), PARAMETER :: frp_threshold= 1.e+7 ! Minimum FRP (Watts) to have plume rise @@ -58,8 +56,7 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & ! TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags character(*), intent(inout) :: errmsg integer, intent(inout) :: errflg - INTEGER, INTENT(IN ) :: ktau, & - ids,ide, jds,jde, kds,kde, & + INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte ! real(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & @@ -98,7 +95,6 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & ! write(0,*)'plumerise' ! RAR: -! if (config_flags%biomass_burn_opt == BIOMASSB_SMOKE) then ! do j=jts,jte: ! do i=its,ite ! ebu(i,kts,j,p_ebu_smoke)= ebb_smoke(i,j) @@ -115,12 +111,12 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & cpor =con_cp/con_rd con_rocp=con_rd/con_cp - IF ( dbg_opt .and. ktau<2000) then + IF ( dbg_opt ) then WRITE(*,*) 'module_plumerise1: its,ite,jts,jte ', its,ite,jts,jte WRITE(*,*) 'module_plumerise1: ims,ime,jms,jme ', ims,ime,jms,jme !WRITE(*,*) 'module_plumerise1: p_ebu_smoke,num_ebu: ', p_ebu_smoke,num_ebu WRITE(*,*) 'module_plumerise1: maxval(ebu(:,kts,:)) ', maxval(ebu(:,kts,:)) - END IF + END IF !endif ! RAR: setting to zero the ebu emissions at the levels k>1, this is necessary when the plumerise is called, so the emissions at k>1 are updated @@ -136,7 +132,6 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & ! For now the flammable fraction is constant, based on the namelist. The next ! step to use LU index and meteorology to parameterize it -! IF (ktau==2) THEN do j=jts,jte do i=its,ite flam_frac(i,j)= 0. @@ -145,13 +140,12 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & end if enddo enddo - ! ENDIF ! RAR: new FRP based approach !check_pl: IF (config_flags%plumerise_flag == 2 ) THEN ! if the namelist option is set for plumerise ! Haiqin: plumerise_flag is added to the namelist options -!check_pl: IF (do_plumerise) THEN ! if the namelist option is set for plumerise +check_pl: IF (do_plumerise) THEN ! if the namelist option is set for plumerise do j=jts,jte do i=its,ite ! k_min(i,j)=0 @@ -175,7 +169,7 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & !theta_in(k)= t_phy(i,k,j)/pi_in(k)*cp enddo - IF (dbg_opt .and. ktau<2000) then + IF (dbg_opt) then WRITE(*,*) 'module_plumerise1: i,j ',i,j WRITE(*,*) 'module_plumerise1: plume_frp(i,j,:) ',plume_frp(i,j,:) WRITE(*,*) 'module_plumerise1: ebu(i,kts,j) ',ebu(i,kts,j) @@ -185,15 +179,15 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & END IF ! RAR: the plume rise calculation step: - CALL plumerise(data,kte,1,1,1,1,1,1, & + CALL plumerise(kte,1,1,1,1,1,1, & !firesize,mean_fct, & !num_ebu, eburn_in, eburn_out, & u_in, v_in, w_in, theta_in ,pi_in, & rho_phyin, qv_in, zmid, z_lev, & plume_frp(i,j,1), k_min(i,j), & - k_max(i,j), ktau, dbg_opt, g, con_cp, & + k_max(i,j), dbg_opt, g, con_cp, & con_rd, cpor, errmsg, errflg ) - !k_max(i,j), ktau, config_flags%debug_chem ) + !k_max(i,j), config_flags%debug_chem ) if(errflg/=0) return kp1= k_min(i,j) @@ -205,7 +199,7 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & enddo ebu(i,kts,j)= (1.-flam_frac(i,j))* ebb_smoke(i,j) - IF ( dbg_opt .and. ktau<2000) then + IF ( dbg_opt ) then WRITE(*,*) 'module_plumerise1: i,j ',i,j WRITE(*,*) 'module_plumerise1: k_min(i,j), k_max(i,j) ',k_min(i,j), k_max(i,j) END IF @@ -213,7 +207,7 @@ subroutine ebu_driver ( data,flam_frac,ebb_smoke,ebu, & enddo enddo -! ENDIF check_pl + ENDIF check_pl end subroutine ebu_driver diff --git a/smoke/module_smoke_plumerise.F90 b/physics/smoke_dust/module_smoke_plumerise.F90 similarity index 97% rename from smoke/module_smoke_plumerise.F90 rename to physics/smoke_dust/module_smoke_plumerise.F90 index 247b09f92..61be06181 100755 --- a/smoke/module_smoke_plumerise.F90 +++ b/physics/smoke_dust/module_smoke_plumerise.F90 @@ -14,8 +14,6 @@ module module_smoke_plumerise use machine , only : kind_phys - use rrfs_smoke_data - use rrfs_smoke_config, only : FIRE_OPT_GBBEPx, FIRE_OPT_MODIS use plume_data_mod, only : num_frp_plume, p_frp_hr, p_frp_std, & !tropical_forest, boreal_forest, savannah, grassland, & wind_eff @@ -26,15 +24,14 @@ module module_smoke_plumerise CONTAINS ! RAR: - subroutine plumerise(data,m1,m2,m3,ia,iz,ja,jz, & + subroutine plumerise(m1,m2,m3,ia,iz,ja,jz, & ! firesize,mean_fct, & ! nspecies,eburn_in,eburn_out, & up,vp,wp,theta,pp,dn0,rv,zt_rams,zm_rams, & - frp_inst,k1,k2, ktau, dbg_opt, g, cp, rgas, & + frp_inst,k1,k2, dbg_opt, g, cp, rgas, & cpor, errmsg, errflg ) implicit none - type(smoke_data), intent(inout) :: data LOGICAL, INTENT (IN) :: dbg_opt @@ -46,7 +43,6 @@ subroutine plumerise(data,m1,m2,m3,ia,iz,ja,jz, & integer :: ng,m1,m2,m3,ia,iz,ja,jz,ibcon,mynum,i,j,k,imm,ixx,ispc !,nspecies - INTEGER, INTENT (IN) :: ktau INTEGER, INTENT (OUT) :: k1,k2 character(*), intent(inout) :: errmsg integer, intent(inout) :: errflg @@ -106,9 +102,6 @@ subroutine plumerise(data,m1,m2,m3,ia,iz,ja,jz, & !---------------------------------------------------------------------- ! print *,' Plumerise_scalar 1',ncall coms => get_thread_coms() - if (ktau==2) then - call coms%set_to_zero() - endif IF (frp_inst=k1+1 @@ -208,7 +199,7 @@ subroutine plumerise(data,m1,m2,m3,ia,iz,ja,jz, & ! enddo !enddo - IF (dbg_opt .AND. ktau<2000) then + IF (dbg_opt) then WRITE(*,*) 'plumerise after set_flam_vert: nkp,k1,k2, ', nkp,k1,k2 WRITE(*,*) 'plumerise after set_flam_vert: dzi ', dzi !WRITE(*,*) 'plumerise after set_flam_vert: eburn_in(2) ', eburn_in(2) @@ -220,7 +211,7 @@ subroutine plumerise(data,m1,m2,m3,ia,iz,ja,jz, & end subroutine plumerise !------------------------------------------------------------------------- -subroutine get_env_condition(coms,k1,k2,kmt,wind_eff,ktau,g,cp,rgas,cpor,errmsg,errflg) +subroutine get_env_condition(coms,k1,k2,kmt,wind_eff,g,cp,rgas,cpor,errmsg,errflg) !se module_zero_plumegen_coms !use rconstants @@ -232,11 +223,11 @@ subroutine get_env_condition(coms,k1,k2,kmt,wind_eff,ktau,g,cp,rgas,cpor,errmsg, real(kind=kind_phys),parameter :: p00=p1000mb real(kind=kind_phys) :: znz,themax,tlll,plll,rlll,zlll,dzdd,dzlll,tlcl,plcl,dzlcl,dummy !integer :: n_setgrid = 0 -integer :: wind_eff,ktau +integer :: wind_eff character(*), intent(inout) :: errmsg integer, intent(inout) :: errflg -if(ktau==2) then +if(.not.coms%initialized) then ! n_setgrid = 1 call set_grid(coms) ! define vertical grid of plume model ! coms%zt(k) = thermo and water levels @@ -348,6 +339,8 @@ subroutine set_grid(coms) coms%dzt(k) = 1. / (coms%zm(k) - coms%zm(k-1)) enddo coms%dzt(1) = coms%dzt(2) * coms%dzt(2) / coms%dzt(3) + +coms%initialized = .true. ! coms%dzm(1) = 0.5/coms%dz ! coms%dzm(2:mzp) = 1./coms%dz @@ -447,27 +440,15 @@ subroutine get_fire_properties(coms,imm,iveg_ag,burnt_area,FRP,errmsg,errflg) type(plumegen_coms), pointer :: coms integer :: moist, i, icount,imm,iveg_ag !,plumerise_flag real(kind=kind_phys):: bfract, effload, heat, hinc ,burnt_area,heat_fluxW,FRP -real(kind=kind_phys), dimension(2,4) :: heat_flux +!real(kind=kind_phys), dimension(2,4) :: heat_flux integer, intent(inout) :: errflg character(*), intent(inout) :: errmsg -INTEGER, parameter :: use_last = 0 +INTEGER, parameter :: use_last = 1 ! RAR 10/31/2022: I set to one, checking with Saulo + !real(kind=kind_phys), parameter :: beta = 5.0 !ref.: Wooster et al., 2005 REAL(kind=kind_phys), parameter :: beta = 0.88 !ref.: Paugam et al., 2015 -data heat_flux/ & -!--------------------------------------------------------------------- -! heat flux !IGBP Land Cover ! -! min ! max !Legend and ! reference -! kW/m^2 !description ! -!-------------------------------------------------------------------- -30.0, 80.0, &! Tropical Forest ! igbp 2 & 4 -30.0, 80.0, &! Boreal(kind=kind_phys) forest ! igbp 1 & 3 -4.4, 23.0, &! cerrado/woody savanna | igbp 5 thru 9 -3.3, 3.3 /! Grassland/cropland ! igbp 10 thru 17 -!-------------------------------------------------------------------- -!-- fire at surface -! -!coms%area = 20.e+4 ! area of burn, m^2 +! coms%area = burnt_area! area of burn, m^2 !IF ( PLUMERISE_flag == 1) THEN @@ -556,7 +537,7 @@ subroutine get_fire_properties(coms,imm,iveg_ag,burnt_area,FRP,errmsg,errflg) COMS%HEATING (ICOUNT) = heat_fluxW * 0.55 ! W/m**2 (0.55 converte para energia convectiva) ICOUNT = ICOUNT + 1 ENDDO -! ramp for 5 minutes +! ramp for 5 minutes, RAR: in the current version this is inactive IF(use_last /= 1) THEN HINC = COMS%HEATING (1) / 4. @@ -565,15 +546,14 @@ subroutine get_fire_properties(coms,imm,iveg_ag,burnt_area,FRP,errmsg,errflg) COMS%HEATING (3) = 2. * HINC COMS%HEATING (4) = 3. * HINC ELSE + HINC = COMS%HEATING (1) / 4. ! RAR: this needs to be revised later IF(imm==1) THEN - HINC = COMS%HEATING (1) / 4. + !HINC = COMS%HEATING (1) / 4. COMS%HEATING (1) = 0.1 COMS%HEATING (2) = HINC COMS%HEATING (3) = 2. * HINC COMS%HEATING (4) = 3. * HINC ELSE - HINC = (COMS%HEATING (1) - heat_flux(imm-1,iveg_ag) * 1000. *0.55)/ 4. - COMS%HEATING (1) = heat_flux(imm-1,iveg_ag) * 1000. *0.55 + 0.1 COMS%HEATING (2) = COMS%HEATING (1)+ HINC COMS%HEATING (3) = COMS%HEATING (2)+ HINC COMS%HEATING (4) = COMS%HEATING (3)+ HINC diff --git a/physics/smoke_dust/module_wetdep_ls.F90 b/physics/smoke_dust/module_wetdep_ls.F90 new file mode 100755 index 000000000..87212920b --- /dev/null +++ b/physics/smoke_dust/module_wetdep_ls.F90 @@ -0,0 +1,79 @@ +!>\file module_wetdep_ls.F90 +!! This file contains aerosol wet deposition module. + +module module_wetdep_ls + use machine , only : kind_phys + use rrfs_smoke_config, only : p_qc, alpha => wetdep_ls_alpha + +contains +subroutine wetdep_ls(dt,var,rain,moist, & + rho,nchem,num_moist,dz8w,vvel, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) + implicit none + + integer, intent(in) :: nchem, num_moist, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte + real(kind_phys), intent(in) :: dt + real(kind_phys), dimension( ims:ime, kms:kme, jms:jme, num_moist),intent(in) :: moist + real(kind_phys), dimension( ims:ime, kms:kme, jms:jme),intent(in) :: rho,dz8w,vvel + real(kind_phys), dimension( ims:ime, kms:kme, jms:jme,1:nchem),intent(inout) :: var + real(kind_phys), dimension( ims:ime, jms:jme),intent(in) :: rain + real(kind_phys), dimension( its:ite, jts:jte) :: var_sum,var_rmv + real(kind_phys), dimension( its:ite, kts:kte, jts:jte) :: var_rmvl + real(kind_phys), dimension( its:ite, jts:jte) :: frc,var_sum_clw,rain_clw + real(kind_phys) :: dvar,factor,clsum + integer :: nv,i,j,k,km,kb,kbeg + !real(kind_phys), parameter :: alpha = .5 ! scavenging factor + + + do nv=1,nchem + do i=its,ite + do j=jts,jte + var_sum_clw(i,j)=0. + var_sum(i,j)=0. + var_rmvl(i,:,j)=0. + frc(i,j)=0. + rain_clw(i,j)=0. + if(rain(i,j).gt.1.e-10)then +! convert rain back to rate +! + rain_clw(i,j)=rain(i,j)/dt +! total cloud water +! + do k=1,kte-1 + dvar=max(0.,moist(i,k,j,p_qc)*rho(i,k,j)*vvel(i,k,j)*dz8w(i,k,j)) + var_sum_clw(i,j)=var_sum_clw(i,j)+dvar + var_sum(i,j)=var_sum(i,j)+var(i,k,j,nv)*rho(i,k,j) + enddo + if(var_sum(i,j).gt.1.e-10 .and. var_sum_clw(i,j).gt.1.e-10 ) then +! assuming that frc is onstant, it is my conversion factor +! (just like in convec. parameterization) + frc(i,j)=rain_clw(i,j)/var_sum_clw(i,j) + frc(i,j)=max(1.e-6,min(frc(i,j),.005)) + endif + endif + enddo + enddo +! +! get rid of it +! + do i=its,ite + do j=jts,jte + if(rain(i,j).gt.1.e-10 .and. var_sum(i,j).gt.1.e-10 .and. var_sum_clw(i,j).gt.1.e-10)then + do k=kts,kte-2 + if(var(i,k,j,nv).gt.1.e-16 .and. moist(i,k,j,p_qc).gt.0.)then + factor = max(0.,frc(i,j)*rho(i,k,j)*dz8w(i,k,j)*vvel(i,k,j)) + dvar=alpha*factor/(1+factor)*var(i,k,j,nv) + var(i,k,j,nv)=max(1.e-16,var(i,k,j,nv)-dvar) + endif + enddo + endif + enddo + enddo + enddo ! nv +end subroutine wetdep_ls +end module module_wetdep_ls diff --git a/smoke/module_zero_plumegen_coms.F90 b/physics/smoke_dust/module_zero_plumegen_coms.F90 similarity index 88% rename from smoke/module_zero_plumegen_coms.F90 rename to physics/smoke_dust/module_zero_plumegen_coms.F90 index 622d6a813..92b9ca2dc 100755 --- a/smoke/module_zero_plumegen_coms.F90 +++ b/physics/smoke_dust/module_zero_plumegen_coms.F90 @@ -9,6 +9,8 @@ module module_zero_plumegen_coms integer, parameter :: nkp = 200, ntime = 200 type plumegen_coms + logical :: initialized = .false. + real(kind=kind_phys),dimension(nkp) :: w,t,qv,qc,qh,qi,sc, & ! blob vth,vti,rho,txs, & est,qsat! never used: ,qpas,qtotal @@ -55,38 +57,28 @@ module module_zero_plumegen_coms procedure :: set_to_zero => plumegen_coms_zero end type plumegen_coms - interface plumegen_coms - procedure :: plumegen_coms_constructor - end interface plumegen_coms - - type(plumegen_coms), private, target :: private_thread_coms - logical, private :: mzpc_initialized = .false. + type(plumegen_coms), private, pointer :: private_thread_coms !$OMP THREADPRIVATE(private_thread_coms) -!$OMP THREADPRIVATE(mzpc_initialized) contains function get_thread_coms() result(coms) implicit none class(plumegen_coms), pointer :: coms - if(.not.mzpc_initialized) then - private_thread_coms = plumegen_coms() - mzpc_initialized = .true. + if(.not.associated(private_thread_coms)) then + allocate(private_thread_coms) + call plumegen_coms_zero(private_thread_coms) endif coms => private_thread_coms end function get_thread_coms - type(plumegen_coms) function plumegen_coms_constructor() result(this) - implicit none - call plumegen_coms_zero(this) - this%testval=3314 - end function plumegen_coms_constructor - subroutine plumegen_coms_zero(this) implicit none class(plumegen_coms) :: this + this%initialized = .false. + this%w=0.0 this%t=0.0 this%qv=0.0 diff --git a/smoke/plume_data_mod.F90 b/physics/smoke_dust/plume_data_mod.F90 similarity index 100% rename from smoke/plume_data_mod.F90 rename to physics/smoke_dust/plume_data_mod.F90 diff --git a/smoke/rrfs_smoke_config.F90 b/physics/smoke_dust/rrfs_smoke_config.F90 similarity index 66% rename from smoke/rrfs_smoke_config.F90 rename to physics/smoke_dust/rrfs_smoke_config.F90 index 43b3aee14..58d4c5846 100755 --- a/smoke/rrfs_smoke_config.F90 +++ b/physics/smoke_dust/rrfs_smoke_config.F90 @@ -16,59 +16,30 @@ module rrfs_smoke_config !-- constant paramters real(kind=kind_phys), parameter :: epsilc = 1.e-12 - !-- chemistyr module configurations + !-- aerosol module configurations integer :: chem_opt = 1 integer :: kemit = 1 integer :: dust_opt = 5 - integer :: dmsemis_opt = 1 integer :: seas_opt = 2 - integer :: biomass_burn_opt=1 logical :: do_plumerise = .true. integer :: addsmoke_flag = 1 - integer :: plumerisefire_frq=60 ! Let's add to the namelist - integer :: chem_conv_tr = 0 - integer :: aer_ra_feedback=1 !0 - integer :: aer_ra_frq = 60 + integer :: plumerisefire_frq=60 integer :: wetdep_ls_opt = 1 integer :: drydep_opt = 1 + integer :: coarsepm_settling = 1 logical :: bb_dcycle = .false. - logical :: smoke_forecast = .false. logical :: aero_ind_fdb = .false. logical :: dbg_opt = .true. - - real(kind=kind_phys), parameter :: depo_fact=0. - integer, parameter :: CHEM_OPT_GOCART= 1 - INTEGER, PARAMETER :: gocartracm_kpp = 301 - integer, parameter :: chem_tune_tracers = 20 - integer, parameter :: DUST_OPT_NONE = 0 - integer, parameter :: SEAS_OPT_NONE = 0 - ! -- DMS emissions - integer, parameter :: DMSE_OPT_NONE = 0 - integer, parameter :: DMSE_OPT_ENABLE = 1 - ! -- subgrid convective transport - integer, parameter :: CTRA_OPT_NONE = 0 - integer, parameter :: CTRA_OPT_GRELL = 2 - ! -- large scale wet deposition - integer, parameter :: WDLS_OPT_NONE = 0 - integer, parameter :: WDLS_OPT_GSD = 1 - integer, parameter :: WDLS_OPT_NGAC = 2 + integer :: smoke_forecast = 0 ! 0 read in ebb_smoke(i,24) + real(kind_phys) :: wetdep_ls_alpha = .5 ! scavenging factor ! -- + integer, parameter :: CHEM_OPT_GOCART= 1 integer, parameter :: call_chemistry = 1 integer, parameter :: num_moist=3, num_chem=20, num_emis_seas=5, num_emis_dust=5 - integer, parameter :: num_emis_ant = 7 - integer, parameter :: SEAS_OPT_DEFAULT = 1 - - integer, parameter :: DUST_OPT_GOCART = 1 - integer, parameter :: DUST_OPT_AFWA = 3 integer, parameter :: DUST_OPT_FENGSHA = 5 - ! -- biomass burning emissions - integer, parameter :: BURN_OPT_ENABLE = 1 - integer, parameter :: FIRE_OPT_MODIS = 1 - integer, parameter :: FIRE_OPT_GBBEPx = 2 - ! -- hydrometeors integer, parameter :: p_qv=1 integer, parameter :: p_qc=2 @@ -77,12 +48,9 @@ module rrfs_smoke_config ! -- FV3 GFDL microphysics integer, parameter :: p_atm_shum = 1 integer, parameter :: p_atm_cldq = 2 - integer, parameter :: p_atm_o3mr = 7 integer :: numgas = 0 - real(kind=kind_phys) :: wetdep_ls_alpha(chem_tune_tracers)=-999. - !-- tracers integer, parameter :: p_so2=1 integer, parameter :: p_sulf=2 @@ -97,7 +65,7 @@ module rrfs_smoke_config integer, parameter :: p_dust_2=11 integer, parameter :: p_dust_3=12 integer, parameter :: p_dust_4=13 - integer, parameter :: p_dust_5=14 + integer, parameter :: p_dust_5=14, p_coarse_pm=14 integer, parameter :: p_seas_1=15 integer, parameter :: p_seas_2=16 integer, parameter :: p_seas_3=17 diff --git a/smoke/rrfs_smoke_postpbl.F90 b/physics/smoke_dust/rrfs_smoke_postpbl.F90 similarity index 66% rename from smoke/rrfs_smoke_postpbl.F90 rename to physics/smoke_dust/rrfs_smoke_postpbl.F90 index f83aaf795..220284dbb 100755 --- a/smoke/rrfs_smoke_postpbl.F90 +++ b/physics/smoke_dust/rrfs_smoke_postpbl.F90 @@ -5,7 +5,6 @@ module rrfs_smoke_postpbl use machine , only : kind_phys - use rrfs_smoke_config implicit none @@ -15,26 +14,22 @@ module rrfs_smoke_postpbl contains -!>\defgroup rrfs_smoke_postpbl GSD Chem emission driver Module -!> \ingroup gsd_chem_group -!! This is the GSD Chem emission driver Module -!! \section arg_table_rrfs_smoke_postpbl_run Argument Table +!> \section arg_table_rrfs_smoke_postpbl_run Argument Table !! \htmlinclude rrfs_smoke_postpbl_run.html !! -!>\section rrfs_smoke_postpbl GSD Chemistry Scheme General Algorithm -!> @{ - subroutine rrfs_smoke_postpbl_run(ite, kte, ntsmoke, ntdust, ntrac, & - qgrs, chem3d, errmsg, errflg) + subroutine rrfs_smoke_postpbl_run(ite, kte, ntsmoke, ntdust, ntcoarsepm, ntrac, & + qgrs, chem3d, rrfs_sd, errmsg, errflg) implicit none - integer, intent(in) :: ite,kte,ntsmoke,ntdust,ntrac + integer, intent(in) :: ite,kte,ntsmoke,ntdust,ntcoarsepm,ntrac integer, parameter :: its=1,kts=1 real(kind_phys), dimension(:,:,:), intent(inout) :: qgrs real(kind_phys), dimension(:,:,:), intent(inout) :: chem3d + logical, intent(in) :: rrfs_sd character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -44,16 +39,20 @@ subroutine rrfs_smoke_postpbl_run(ite, kte, ntsmoke, ntdust, ntrac, & errmsg = '' errflg = 0 + if (.not. rrfs_sd) return + !--- put smoke stuff back into tracer array do k=kts,kte do i=its,ite qgrs(i,k,ntsmoke)= chem3d(i,k,1) qgrs(i,k,ntdust )= chem3d(i,k,2) + qgrs(i,k,ntcoarsepm)= chem3d(i,k,3) enddo enddo - end subroutine rrfs_smoke_postpbl_run + return + + end subroutine rrfs_smoke_postpbl_run -!> @} end module rrfs_smoke_postpbl diff --git a/smoke/rrfs_smoke_postpbl.meta b/physics/smoke_dust/rrfs_smoke_postpbl.meta similarity index 69% rename from smoke/rrfs_smoke_postpbl.meta rename to physics/smoke_dust/rrfs_smoke_postpbl.meta index 99aae69f2..50f7afae7 100755 --- a/smoke/rrfs_smoke_postpbl.meta +++ b/physics/smoke_dust/rrfs_smoke_postpbl.meta @@ -1,11 +1,11 @@ [ccpp-table-properties] - name = rrfs_smoke_wrapper + name = rrfs_smoke_postpbl type = scheme - dependencies = dep_dry_gocart_mod.F90,dep_dry_mod.F90,dep_simple_mod.F90,dep_vertmx_mod.F90,dep_wet_ls_mod.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,rrfs_smoke_data.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90 + dependencies = dep_dry_mod.F90,module_wetdep_ls.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90 ######################################################################## [ccpp-arg-table] - name = rrfs_smoke_wrapper_run + name = rrfs_smoke_postpbl_run type = scheme [ite] standard_name = horizontal_loop_extent @@ -35,6 +35,13 @@ dimensions = () type = integer intent = in +[ntcoarsepm] + standard_name = index_for_coarse_particulate_matter_in_tracer_concentration_array + long_name = tracer index for coarse particulate matter + units = index + dimensions = () + type = integer + intent = in [ntrac] standard_name = number_of_tracers long_name = number of tracers @@ -54,10 +61,17 @@ standard_name = chem3d_mynn_pbl_transport long_name = mynn pbl transport of smoke and dust units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension,2) + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_chemical_species_vertically_mixed) type = real kind = kind_phys intent = inout +[rrfs_sd] + standard_name = do_smoke_coupling + long_name = flag controlling rrfs_sd collection (default off) + units = flag + dimensions = () + type = logical + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/smoke/rrfs_smoke_wrapper.F90 b/physics/smoke_dust/rrfs_smoke_wrapper.F90 similarity index 63% rename from smoke/rrfs_smoke_wrapper.F90 rename to physics/smoke_dust/rrfs_smoke_wrapper.F90 index ac32e1ad4..1f9ef6340 100755 --- a/smoke/rrfs_smoke_wrapper.F90 +++ b/physics/smoke_dust/rrfs_smoke_wrapper.F90 @@ -1,19 +1,26 @@ !>\file rrfs_smoke_wrapper.F90 -!! This file is CCPP RRFS smoke driver +!! This file is CCPP driver of RRFS Smoke and Dust !! Haiqin.Li@noaa.gov 02/2021 module rrfs_smoke_wrapper - use machine , only : kind_phys - use rrfs_smoke_config - use dust_data_mod - use seas_mod, only : gocart_seasalt_driver - use dust_fengsha_mod,only : gocart_dust_fengsha_driver - use plume_data_mod - use module_plumerise1 !plume_rise_mod - use module_add_emiss_burn - use dep_dry_mod - use rrfs_smoke_data + use machine , only : kind_phys + use rrfs_smoke_config, only : kemit, dust_opt, seas_opt, do_plumerise, & + addsmoke_flag, plumerisefire_frq, wetdep_ls_opt, & + drydep_opt, coarsepm_settling, aero_ind_fdb, & + dbg_opt, smoke_forecast, wetdep_ls_alpha, & + num_moist, num_chem, num_emis_seas, num_emis_dust, & + DUST_OPT_FENGSHA, p_qv, p_atm_shum, p_atm_cldq, & + p_smoke, p_dust_1, p_coarse_pm, epsilc + use dust_data_mod, only : dust_alpha, dust_gamma + use plume_data_mod, only : p_frp_std, p_frp_hr, num_frp_plume + use seas_mod, only : gocart_seasalt_driver + use dust_fengsha_mod, only : gocart_dust_fengsha_driver + use dep_dry_mod, only : dry_dep_driver + use module_wetdep_ls, only : wetdep_ls + use module_plumerise1, only : ebu_driver + use module_add_emiss_burn, only : add_emis_burn + use coarsepm_settling_mod, only : coarsepm_settling_driver implicit none @@ -23,36 +30,39 @@ module rrfs_smoke_wrapper contains -!>\defgroup rrfs_smoke_wrapper GSD Chem emission driver Module +!>\defgroup rrfs_smoke_wrapper rrfs-sd emission driver Module !> \ingroup gsd_chem_group -!! This is the GSD Chem emission driver Module +!! This is the rrfs-sd emission driver Module !! \section arg_table_rrfs_smoke_wrapper_run Argument Table !! \htmlinclude rrfs_smoke_wrapper_run.html !! -!>\section rrfs_smoke_wrapper GSD Chemistry Scheme General Algorithm +!>\section rrfs_smoke_wrapper rrfs-sd Scheme General Algorithm !> @{ - subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, & - u10m, v10m, ustar, rlat, rlon, tskin, pb2d, t2m, dpt2m, & - pr3d, ph3d,phl3d, prl3d, tk3d, us3d, vs3d, spechum, w, & - nsoil, smc, vegtype, soiltyp, sigmaf, dswsfc, zorl,snow, & - julian, idat, rain_cpl, rainc_cpl, exch, hf2d, g, pi, con_cp, con_rd, & - dust12m_in, emi_in, smoke_GBBEPx, ntrac, qgrs, gq0, chem3d, tile_num, & - ntsmoke, ntdust, imp_physics, imp_physics_thompson, & - nwfa, nifa, emanoc, & - emdust, emseas, ebb_smoke_hr, frp_hr, frp_std_hr, & - coef_bb, ebu_smoke,fhist, min_fplume, max_fplume, hwp, & - smoke_ext, dust_ext, & - seas_opt_in, dust_opt_in, biomass_burn_opt_in, drydep_opt_in, & - do_plumerise_in, plumerisefire_frq_in, addsmoke_flag_in, & + subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, & + u10m, v10m, ustar, rlat, rlon, tskin, pb2d, t2m, dpt2m, & + pr3d, ph3d,phl3d, prl3d, tk3d, us3d, vs3d, spechum, w, & + nsoil, smc, vegtype, soiltyp, sigmaf, dswsfc, zorl, snow, julian, & + idat, rain_cpl, rainc_cpl, exch, hf2d, g, pi, con_cp, con_rd, con_fv, & + dust12m_in, emi_in, smoke_RRFS, ntrac, qgrs, gq0, chem3d, tile_num, & + ntsmoke, ntdust, ntcoarsepm, imp_physics, imp_physics_thompson, & + nwfa, nifa, emanoc, emdust, emseas, & + ebb_smoke_hr, frp_hr, frp_std_hr, & + coef_bb, ebu_smoke,fhist, min_fplume, max_fplume, hwp, wetness, & + smoke_ext, dust_ext, ndvel, ddvel_inout,rrfs_sd, & + dust_alpha_in, dust_gamma_in, fire_in, & + seas_opt_in, dust_opt_in, drydep_opt_in, coarsepm_settling_in, & + do_plumerise_in, plumerisefire_frq_in, addsmoke_flag_in, & + wetdep_ls_opt_in,wetdep_ls_alpha_in, & smoke_forecast_in, aero_ind_fdb_in,dbg_opt_in,errmsg,errflg) implicit none integer, intent(in) :: im,kte,kme,ktau,nsoil,tile_num,jdate(8),idat(8) - integer, intent(in) :: ntrac, ntsmoke, ntdust - real(kind_phys),intent(in) :: dt, julian, g, pi, con_cp, con_rd - logical, intent(in) :: smoke_forecast_in,aero_ind_fdb_in,dbg_opt_in + integer, intent(in) :: ntrac, ntsmoke, ntdust, ntcoarsepm, ndvel + real(kind_phys),intent(in) :: dt, julian, g, pi, con_cp, con_rd, con_fv + logical, intent(in) :: aero_ind_fdb_in,dbg_opt_in + integer, intent(in) :: smoke_forecast_in integer, parameter :: ids=1,jds=1,jde=1, kds=1 integer, parameter :: ims=1,jms=1,jme=1, kms=1 @@ -61,10 +71,10 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, integer, dimension(:), intent(in) :: land, vegtype, soiltyp real(kind_phys), dimension(:,:), intent(in) :: smc real(kind_phys), dimension(:,:,:), intent(in) :: dust12m_in - real(kind_phys), dimension(:,:,:), intent(in) :: smoke_GBBEPx + real(kind_phys), dimension(:,:,:), intent(in) :: smoke_RRFS real(kind_phys), dimension(:,:), intent(in) :: emi_in - real(kind_phys), dimension(:), intent(in) :: u10m, v10m, ustar, dswsfc, & - garea, rlat,rlon, tskin, pb2d, sigmaf, zorl, snow, & + real(kind_phys), dimension(:), intent(in) :: u10m, v10m, ustar, dswsfc, & + garea, rlat,rlon, tskin, pb2d, sigmaf, zorl, snow, & rain_cpl, rainc_cpl, hf2d, t2m, dpt2m real(kind_phys), dimension(:,:), intent(in) :: ph3d, pr3d real(kind_phys), dimension(:,:), intent(in) :: phl3d, prl3d, tk3d, & @@ -75,14 +85,19 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, real(kind_phys), dimension(:), intent(inout) :: ebb_smoke_hr, frp_hr, frp_std_hr real(kind_phys), dimension(:), intent(inout) :: coef_bb, fhist real(kind_phys), dimension(:,:), intent(inout) :: ebu_smoke + real(kind_phys), dimension(:,:), intent(inout) :: fire_in real(kind_phys), dimension(:), intent(inout) :: max_fplume, min_fplume real(kind_phys), dimension(:), intent( out) :: hwp real(kind_phys), dimension(:,:), intent(out) :: smoke_ext, dust_ext real(kind_phys), dimension(:,:), intent(inout) :: nwfa, nifa + real(kind_phys), dimension(:,:), intent(inout) :: ddvel_inout + real (kind=kind_phys), dimension(:), intent(in) :: wetness integer, intent(in ) :: imp_physics, imp_physics_thompson - integer, intent(in) :: seas_opt_in, dust_opt_in, biomass_burn_opt_in, & - drydep_opt_in, plumerisefire_frq_in, addsmoke_flag_in - logical, intent(in ) :: do_plumerise_in + real (kind=kind_phys), intent(in) :: dust_alpha_in, dust_gamma_in, wetdep_ls_alpha_in + integer, intent(in) :: seas_opt_in, dust_opt_in, drydep_opt_in, & + coarsepm_settling_in, plumerisefire_frq_in, & + addsmoke_flag_in, wetdep_ls_opt_in + logical, intent(in ) :: do_plumerise_in, rrfs_sd character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -97,7 +112,6 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, real(kind_phys), dimension(ims:im, kms:kme, jms:jme, 1:num_moist) :: moist real(kind_phys), dimension(ims:im, kms:kme, jms:jme, 1:num_chem ) :: chem real(kind_phys), dimension(ims:im, 1, jms:jme, 1:num_emis_seas ) :: emis_seas - real(kind_phys), dimension(ims:im, jms:jme, 1:num_chem ) :: dry_fall real(kind_phys), dimension(ims:im, jms:jme) :: seashelp integer :: ide, ime, ite, kde, julday @@ -115,22 +129,18 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, real(kind_phys), dimension(ims:im, jms:jme, num_frp_plume ) :: plume_frp real(kind_phys), dimension(ims:im, jms:jme ) :: coef_bb_dc, flam_frac, & fire_hist, peak_hr - real(kind_phys), dimension(ims:im,kms:kme,jms:jme ) :: aod3d_smoke, aod3d_dust + real(kind_phys), dimension(ims:im,kms:kme,jms:jme ) :: ext3d_smoke, ext3d_dust integer, dimension(ims:im, jms:jme ) :: min_fplume2, max_fplume2 - real(kind_phys) :: dtstep - logical :: call_plume, scale_fire_emiss + logical :: call_fire !>- optical variables real(kind_phys), dimension(ims:im, kms:kme, jms:jme) :: rel_hum + real(kind_phys), dimension(ims:im, jms:jme, ndvel) :: ddvel !>-- anthropogentic variables -! real(kind_phys), dimension(ims:im, kms:kemit, jms:jme, 1:num_emis_ant) :: emis_ant real(kind_phys), dimension(ims:im) :: emis_anoc - - real(kind_phys), dimension(ims:im, kms:kme, jms:jme) :: ac3, ahno3, anh3, asulf, cor3, h2oai, h2oaj, nu3 - real(kind_phys), dimension(ims:im, jms:jme) :: dep_vel_o3, e_co + real(kind_phys), dimension(ims:im, jms:jme, 1) :: sedim real(kind_phys) :: gmt - real(kind_phys), dimension(1:num_chem) :: ppm2ugkg !> -- parameter to caluclate wfa&ifa (m) real(kind_phys), parameter :: mean_diameter1= 4.E-8, sigma1=1.8 @@ -142,26 +152,23 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, real(kind_phys), parameter :: density_dust= 2.6e+3, density_sulfate=1.8e+3 real(kind_phys), parameter :: density_oc = 1.4e+3, density_seasalt=2.2e+3 - real(kind_phys) :: daero_emis_wfa, daero_emis_ifa + real(kind_phys), dimension(im) :: daero_emis_wfa, daero_emis_ifa !>-- local variables real(kind_phys), dimension(im) :: wdgust, snoweq - integer :: current_month, current_hour + integer :: current_month, current_hour, hour_int real(kind_phys) :: curr_secs real(kind_phys) :: factor, factor2, factor3 - integer :: nbegin, nv, nvv - integer :: i, j, jp, k, kp, n - - type(smoke_data), pointer :: data - - data => get_thread_smoke_data() + integer :: nbegin, nv + integer :: i, j, k, kp, n errmsg = '' errflg = 0 + if (.not. rrfs_sd) return + !>-- options to turn on/off sea-salt, dust, plume-rising seas_opt = seas_opt_in dust_opt = dust_opt_in - biomass_burn_opt = biomass_burn_opt_in drydep_opt = drydep_opt_in do_plumerise = do_plumerise_in plumerisefire_frq = plumerisefire_frq_in @@ -169,46 +176,42 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, smoke_forecast = smoke_forecast_in aero_ind_fdb = aero_ind_fdb_in dbg_opt = dbg_opt_in + wetdep_ls_opt = wetdep_ls_opt_in + wetdep_ls_alpha = wetdep_ls_alpha_in + coarsepm_settling = coarsepm_settling_in - !print*,'hli ktau',ktau ! -- set domain ide=im ime=im ite=im kde=kte - h2oai = 0. - h2oaj = 0. - nu3 = 0. - ac3 = 0. - cor3 = 0. - asulf = 0. - ahno3 = 0. - anh3 = 0. - e_co = 0. - dep_vel_o3 = 0. - min_fplume2 = 0 max_fplume2 = 0 emis_seas = 0. emis_dust = 0. peak_hr = 0. flam_frac = 0. - aod3d_smoke = 0. - aod3d_dust = 0. + ext3d_smoke = 0. + ext3d_dust = 0. + daero_emis_wfa = 0. + daero_emis_ifa = 0. rcav = 0. rnav = 0. curr_secs = ktau * dt - current_month=jdate(2) - current_hour =jdate(5)+1 - gmt = real(idat(5)) + current_month=jdate(2) ! needed for the dust input data + current_hour =jdate(5)+1 ! =1 at 00Z + hour_int=ktau*dt/3600. ! hours since the simulation start + gmt = real(mod(idat(5)+hour_int,24)) julday = int(julian) - ! -- volume to mass fraction conversion table (ppm -> ug/kg) - ppm2ugkg = 1._kind_phys - ppm2ugkg(p_sulf) = 1.e+03_kind_phys * mw_so4_aer / mwdry + do nv=1,ndvel + do i=its,ite + ddvel(i,1,nv)=ddvel_inout(i,nv) + enddo + enddo ! -- compute incremental convective and large-scale rainfall do i=its,ite @@ -220,35 +223,24 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, ! plumerise frequency in minutes set up by the namelist input - call_plume = (biomass_burn_opt == BURN_OPT_ENABLE) .and. (plumerisefire_frq > 0) - if (call_plume) & - call_plume = (mod(int(curr_secs), max(1, 60*plumerisefire_frq)) == 0) & - .or. (ktau == 2) + call_fire = (do_plumerise .and. (plumerisefire_frq > 0)) + if (call_fire) call_fire = (mod(int(curr_secs), max(1, 60*plumerisefire_frq)) == 0) .or. (ktau == 2) - !scale_fire_emiss = .false. - - ! -- compute accumulated large-scale and convective rainfall since last call - if (ktau > 1) then - dtstep = call_chemistry * dt - else - dtstep = dt - end if - !>- get ready for chemistry run call rrfs_smoke_prep( & - ktau, current_month, current_hour, & + current_month, current_hour, gmt, con_rd, con_fv, & u10m,v10m,ustar,land,garea,rlat,rlon,tskin, & pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,exch,w, & nsoil,smc,vegtype,soiltyp,sigmaf,dswsfc,zorl, & - snow,dust12m_in,emi_in,smoke_GBBEPx, & - hf2d, pb2d, g, pi, & + snow,dust12m_in,emi_in,smoke_RRFS, & + hf2d, pb2d, g, pi, hour_int, & u10,v10,ust,tsk,xland,xlat,xlong,dxy, & rri,t_phy,u_phy,v_phy,p_phy,rho_phy,dz8w,p8w, & t8w,exch_h, & z_at_w,vvel,zmid, & ntrac,gq0, & - num_chem, num_moist, ppm2ugkg, & - ntsmoke, ntdust, & + num_chem,num_moist, & + ntsmoke, ntdust,ntcoarsepm, & moist,chem,plume_frp,ebu_in, & ebb_smoke_hr, frp_hr, frp_std_hr, emis_anoc, & smois,ivgtyp,isltyp,vegfrac,rmol,swdown,znt,hfx,pbl, & @@ -259,25 +251,32 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, ! Make this global, calculate at 1st time step only !>-- for plumerise -- -!IF (ktau==1) THEN + do j=jts,jte do i=its,ite - if (xlong(i,j)<-130.) then + peak_hr(i,j)= fire_in(i,10) + enddo + enddo + + IF (ktau==1) THEN + do j=jts,jte + do i=its,ite + if (xlong(i,j)<230.) then peak_hr(i,j)= 0.0* 3600. ! peak at 24 UTC, fires in Alaska - elseif(xlong(i,j)<-115.) then + elseif(xlong(i,j)<245.) then peak_hr(i,j)= 23.0* 3600. - elseif (xlong(i,j)<-100.) then + elseif (xlong(i,j)<260.) then peak_hr(i,j)= 22.0* 3600. ! peak at 22 UTC, fires in the western US - elseif (xlong(i,j)<-85.) then + elseif (xlong(i,j)<275.) then peak_hr(i,j)= 21.0* 3600. - elseif (xlong(i,j)<-70.) then ! peak at 20 UTC, fires in the eastern US + elseif (xlong(i,j)<290.) then ! peak at 20 UTC, fires in the eastern US peak_hr(i,j)= 20.0* 3600. else peak_hr(i,j)= 19.0* 3600. endif enddo enddo -!END IF + ENDIF IF (ktau==1) THEN ebu = 0. @@ -299,29 +298,30 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, !>- compute sea-salt - ! -- compute sea salt - if (seas_opt >= SEAS_OPT_DEFAULT) then - call gocart_seasalt_driver(ktau,dt,rri,t_phy,moist, & + ! -- compute sea salt (opt=2) + if (seas_opt == 2) then + call gocart_seasalt_driver(dt,rri,t_phy, & u_phy,v_phy,chem,rho_phy,dz8w,u10,v10,ust,p8w,tsk, & xland,xlat,xlong,dxy,g,emis_seas,pi, & - seashelp,num_emis_seas,num_moist,num_chem,seas_opt, & + seashelp,num_emis_seas,num_chem,seas_opt, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte) endif - !-- compute dust - select case (dust_opt) - case (DUST_OPT_FENGSHA) + !-- compute dust (opt=5) + if (dust_opt==DUST_OPT_FENGSHA) then ! Set at compile time in dust_data_mod: - call gocart_dust_fengsha_driver(data,dt,chem,rho_phy,smois,p8w,ssm, & + dust_alpha = dust_alpha_in + dust_gamma = dust_gamma_in + call gocart_dust_fengsha_driver(dt,chem,rho_phy,smois,p8w,ssm, & isltyp,vegfrac,snowh,xland,dxy,g,emis_dust,ust,znt, & clayf,sandf,rdrag,uthr, & - num_emis_dust,num_moist,num_chem,nsoil, & + num_emis_dust,num_chem,nsoil, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte) - end select + end if ! compute wild-fire plumes !-- to add a namelist option to turn on/off plume raising @@ -329,13 +329,12 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, !-- /scratch2/BMC/ap-fc/Ravan/rapid-refresh/WRFV3.9/smoke ! Every hour (per namelist) the ebu_driver is called to calculate ebu, but ! the plumerise is controlled by the namelist option of plumerise_flag - if (call_plume) then -! WRITE(*,*) 'plumerise is called at ktau= ',ktau + if (call_fire) then call ebu_driver ( & - data,flam_frac,ebu_in,ebu, & + flam_frac,ebu_in,ebu, & t_phy,moist(:,:,:,p_qv), & rho_phy,vvel,u_phy,v_phy,p_phy, & - z_at_w,zmid,ktau,g,con_cp,con_rd, & + z_at_w,zmid,g,con_cp,con_rd, & plume_frp, min_fplume2, max_fplume2, & ! new approach ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & @@ -345,34 +344,52 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, ! -- add biomass burning emissions at every timestep if (addsmoke_flag == 1) then - call add_emis_burn(data,dtstep,ktau,dz8w,rho_phy,rel_hum,chem, & + call add_emis_burn(dt,dz8w,rho_phy,rel_hum,chem, & julday,gmt,xlat,xlong, & ivgtyp, vegfrac, peak_hr, & ! RAR curr_secs,ebu, & - coef_bb_dc,fire_hist,aod3d_smoke,aod3d_dust, & - ! scalar(ims,kms,jms,P_QNWFA),scalar(ims,kms,jms,P_QNIFA), ! & + coef_bb_dc,fire_hist,ext3d_smoke,ext3d_dust, & rcav, rnav,swdown,smoke_forecast, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte ) endif -! WRITE(*,*) 'after add_emis_burn at ktau= ',ktau + !>-- compute coarsepm setting + if (coarsepm_settling == 1) then + call coarsepm_settling_driver(dt,t_phy,rel_hum, & + chem(:,:,:,p_coarse_pm), & + rho_phy,dz8w,p8w,p_phy,sedim, & + dxy,g,1, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) + endif !>-- compute dry deposition if (drydep_opt == 1) then - call dry_dep_driver(data,ktau,dt,julday,current_month,t_phy,p_phy, & - moist,p8w,rmol,rri,gmt,t8w,rcav, & - chem,rho_phy,dz8w,exch_h,hfx, & - ivgtyp,tsk,swdown,vegfrac,pbl,ust,znt,zmid,z_at_w, & - xland,xlat,xlong,h2oaj,h2oai,nu3,ac3,cor3,asulf,ahno3, & - anh3,dry_fall,dep_vel_o3,g, & - e_co,kemit,snowh,numgas, & - num_chem,num_moist, & + + call dry_dep_driver(rmol,ust,ndvel,ddvel,rel_hum, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte) + + do nv=1,ndvel + do i=its,ite + ddvel_inout(i,nv)=ddvel(i,1,nv) + enddo + enddo + else + ddvel_inout(:,:)=0. + endif + +!>- large-scale wet deposition + if (wetdep_ls_opt == 1) then + call wetdep_ls(dt,chem,rnav,moist, & + rho_phy,num_chem,num_moist,dz8w,vvel, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte) endif -! WRITE(*,*) 'dry depostion is done at ktau= ',ktau do k=kts,kte do i=its,ite @@ -384,95 +401,100 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, !---- diagnostic output of hourly wildfire potential (07/2021) hwp = 0. do i=its,ite - wdgust(i)=1.68*sqrt(us3d(i,1)**2+vs3d(i,1)**2) - snoweq(i)=max((25.-snow(i)*1000.)/25.,0.) - !hwp(i)=44.09*wdgust(i)**1.82*max(0.,t2m(i)-dpt2m(i))**0.61*max(0.,1.-smc(i,1))**14.0*snoweq(i)*sigmaf(i) - hwp(i)=44.09*wdgust(i)**1.82*(t2m(i)-dpt2m(i))**0.61*(1.-smc(i,1))**14.0*snoweq(i)*sigmaf(i) + wdgust(i)=max(1.68*sqrt(us3d(i,1)**2+vs3d(i,1)**2),3.) + snoweq(i)=max((25.-snow(i))/25.,0.) + hwp(i)=0.237*wdgust(i)**1.11*max(t2m(i)-dpt2m(i),15.)**0.92*((1.-wetness(i))**6.95)*snoweq(i) ! Eric 08/2022 enddo !---- diagnostic output of smoke & dust optical extinction (12/2021) do k=kts,kte do i=its,ite - smoke_ext(i,k) = aod3d_smoke(i,k,1) - dust_ext (i,k) = aod3d_dust (i,k,1) + smoke_ext(i,k) = ext3d_smoke(i,k,1) + dust_ext (i,k) = ext3d_dust (i,k,1) enddo enddo !------------------------------------- !---- put smoke stuff back into tracer array do k=kts,kte do i=its,ite - gq0(i,k,ntsmoke )=ppm2ugkg(p_smoke ) * max(epsilc,chem(i,k,1,p_smoke)) ! - gq0(i,k,ntdust )=ppm2ugkg(p_dust_1) * max(epsilc,chem(i,k,1,p_dust_1)) + gq0(i,k,ntsmoke ) = min(5000.,max(epsilc,chem(i,k,1,p_smoke ))) + gq0(i,k,ntdust ) = min(200.,max(epsilc,chem(i,k,1,p_dust_1))) + gq0(i,k,ntcoarsepm)= min(5000.,max(epsilc,chem(i,k,1,p_coarse_pm))) enddo enddo do k=kts,kte do i=its,ite - qgrs(i,k,ntsmoke )= gq0(i,k,ntsmoke ) - qgrs(i,k,ntdust )= gq0(i,k,ntdust ) - chem3d(i,k,1 )= gq0(i,k,ntsmoke ) - chem3d(i,k,2 )= gq0(i,k,ntdust ) + qgrs(i,k,ntsmoke )= gq0(i,k,ntsmoke ) + qgrs(i,k,ntdust )= gq0(i,k,ntdust ) + qgrs(i,k,ntcoarsepm)= gq0(i,k,ntcoarsepm) + chem3d(i,k,1 )= gq0(i,k,ntsmoke ) + chem3d(i,k,2 )= gq0(i,k,ntdust ) + chem3d(i,k,3 )= gq0(i,k,ntcoarsepm) enddo enddo !------------------------------------- !-- to output for diagnostics -! WRITE(*,*) 'rrfs nwfa/nifa 1 at ktau= ',ktau do i = 1, im - emseas (i) = emis_seas (i,1,1,1)*1.e+9 ! size bin 1 sea salt emission: ug/m2/s - emdust (i) = emis_dust (i,1,1,1) ! size bin 1 dust emission : ug/m2/s - emanoc (i) = emis_anoc (i) ! anthropogenic organic carbon: ug/m2/s - coef_bb (i) = coef_bb_dc (i,1) - fhist (i) = fire_hist (i,1) + emseas (i) = emis_seas(i,1,1,1)*1.e+9 ! size bin 1 sea salt emission: ug/m2/s + emdust (i) = emis_dust(i,1,1,1) + emis_dust(i,1,1,2) + & + emis_dust(i,1,1,3) + emis_dust(i,1,1,4) ! dust emission: ug/m2/s + emanoc (i) = emis_anoc (i) ! anthropogenic organic carbon: ug/m2/s + coef_bb (i) = coef_bb_dc(i,1) + fhist (i) = fire_hist (i,1) min_fplume (i) = real(min_fplume2(i,1)) max_fplume (i) = real(max_fplume2(i,1)) + emseas (i) = sandf(i,1) ! sand for dust + emanoc (i) = uthr (i,1) ! u threshold for dust + enddo + + do i = 1, im + fire_in(i,10) = peak_hr(i,1) enddo -! WRITE(*,*) 'rrfs nwfa/nifa 2 at ktau= ',ktau !-- to provide real aerosol emission for Thompson MP if (imp_physics == imp_physics_thompson .and. aero_ind_fdb) then fact_wfa = 1.e-9*6.0/pi*exp(4.5*log(sigma1)**2)/mean_diameter1**3 fact_ifa = 1.e-9*6.0/pi*exp(4.5*log(sigma2)**2)/mean_diameter2**3 - do i = its, ite - do k = kts, kte - if (k==1)then - daero_emis_wfa =(emanoc(i)+ebu_smoke(i,k))/density_oc + emseas(i)/density_seasalt - else - daero_emis_wfa = ebu_smoke(i,k)/density_oc - endif - daero_emis_wfa = kappa_oc* daero_emis_wfa*fact_wfa*rri(i,k,1)/dz8w(i,k,1) ! consider using dust tracer + do i = 1, im + daero_emis_wfa(i) =(emanoc(i)+ebu_smoke(i,kemit))/density_oc + emseas(i)/density_seasalt + daero_emis_ifa(i) = emdust(i)/density_dust + + daero_emis_wfa(i) = daero_emis_wfa(i)*fact_wfa*rri(i,kemit,1)/dz8w(i,kemit,1) + daero_emis_ifa(i) = daero_emis_ifa(i)*fact_ifa*rri(i,kemit,1)/dz8w(i,kemit,1) - nwfa(i,k) = nwfa(i,k) + daero_emis_wfa*dt - nifa(i,k) = gq0(i,k,ntdust)/density_dust*fact_ifa*kappa_dust ! Check the formula + nwfa(i,kemit) = nwfa(i,kemit) + daero_emis_wfa(i)*dt + nifa(i,kemit) = nifa(i,kemit) + daero_emis_ifa(i)*dt if(land(i).eq.1)then - nwfa(i,k) = nwfa(i,k)*(1 - 0.10*dt/86400.) !-- mimicking dry deposition + nwfa(i,kemit) = nwfa(i,kemit)*(1. - 0.10*dt/86400.) !-- mimicking dry deposition + nifa(i,kemit) = nifa(i,kemit)*(1. - 0.10*dt/86400.) !-- mimicking dry deposition else - nwfa(i,k) = nwfa(i,k)*(1 - 0.05*dt/86400.) !-- mimicking dry deposition + nwfa(i,kemit) = nwfa(i,kemit)*(1. - 0.05*dt/86400.) !-- mimicking dry deposition + nifa(i,kemit) = nifa(i,kemit)*(1. - 0.05*dt/86400.) !-- mimicking dry deposition endif - enddo + nwfa(i,kemit) = MIN(2.E10,nwfa(i,kemit)) + nifa(i,kemit) = MIN(9999.E6,nifa(i,kemit)) enddo endif -! WRITE(*,*) 'rrfs smoke wrapper is done at ktau= ',ktau end subroutine rrfs_smoke_wrapper_run subroutine rrfs_smoke_prep( & - ktau,current_month,current_hour, & + current_month,current_hour,gmt,con_rd,con_fv, & u10m,v10m,ustar,land,garea,rlat,rlon,ts2d, & pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,exch,w, & nsoil,smc,vegtype,soiltyp,sigmaf,dswsfc,zorl, & - snow_cpl,dust12m_in,emi_in,smoke_GBBEPx, & - hf2d, pb2d, g, pi, & + snow_cpl,dust12m_in,emi_in,smoke_RRFS, & + hf2d, pb2d, g, pi, hour_int, & u10,v10,ust,tsk,xland,xlat,xlong,dxy, & rri,t_phy,u_phy,v_phy,p_phy,rho_phy,dz8w,p8w, & t8w,exch_h, & z_at_w,vvel,zmid, & ntrac,gq0, & - num_chem, num_moist, ppm2ugkg, & - ntsmoke, ntdust, & - !num_emis_ant, & - !emis_ant, & + num_chem, num_moist, & + ntsmoke, ntdust, ntcoarsepm, & moist,chem,plume_frp,ebu_in, & ebb_smoke_hr, frp_hr, frp_std_hr, emis_anoc, & smois,ivgtyp,isltyp,vegfrac,rmol,swdown,znt,hfx,pbl, & @@ -482,19 +504,19 @@ subroutine rrfs_smoke_prep( & its,ite, jts,jte, kts,kte) !Chem input configuration - integer, intent(in) :: ktau, current_month, current_hour + integer, intent(in) :: current_month, current_hour, hour_int !FV3 input variables integer, intent(in) :: nsoil integer, dimension(ims:ime), intent(in) :: land, vegtype, soiltyp integer, intent(in) :: ntrac - real(kind=kind_phys), intent(in) :: g, pi + real(kind=kind_phys), intent(in) :: g, pi, gmt, con_rd, con_fv real(kind=kind_phys), dimension(ims:ime), intent(in) :: & u10m, v10m, ustar, garea, rlat, rlon, ts2d, sigmaf, dswsfc, & zorl, snow_cpl, pb2d, hf2d real(kind=kind_phys), dimension(ims:ime, nsoil), intent(in) :: smc real(kind=kind_phys), dimension(ims:ime, 12, 5), intent(in) :: dust12m_in - real(kind=kind_phys), dimension(ims:ime, 24, 3), intent(in) :: smoke_GBBEPx + real(kind=kind_phys), dimension(ims:ime, 24, 3), intent(in) :: smoke_RRFS real(kind=kind_phys), dimension(ims:ime, 1), intent(in) :: emi_in real(kind=kind_phys), dimension(ims:ime, kms:kme), intent(in) :: pr3d,ph3d real(kind=kind_phys), dimension(ims:ime, kts:kte), intent(in) :: & @@ -502,16 +524,13 @@ subroutine rrfs_smoke_prep( & real(kind=kind_phys), dimension(ims:ime, kts:kte,ntrac), intent(in) :: gq0 - !GSD Chem variables - !integer,intent(in) :: num_emis_ant - integer,intent(in) :: num_chem, num_moist, ntsmoke, ntdust + !rrfs-sd variables + integer,intent(in) :: num_chem, num_moist, ntsmoke, ntdust, ntcoarsepm integer,intent(in) :: ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte - !real(kind_phys), dimension(ims:ime, kms:kemit, jms:jme, num_emis_ant), intent(inout) :: emis_ant - real(kind_phys), dimension(num_chem), intent(in) :: ppm2ugkg real(kind_phys), dimension(ims:ime, jms:jme),intent(out) :: ebu_in real(kind_phys), dimension(ims:ime, jms:jme, num_frp_plume), intent(out) :: plume_frp @@ -534,7 +553,7 @@ subroutine rrfs_smoke_prep( & real(kind_phys), parameter :: frpc = 1._kind_phys ! FRP conversion factor (Regional) ! -- local variables - integer i,ip,j,jp,k,kp,kk,kkp,nv,l,ll,n + integer i,ip,j,k,kp,kk,kkp,nv,l,ll,n ! -- initialize fire emissions !plume = 0._kind_phys @@ -542,6 +561,8 @@ subroutine rrfs_smoke_prep( & ebu_in = 0._kind_phys ebb_smoke_hr = 0._kind_phys emis_anoc = 0._kind_phys + frp_hr = 0._kind_phys + frp_std_hr = 0._kind_phys ! -- initialize output arrays isltyp = 0._kind_phys @@ -617,75 +638,60 @@ subroutine rrfs_smoke_prep( & enddo enddo - !if (ktau <= 1) then - ! emis_ant = 0. - ! !emis_vol = 0. - !end if - do j=jts,jte - jp = j - jts + 1 - do i=its,ite - ip = i - its + 1 - z_at_w(i,kts,j)=max(0.,ph3d(ip,1)/g) - enddo + do i=its,ite + z_at_w(i,kts,j)=max(0.,ph3d(i,1)/g) + enddo enddo do j=jts,jte - jp = j - jts + 1 - do k=kts,kte - kp = k - kts + 1 - do i=its,ite - ip = i - its + 1 - dz8w(i,k,j)=abs(ph3d(ip,kp+1)-ph3d(ip,kp))/g - z_at_w(i,k+1,j)=z_at_w(i,k,j)+dz8w(i,k,j) - enddo + do k=kts,kte + do i=its,ite + dz8w(i,k,j)=abs(ph3d(i,k+1)-ph3d(i,k))/g + z_at_w(i,k+1,j)=z_at_w(i,k,j)+dz8w(i,k,j) enddo + enddo enddo do j=jts,jte - jp = j - jts + 1 - do k=kts,kte+1 - kp = k - kts + 1 - do i=its,ite - ip = i - its + 1 - p8w(i,k,j)=pr3d(ip,kp) - enddo + do k=kts,kte+1 + do i=its,ite + p8w(i,k,j)=pr3d(i,k) enddo + enddo enddo do j=jts,jte - jp = j - jts + 1 do k=kts,kte+1 kk=min(k,kte) kkp = kk - kts + 1 do i=its,ite - ip = i - its + 1 dz8w(i,k,j)=z_at_w(i,kk+1,j)-z_at_w(i,kk,j) - t_phy(i,k,j)=tk3d(ip,kkp) - p_phy(i,k,j)=prl3d(ip,kkp) - u_phy(i,k,j)=us3d(ip,kkp) - v_phy(i,k,j)=vs3d(ip,kkp) - rho_phy(i,k,j)=p_phy(i,k,j)/(287.04*t_phy(i,k,j)*(1.+.608*spechum(ip,kkp))) + t_phy(i,k,j)=tk3d(i,kkp) + p_phy(i,k,j)=prl3d(i,kkp) + u_phy(i,k,j)=us3d(i,kkp) + v_phy(i,k,j)=vs3d(i,kkp) + rho_phy(i,k,j)=p_phy(i,k,j)/(con_rd*t_phy(i,k,j)*(1.+con_fv*spechum(i,kkp))) rri(i,k,j)=1./rho_phy(i,k,j) - vvel(i,k,j)=-w(ip,kkp)*rri(i,k,j)/g + vvel(i,k,j)=-w(i,kkp)*rri(i,k,j)/g moist(i,k,j,:)=0. - moist(i,k,j,1)=gq0(ip,kkp,p_atm_shum) + moist(i,k,j,1)=gq0(i,kkp,p_atm_shum) if (t_phy(i,k,j) > 265.) then - moist(i,k,j,2)=gq0(ip,kkp,p_atm_cldq) + moist(i,k,j,2)=gq0(i,kkp,p_atm_cldq) moist(i,k,j,3)=0. if (moist(i,k,j,2) < 1.e-8) moist(i,k,j,2)=0. else moist(i,k,j,2)=0. - moist(i,k,j,3)=gq0(ip,kkp,p_atm_cldq) + moist(i,k,j,3)=gq0(i,kkp,p_atm_cldq) if(moist(i,k,j,3) < 1.e-8)moist(i,k,j,3)=0. endif - rel_hum(i,k,j) = .95 - rel_hum(i,k,j) = MIN( .95, moist(i,k,j,1) / & + !rel_hum(i,k,j) = min(0.95,spechum(i,kkp)) + rel_hum(i,k,j) = min(0.95, moist(i,k,j,1) / & (3.80*exp(17.27*(t_phy(i,k,j)-273.)/ & (t_phy(i,k,j)-36.))/(.01*p_phy(i,k,j)))) - rel_hum(i,k,j)=max(0.1,rel_hum(i,k,j)) + rel_hum(i,k,j) = max(0.1,rel_hum(i,k,j)) !-- - zmid(i,k,j)=phl3d(ip,kkp)/g + zmid(i,k,j)=phl3d(i,kkp)/g enddo enddo enddo @@ -705,7 +711,6 @@ subroutine rrfs_smoke_prep( & enddo enddo - ! -- only used in phtolysis.... do j=jts,jte do i=its,ite t8w(i,1,j)=t_phy(i,1,j) @@ -718,27 +723,26 @@ subroutine rrfs_smoke_prep( & emis_anoc(i) = emi_in(i,1) enddo - ! select case (plumerise_flag) - ! case (FIRE_OPT_GBBEPx) + if (hour_int<24) then do j=jts,jte do i=its,ite - ebb_smoke_hr(i) = smoke_GBBEPx(i,current_hour,1) ! smoke - frp_hr (i) = smoke_GBBEPx(i,current_hour,2) ! frp - frp_std_hr (i) = smoke_GBBEPx(i,current_hour,3) ! std frp + ebb_smoke_hr(i) = smoke_RRFS(i,hour_int+1,1) ! smoke + frp_hr (i) = smoke_RRFS(i,hour_int+1,2) ! frp + frp_std_hr (i) = smoke_RRFS(i,hour_int+1,3) ! std frp ebu_in (i,j) = ebb_smoke_hr(i) - plume_frp(i,j,p_frp_hr ) = conv_frp* frp_hr (i) - plume_frp(i,j,p_frp_std ) = conv_frp* frp_std_hr (i) + plume_frp(i,j,p_frp_hr ) = conv_frp* frp_hr (i) + plume_frp(i,j,p_frp_std) = conv_frp* frp_std_hr (i) enddo enddo - ! case default - ! end select + endif ! We will add a namelist variable, real :: flam_frac_global do k=kms,kte do i=ims,ime - chem(i,k,jts,p_smoke )=max(epsilc,gq0(i,k,ntsmoke )/ppm2ugkg(p_smoke)) - chem(i,k,jts,p_dust_1)=max(epsilc,gq0(i,k,ntdust )/ppm2ugkg(p_dust_1)) + chem(i,k,jts,p_smoke )=max(epsilc,gq0(i,k,ntsmoke )) + chem(i,k,jts,p_dust_1 )=max(epsilc,gq0(i,k,ntdust )) + chem(i,k,jts,p_coarse_pm)=max(epsilc,gq0(i,k,ntcoarsepm)) enddo enddo diff --git a/smoke/rrfs_smoke_wrapper.meta b/physics/smoke_dust/rrfs_smoke_wrapper.meta similarity index 83% rename from smoke/rrfs_smoke_wrapper.meta rename to physics/smoke_dust/rrfs_smoke_wrapper.meta index ef46b04ea..bf2fddd60 100755 --- a/smoke/rrfs_smoke_wrapper.meta +++ b/physics/smoke_dust/rrfs_smoke_wrapper.meta @@ -1,7 +1,7 @@ [ccpp-table-properties] name = rrfs_smoke_wrapper type = scheme - dependencies = dep_dry_gocart_mod.F90,dep_dry_mod.F90,dep_simple_mod.F90,dep_vertmx_mod.F90,dep_wet_ls_mod.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,rrfs_smoke_data.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90 + dependencies = dep_dry_mod.F90,module_wetdep_ls.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90,coarsepm_settling_mod.F90 ######################################################################## [ccpp-arg-table] @@ -263,9 +263,9 @@ kind = kind_phys intent = in [snow] - standard_name = lwe_thickness_of_snow_amount - long_name = snow fall on physics timestep - units = m + standard_name = lwe_surface_snow + long_name = water equivalent snow depth + units = mm dimensions = (horizontal_loop_extent) type = real kind = kind_phys @@ -349,6 +349,14 @@ type = real kind = kind_phys intent = in +[con_fv] + standard_name = ratio_of_vapor_to_dry_air_gas_constants_minus_one + long_name = (rv/rd) - 1 (rv = ideal gas constant for water vapor) + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [dust12m_in] standard_name = fengsha_dust12m_input long_name = fengsha dust input @@ -365,9 +373,9 @@ type = real kind = kind_phys intent = in -[smoke_GBBEPx] - standard_name = emission_smoke_GBBEPx - long_name = emission fire GBBEPx +[smoke_RRFS] + standard_name = emission_smoke_RRFS + long_name = emission fire RRFS units = various dimensions = (horizontal_loop_extent,24,3) type = real @@ -400,7 +408,7 @@ standard_name = chem3d_mynn_pbl_transport long_name = mynn pbl transport of smoke and dust units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension,2) + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_chemical_species_vertically_mixed) type = real kind = kind_phys intent = inout @@ -425,6 +433,13 @@ dimensions = () type = integer intent = in +[ntcoarsepm] + standard_name = index_for_coarse_particulate_matter_in_tracer_concentration_array + long_name = tracer index for coarse particulate matter + units = index + dimensions = () + type = integer + intent = in [imp_physics] standard_name = control_for_microphysics_scheme long_name = choice of microphysics scheme @@ -456,8 +471,8 @@ kind = kind_phys intent = inout [emanoc] - standard_name = emission_of_anoc_for_thompson_mp - long_name = emission of anoc for thompson mp + standard_name = emission_of_anothropogenic_for_mp_indir_fdb + long_name = emission of anothropogenic for mp indirect feedabck units = ug m-2 s-1 dimensions = (horizontal_loop_extent) type = real @@ -472,8 +487,8 @@ kind = kind_phys intent = inout [emseas] - standard_name = emission_of_seas_for_smoke - long_name = emission of seas for smoke + standard_name = emission_of_sea_salt_for_mp_indir_fdb + long_name = emission of sea salt for mp indirect feedabck units = ug m-2 s-1 dimensions = (horizontal_loop_extent) type = real @@ -551,6 +566,14 @@ type = real kind = kind_phys intent = out +[wetness] + standard_name = normalized_soil_wetness_for_land_surface_model + long_name = normalized soil wetness + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in [smoke_ext] standard_name = extinction_coefficient_in_air_due_to_smoke long_name = extinction coefficient in air due to smoke @@ -567,6 +590,52 @@ type = real kind = kind_phys intent = out +[ndvel] + standard_name = number_of_chemical_species_deposited + long_name = number of chemical pbl deposited + units = count + dimensions = () + type = integer + intent = in +[ddvel_inout] + standard_name = dry_deposition_velocity_mynn_pbl_transport + long_name = dry deposition velocity by mynn pbl transport + units = m s-1 + dimensions = (horizontal_loop_extent,number_of_chemical_species_deposited) + type = real + kind = kind_phys + intent = inout +[rrfs_sd] + standard_name = do_smoke_coupling + long_name = flag controlling rrfs_sd collection (default off) + units = flag + dimensions = () + type = logical + intent = in +[dust_alpha_in] + standard_name = alpha_fengsha_dust_scheme + long_name = alpha paramter for fengsha dust scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[dust_gamma_in] + standard_name = gamma_fengsha_dust_scheme + long_name = gamma paramter for fengsha dust scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[fire_in] + standard_name = smoke_fire_auxiliary_input + long_name = smoke fire auxiliary input variables + units = various + dimensions = (horizontal_loop_extent,fire_auxiliary_data_extent) + type = real + kind = kind_phys + intent = inout [seas_opt_in] standard_name = control_for_smoke_sea_salt long_name = rrfs smoke sea salt emission option @@ -581,20 +650,35 @@ dimensions = () type = integer intent = in -[biomass_burn_opt_in] - standard_name = control_for_smoke_biomass_burn - long_name = rrfs smoke biomass burning option +[drydep_opt_in] + standard_name = control_for_smoke_dry_deposition + long_name = rrfs smoke dry deposition option units = index dimensions = () type = integer intent = in -[drydep_opt_in] - standard_name = control_for_smoke_dry_deposition - long_name = rrfs smoke dry deposition option +[coarsepm_settling_in] + standard_name = control_for_smoke_coarsepm_settling + long_name = rrfs smoke coarsepm settling option + units = index + dimensions = () + type = integer + intent = in +[wetdep_ls_opt_in] + standard_name = control_for_smoke_wet_deposition + long_name = rrfs smoke large scale wet deposition option units = index dimensions = () type = integer intent = in +[wetdep_ls_alpha_in] + standard_name = alpha_for_ls_wet_depoistion + long_name = alpha paramter for ls wet deposition + units = none + dimensions = () + type = real + kind = kind_phys + intent = in [do_plumerise_in] standard_name = do_smoke_plumerise long_name = rrfs smoke plumerise option @@ -618,10 +702,10 @@ intent = in [smoke_forecast_in] standard_name = do_smoke_forecast - long_name = flag for rrfs smoke forecast - units = flag + long_name = index for rrfs smoke forecast + units = index dimensions = () - type = logical + type = integer intent = in [aero_ind_fdb_in] standard_name = do_smoke_aerosol_indirect_feedback diff --git a/smoke/seas_data_mod.F90 b/physics/smoke_dust/seas_data_mod.F90 similarity index 100% rename from smoke/seas_data_mod.F90 rename to physics/smoke_dust/seas_data_mod.F90 diff --git a/smoke/seas_mod.F90 b/physics/smoke_dust/seas_mod.F90 similarity index 96% rename from smoke/seas_mod.F90 rename to physics/smoke_dust/seas_mod.F90 index 85c861156..1d18046ad 100755 --- a/smoke/seas_mod.F90 +++ b/physics/smoke_dust/seas_mod.F90 @@ -13,7 +13,6 @@ module seas_mod implicit none - integer, parameter :: SEAS_OPT_DEFAULT = 1 integer, parameter :: CHEM_OPT_GOCART = 300 integer, parameter :: chem_opt = 300 @@ -22,26 +21,24 @@ module seas_mod private - public :: SEAS_OPT_DEFAULT - public :: gocart_seasalt_driver CONTAINS - subroutine gocart_seasalt_driver(ktau,dt,alt,t_phy,moist,u_phy, & + subroutine gocart_seasalt_driver(dt,alt,t_phy,u_phy, & v_phy,chem,rho_phy,dz8w,u10,v10,ustar,p8w,tsk, & - xland,xlat,xlong,area,g,emis_seas,pi, & - seashelp,num_emis_seas,num_moist,num_chem,seas_opt, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) + xland,xlat,xlong,area,g,emis_seas,pi, & + seashelp,num_emis_seas,num_chem,seas_opt, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) - INTEGER, INTENT(IN ) :: ktau,num_emis_seas,num_moist,num_chem, & + INTEGER, INTENT(IN ) :: num_emis_seas,num_chem, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte,seas_opt - REAL(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & - INTENT(IN ) :: moist +! REAL(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & +! INTENT(IN ) :: moist REAL(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), & INTENT(INOUT ) :: chem REAL(kind=kind_phys), DIMENSION( ims:ime, 1, jms:jme,num_emis_seas), & diff --git a/smoke/seas_ngac_mod.F90 b/physics/smoke_dust/seas_ngac_mod.F90 similarity index 100% rename from smoke/seas_ngac_mod.F90 rename to physics/smoke_dust/seas_ngac_mod.F90 diff --git a/physics/ugwpv1_gsldrag.F90 b/physics/ugwpv1_gsldrag.F90 index 32c58ff91..9303e0221 100644 --- a/physics/ugwpv1_gsldrag.F90 +++ b/physics/ugwpv1_gsldrag.F90 @@ -303,13 +303,13 @@ end subroutine ugwpv1_gsldrag_finalize !! !> \section gen_ugwpv1_gsldrag CIRES UGWP Scheme General Algorithm !! @{ - subroutine ugwpv1_gsldrag_run(me, master, im, levs, ntrac, lonr, dtp, fhzero,kdt, & - ldiag3d, lssav, flag_for_gwd_generic_tend, do_gsl_drag_ls_bl, do_gsl_drag_ss, & - do_gsl_drag_tofd, do_ugwp_v1, do_ugwp_v1_orog_only, do_ugwp_v1_w_gsldrag, & - gwd_opt, do_tofd, ldiag_ugwp, cdmbgwd, jdat, & - nmtvr, hprime, oc, theta, sigma, gamma, elvmax, clx, oa4, & - varss,oc1ss,oa4ss,ol4ss, dx, xlat, xlat_d, sinlat, coslat, area, & - rain, br1, hpbl, kpbl, slmsk, & + subroutine ugwpv1_gsldrag_run(me, master, im, levs, ak, bk, ntrac, lonr, dtp, & + fhzero, kdt, ldiag3d, lssav, flag_for_gwd_generic_tend, do_gsl_drag_ls_bl, & + do_gsl_drag_ss, do_gsl_drag_tofd, do_ugwp_v1, do_ugwp_v1_orog_only, & + do_ugwp_v1_w_gsldrag, gwd_opt, do_tofd, ldiag_ugwp, ugwp_seq_update, & + cdmbgwd, jdat, nmtvr, hprime, oc, theta, sigma, gamma, & + elvmax, clx, oa4, varss,oc1ss,oa4ss,ol4ss, dx, xlat, xlat_d, sinlat, coslat, & + area, rain, br1, hpbl, kpbl, slmsk, & ugrs, vgrs, tgrs, q1, prsi, prsl, prslk, phii, phil, del, tau_amf, & dudt_ogw, dvdt_ogw, du_ogwcol, dv_ogwcol, & dudt_obl, dvdt_obl, du_oblcol, dv_oblcol, & @@ -359,11 +359,13 @@ subroutine ugwpv1_gsldrag_run(me, master, im, levs, ntrac, lonr, dtp, fhzero,kd ! flags for choosing combination of GW drag schemes to run logical, intent (in) :: do_gsl_drag_ls_bl, do_gsl_drag_ss, do_gsl_drag_tofd - logical, intent (in) :: do_ugwp_v1, do_ugwp_v1_orog_only, do_tofd, ldiag_ugwp + logical, intent (in) :: do_ugwp_v1, do_ugwp_v1_orog_only, do_tofd + logical, intent (in) :: ldiag_ugwp, ugwp_seq_update logical, intent (in) :: do_ugwp_v1_w_gsldrag ! combination of ORO and NGW schemes integer, intent(in) :: me, master, im, levs, ntrac,lonr real(kind=kind_phys), intent(in) :: dtp, fhzero + real(kind=kind_phys), intent(in) :: ak(:), bk(:) integer, intent(in) :: kdt, jdat(:) ! SSO parameters and variables @@ -494,21 +496,18 @@ subroutine ugwpv1_gsldrag_run(me, master, im, levs, ntrac, lonr, dtp, fhzero,kd !=============================================================== ! ORO-diag - if (do_ugwp_v1 .or. gwd_opt==33 .or. gwd_opt==22) then + if (do_ugwp_v1 .or. ldiag_ugwp) then dudt_ogw(:,:)= 0.; dvdt_ogw(:,:)=0.; dudt_obl(:,:)=0.; dvdt_obl(:,:)=0. dudt_oss(:,:)= 0.; dvdt_oss(:,:)=0.; dudt_ofd(:,:)=0.; dvdt_ofd(:,:)=0. du_ogwcol(:)=0. ; dv_ogwcol(:)=0. ; du_oblcol(:)=0. ; dv_oblcol(:)=0. du_osscol(:)=0. ; dv_osscol(:)=0. ;du_ofdcol(:)=0. ; dv_ofdcol(:)=0. + dudt_ngw(:,:)=0.; dvdt_ngw(:,:)=0.; dtdt_ngw(:,:)=0.; kdis_ngw(:,:)=0. else dudt_ogw(:,:) = 0. end if dusfcg (:) = 0. ; dvsfcg(:) =0. -! - if (do_ugwp_v1) then - dudt_ngw(:,:)=0.; dvdt_ngw(:,:)=0.; dtdt_ngw(:,:)=0.; kdis_ngw(:,:)=0. - end if ! ngw+ogw - diag @@ -545,7 +544,7 @@ subroutine ugwpv1_gsldrag_run(me, master, im, levs, ntrac, lonr, dtp, fhzero,kd ! dusfcg, dvsfcg ! ! - call drag_suite_run(im,levs, Pdvdt, Pdudt, Pdtdt, & + call drag_suite_run(im, levs, Pdvdt, Pdudt, Pdtdt, & ugrs,vgrs,tgrs,q1, & kpbl,prsi,del,prsl,prslk,phii,phil,dtp, & kdt,hprime,oc,oa4,clx,varss,oc1ss,oa4ss, & @@ -561,8 +560,8 @@ subroutine ugwpv1_gsldrag_run(me, master, im, levs, ntrac, lonr, dtp, fhzero,kd do_gsl_drag_ls_bl,do_gsl_drag_ss,do_gsl_drag_tofd, & dtend, dtidx, index_of_process_orographic_gwd, & index_of_temperature, index_of_x_wind, & - index_of_y_wind, ldiag3d, spp_wts_gwd, spp_gwd, & - errmsg, errflg) + index_of_y_wind, ldiag3d, ldiag_ugwp, & + ugwp_seq_update, spp_wts_gwd, spp_gwd, errmsg, errflg) ! ! dusfcg = du_ogwcol + du_oblcol + du_osscol + du_ofdcol ! diff --git a/physics/ugwpv1_gsldrag.meta b/physics/ugwpv1_gsldrag.meta index 0e1f6ddf1..82caa8832 100644 --- a/physics/ugwpv1_gsldrag.meta +++ b/physics/ugwpv1_gsldrag.meta @@ -198,21 +198,21 @@ type = logical intent = in [do_gsl_drag_ls_bl] - standard_name = flag_for_gsl_drag_suite_large_scale_orographic_and_blocking_drag - long_name = flag to activate GSL drag suite - large-scale GWD and blocking + standard_name = do_gsl_drag_suite_mesoscale_orographic_and_blocking_drag + long_name = flag to activate GSL drag suite - mesoscale GWD and blocking units = flag dimensions = () type = logical intent = in [do_gsl_drag_ss] - standard_name = flag_for_gsl_drag_suite_small_scale_orographic_drag + standard_name = do_gsl_drag_suite_small_scale_orographic_drag long_name = flag to activate GSL drag suite - small-scale GWD units = flag dimensions = () type = logical intent = in [do_gsl_drag_tofd] - standard_name = flag_for_gsl_drag_suite_turbulent_orographic_form_drag + standard_name = do_gsl_drag_suite_turbulent_orographic_form_drag long_name = flag to activate GSL drag suite - turb orog form drag units = flag dimensions = () @@ -307,6 +307,22 @@ dimensions = () type = integer intent = in +[ak] + standard_name = sigma_pressure_hybrid_coordinate_a_coefficient + long_name = a parameter for sigma pressure level calculations + units = Pa + dimensions = (vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[bk] + standard_name = sigma_pressure_hybrid_coordinate_b_coefficient + long_name = b parameter for sigma pressure level calculations + units = none + dimensions = (vertical_interface_dimension) + type = real + kind = kind_phys + intent = in [ntrac] standard_name = number_of_tracers long_name = number of tracers @@ -366,21 +382,21 @@ type = logical intent = in [do_gsl_drag_ls_bl] - standard_name = flag_for_gsl_drag_suite_large_scale_orographic_and_blocking_drag - long_name = flag to activate GSL drag suite - large-scale GWD and blocking + standard_name = do_gsl_drag_suite_mesoscale_orographic_and_blocking_drag + long_name = flag to activate GSL drag suite - mesoscale GWD and blocking units = flag dimensions = () type = logical intent = in [do_gsl_drag_ss] - standard_name = flag_for_gsl_drag_suite_small_scale_orographic_drag + standard_name = do_gsl_drag_suite_small_scale_orographic_drag long_name = flag to activate GSL drag suite - small-scale GWD units = flag dimensions = () type = logical intent = in [do_gsl_drag_tofd] - standard_name = flag_for_gsl_drag_suite_turbulent_orographic_form_drag + standard_name = do_gsl_drag_suite_turbulent_orographic_form_drag long_name = flag to activate GSL drag suite - turb orog form drag units = flag dimensions = () @@ -428,6 +444,13 @@ dimensions = () type = logical intent = in +[ugwp_seq_update] + standard_name = do_ugwp_sequential_update + long_name = flag for ugwp sequential update + units = flag + dimensions = () + type = logical + intent = in [cdmbgwd] standard_name = multiplicative_tunable_parameters_for_mountain_blocking_and_orographic_gravity_wave_drag long_name = multiplication factors for cdmb and gwd @@ -723,7 +746,7 @@ intent = in [dudt_ogw] standard_name = tendency_of_x_wind_due_to_mesoscale_orographic_gravity_wave_drag - long_name = x momentum tendency from meso scale ogw + long_name = x wind tendency from meso scale ogw units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real @@ -731,7 +754,7 @@ intent = out [dvdt_ogw] standard_name = tendency_of_y_wind_due_to_mesoscale_orographic_gravity_wave_drag - long_name = y momentum tendency from meso scale ogw + long_name = y wind tendency from meso scale ogw units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real @@ -754,16 +777,16 @@ kind = kind_phys intent = out [dudt_obl] - standard_name = tendency_of_x_momentum_due_to_blocking_drag - long_name = x momentum tendency from blocking drag + standard_name = tendency_of_x_wind_due_to_blocking_drag + long_name = x wind tendency from blocking drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = out [dvdt_obl] - standard_name = tendency_of_y_momentum_due_to_blocking_drag - long_name = y momentum tendency from blocking drag + standard_name = tendency_of_y_wind_due_to_blocking_drag + long_name = y wind tendency from blocking drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real @@ -786,16 +809,16 @@ kind = kind_phys intent = out [dudt_oss] - standard_name = tendency_of_x_momentum_due_to_small_scale_gravity_wave_drag - long_name = x momentum tendency from small scale gwd + standard_name = tendency_of_x_wind_due_to_small_scale_gravity_wave_drag + long_name = x wind tendency from small scale gwd units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = out [dvdt_oss] - standard_name = tendency_of_y_momentum_due_to_small_scale_gravity_wave_drag - long_name = y momentum tendency from small scale gwd + standard_name = tendency_of_y_wind_due_to_small_scale_gravity_wave_drag + long_name = y wind tendency from small scale gwd units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real @@ -818,16 +841,16 @@ kind = kind_phys intent = out [dudt_ofd] - standard_name = tendency_of_x_momentum_due_to_form_drag - long_name = x momentum tendency from form drag + standard_name = tendency_of_x_wind_due_to_form_drag + long_name = x wind tendency from form drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = out [dvdt_ofd] - standard_name = tendency_of_y_momentum_due_to_form_drag - long_name = y momentum tendency from form drag + standard_name = tendency_of_y_wind_due_to_form_drag + long_name = y wind tendency from form drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real diff --git a/physics/ugwpv1_gsldrag_post.F90 b/physics/ugwpv1_gsldrag_post.F90 index d50ee9714..8c6704dc5 100644 --- a/physics/ugwpv1_gsldrag_post.F90 +++ b/physics/ugwpv1_gsldrag_post.F90 @@ -9,14 +9,21 @@ module ugwpv1_gsldrag_post !> \section arg_table_ugwpv1_gsldrag_post_run Argument Table !! \htmlinclude ugwpv1_gsldrag_post_run.html !! - subroutine ugwpv1_gsldrag_post_run ( im, levs, & - ldiag_ugwp, dtf, & - dudt_gw, dvdt_gw, dtdt_gw, du_ofdcol, du_oblcol, tau_ogw, & - tau_ngw, zobl, zlwb, zogw, dudt_obl, dudt_ofd, dudt_ogw, & - tot_zmtb, tot_zlwb, tot_zogw, & + subroutine ugwpv1_gsldrag_post_run ( im, levs, ldiag_ugwp, & + dtf, dudt_gw, dvdt_gw, dtdt_gw, & + tau_ogw, tau_ngw, zobl, zlwb, zogw, dudt_obl, dvdt_obl, & + dudt_ofd, dvdt_ofd, dudt_ogw, dvdt_ogw, & + dudt_oss, dvdt_oss, tot_zmtb, tot_zlwb, tot_zogw, & tot_tofd, tot_mtb, tot_ogw, tot_ngw, & du3dt_mtb,du3dt_ogw, du3dt_tms, du3dt_ngw, dv3dt_ngw, & - dtdt, dudt, dvdt, errmsg, errflg) + dudt_ngw, dvdt_ngw, dtdt_ngw, & + ldu3dt_ngw, ldv3dt_ngw, ldt3dt_ngw, & + dws3dt_ogw, dws3dt_obl, dws3dt_oss, dws3dt_ofd, & + ldu3dt_ogw, ldu3dt_obl, ldu3dt_oss, ldu3dt_ofd, & + du_ogwcol, dv_ogwcol, du_oblcol, dv_oblcol, du_osscol, & + dv_osscol, du_ofdcol, dv_ofdcol, du3_ogwcol, dv3_ogwcol, & + du3_oblcol, dv3_oblcol, du3_osscol, dv3_osscol, du3_ofdcol, & + dv3_ofdcol, dtdt, dudt, dvdt, errmsg, errflg) use machine, only: kind_phys @@ -33,8 +40,25 @@ subroutine ugwpv1_gsldrag_post_run ( im, levs, & real(kind=kind_phys), intent(inout), dimension(:) :: tot_zmtb, tot_zlwb, tot_zogw real(kind=kind_phys), intent(in), dimension(:,:) :: dtdt_gw, dudt_gw, dvdt_gw - real(kind=kind_phys), intent(in), dimension(:,:) :: dudt_obl, dudt_ogw, dudt_ofd - real(kind=kind_phys), intent(inout), dimension(:,:) :: du3dt_mtb, du3dt_ogw, du3dt_tms, du3dt_ngw, dv3dt_ngw + real(kind=kind_phys), intent(in), dimension(:,:) :: dudt_obl, dvdt_obl, dudt_ogw + real(kind=kind_phys), intent(in), dimension(:,:) :: dvdt_ogw, dudt_ofd, dvdt_ofd + real(kind=kind_phys), intent(in), dimension(:,:) :: dudt_oss, dvdt_oss + real(kind=kind_phys), intent(inout), dimension(:,:) :: du3dt_mtb, du3dt_ogw, du3dt_tms + real(kind=kind_phys), intent(inout), dimension(:,:) :: du3dt_ngw, dv3dt_ngw + real(kind=kind_phys), intent(in), dimension(:,:) :: dudt_ngw, dvdt_ngw, dtdt_ngw + real(kind=kind_phys), intent(inout), dimension(:,:) :: ldu3dt_ngw, ldv3dt_ngw, ldt3dt_ngw + real(kind=kind_phys), intent(inout), dimension(:,:) :: dws3dt_ogw, dws3dt_obl + real(kind=kind_phys), intent(inout), dimension(:,:) :: dws3dt_oss, dws3dt_ofd + real(kind=kind_phys), intent(inout), dimension(:,:) :: ldu3dt_ogw, ldu3dt_obl + real(kind=kind_phys), intent(inout), dimension(:,:) :: ldu3dt_oss, ldu3dt_ofd + real(kind=kind_phys), intent(in), dimension(:) :: du_ogwcol, dv_ogwcol + real(kind=kind_phys), intent(in), dimension(:) :: dv_oblcol + real(kind=kind_phys), intent(in), dimension(:) :: du_osscol, dv_osscol + real(kind=kind_phys), intent(in), dimension(:) :: dv_ofdcol + real(kind=kind_phys), intent(inout), dimension(:) :: du3_ogwcol, dv3_ogwcol + real(kind=kind_phys), intent(inout), dimension(:) :: du3_oblcol, dv3_oblcol + real(kind=kind_phys), intent(inout), dimension(:) :: du3_osscol, dv3_osscol + real(kind=kind_phys), intent(inout), dimension(:) :: du3_ofdcol, dv3_ofdcol real(kind=kind_phys), intent(inout), dimension(:,:) :: dtdt, dudt, dvdt @@ -63,6 +87,32 @@ subroutine ugwpv1_gsldrag_post_run ( im, levs, & du3dt_ogw = du3dt_ogw + dtf *dudt_ogw du3dt_ngw = du3dt_ngw + dtf *dudt_gw dv3dt_ngw = dv3dt_ngw + dtf *dvdt_gw + + dws3dt_ogw = dws3dt_ogw + dtf *sqrt(dudt_ogw**2+dvdt_ogw**2) + dws3dt_obl = dws3dt_obl + dtf *sqrt(dudt_obl**2+dvdt_obl**2) + + du3_ogwcol = du3_ogwcol + dtf *du_ogwcol + dv3_ogwcol = dv3_ogwcol + dtf *dv_ogwcol + du3_oblcol = du3_oblcol + dtf *du_oblcol + dv3_oblcol = dv3_oblcol + dtf *dv_oblcol + + dws3dt_oss = dws3dt_oss + dtf *sqrt(dudt_oss**2+dvdt_oss**2) + dws3dt_ofd = dws3dt_ofd + dtf *sqrt(dudt_ofd**2+dvdt_ofd**2) + + ldu3dt_ogw = ldu3dt_ogw + dtf *dudt_ogw + ldu3dt_obl = ldu3dt_obl + dtf *dudt_obl + ldu3dt_oss = ldu3dt_oss + dtf *dudt_oss + ldu3dt_ofd = ldu3dt_ofd + dtf *dudt_ofd + + du3_osscol = du3_osscol + dtf*du_osscol + dv3_osscol = dv3_osscol + dtf*dv_osscol + du3_ofdcol = du3_ofdcol + dtf*du_ofdcol + dv3_ofdcol = dv3_ofdcol + dtf*dv_ofdcol + + ! Special treatment for non-stationary GWD diagnostics + ldu3dt_ngw = ldu3dt_ngw + dtf *dudt_ngw + ldv3dt_ngw = ldv3dt_ngw + dtf *dvdt_ngw + ldt3dt_ngw = ldt3dt_ngw + dtf *dtdt_ngw endif !===================================================================== diff --git a/physics/ugwpv1_gsldrag_post.meta b/physics/ugwpv1_gsldrag_post.meta index 4a0e88de9..f8766060c 100644 --- a/physics/ugwpv1_gsldrag_post.meta +++ b/physics/ugwpv1_gsldrag_post.meta @@ -60,22 +60,6 @@ type = real kind = kind_phys intent = in -[du_ofdcol] - standard_name = vertically_integrated_x_momentum_flux_due_to_form_drag - long_name = integrated x momentum flux from form drag - units = Pa - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[du_oblcol] - standard_name = vertically_integrated_x_momentum_flux_due_to_blocking_drag - long_name = integrated x momentum flux from blocking drag - units = Pa - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in [tau_ogw] standard_name = instantaneous_momentum_flux_due_to_orographic_gravity_wave_drag long_name = momentum flux or stress due to orographic gravity wave drag @@ -117,16 +101,32 @@ kind = kind_phys intent = in [dudt_obl] - standard_name = tendency_of_x_momentum_due_to_blocking_drag - long_name = x momentum tendency from blocking drag + standard_name = tendency_of_x_wind_due_to_blocking_drag + long_name = x wind tendency from blocking drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dvdt_obl] + standard_name = tendency_of_y_wind_due_to_blocking_drag + long_name = y wind tendency from blocking drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = in [dudt_ofd] - standard_name = tendency_of_x_momentum_due_to_form_drag - long_name = x momentum tendency from form drag + standard_name = tendency_of_x_wind_due_to_form_drag + long_name = x wind tendency from form drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dvdt_ofd] + standard_name = tendency_of_y_wind_due_to_form_drag + long_name = y wind tendency from form drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real @@ -134,7 +134,31 @@ intent = in [dudt_ogw] standard_name = tendency_of_x_wind_due_to_mesoscale_orographic_gravity_wave_drag - long_name = x momentum tendency from meso scale ogw + long_name = x wind tendency from meso scale ogw + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dvdt_ogw] + standard_name = tendency_of_y_wind_due_to_mesoscale_orographic_gravity_wave_drag + long_name = y wind tendency from meso scale ogw + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dudt_oss] + standard_name = tendency_of_x_wind_due_to_small_scale_gravity_wave_drag + long_name = x wind tendency from small scale gwd + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dvdt_oss] + standard_name = tendency_of_y_wind_due_to_small_scale_gravity_wave_drag + long_name = y wind tendency from small scale gwd units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real @@ -236,6 +260,246 @@ type = real kind = kind_phys intent = inout +[dudt_ngw] + standard_name = tendency_of_x_wind_due_to_nonorographic_gravity_wave_drag + long_name = zonal wind tendency due to non-stationary GWs + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dvdt_ngw] + standard_name = tendency_of_y_wind_due_to_nonorographic_gravity_wave_drag + long_name = meridional wind tendency due to non-stationary GWs + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dtdt_ngw] + standard_name = tendency_of_air_temperature_due_to_nonorographic_gravity_wave_drag + long_name = air temperature tendency due to non-stationary GWs + units = K s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[ldu3dt_ngw] + standard_name = cumulative_change_in_x_wind_due_to_convective_gravity_wave_drag + long_name = cumulative change in x wind due to convective gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldv3dt_ngw] + standard_name = cumulative_change_in_y_wind_due_to_convective_gravity_wave_drag + long_name = cumulative change in y wind due to convective gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldt3dt_ngw] + standard_name = cumulative_change_in_temperature_due_to_convective_gravity_wave_drag + long_name = cumulative change in temperature due to convective gravity wave drag + units = K + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dws3dt_ogw] + standard_name = cumulative_change_in_wind_speed_due_to_mesoscale_orographic_gravity_wave_drag + long_name = cumulative change in wind speed due to mesoscale orographic gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dws3dt_obl] + standard_name = cumulative_change_in_wind_speed_due_to_blocking_drag + long_name = cumulative change in wind speed due to blocking drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dws3dt_oss] + standard_name = cumulative_change_in_wind_speed_due_to_small_scale_orographic_gravity_wave_drag + long_name = cumulative change in wind speed due to small scale orographic gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dws3dt_ofd] + standard_name = cumulative_change_in_wind_speed_due_to_turbulent_orographic_form_drag + long_name = cumulative change in wind speed due to turbulent orographic form drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldu3dt_ogw] + standard_name = cumulative_change_in_x_wind_due_to_mesoscale_orographic_gravity_wave_drag + long_name = cumulative change in x wind due to mesoscale orographic gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldu3dt_obl] + standard_name = cumulative_change_in_x_wind_due_to_blocking_drag + long_name = cumulative change in x wind due to blocking drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldu3dt_oss] + standard_name = cumulative_change_in_x_wind_due_to_small_scale_gravity_wave_drag + long_name = cumulative change in x wind due to small scale gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldu3dt_ofd] + standard_name = cumulative_change_in_x_wind_due_to_form_drag + long_name = cumulative change in x wind due to form drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[du_ogwcol] + standard_name = vertically_integrated_x_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = integrated x momentum flux from meso scale ogw + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[dv_ogwcol] + standard_name = vertically_integrated_y_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = integrated y momentum flux from meso scale ogw + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[du_oblcol] + standard_name = vertically_integrated_x_momentum_flux_due_to_blocking_drag + long_name = integrated x momentum flux from blocking drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[dv_oblcol] + standard_name = vertically_integrated_y_momentum_flux_due_to_blocking_drag + long_name = integrated y momentum flux from blocking drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[du_osscol] + standard_name = vertically_integrated_x_momentum_flux_due_to_small_scale_gravity_wave_drag + long_name = integrated x momentum flux from small scale gwd + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[dv_osscol] + standard_name = vertically_integrated_y_momentum_flux_due_to_small_scale_gravity_wave_drag + long_name = integrated y momentum flux from small scale gwd + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[du_ofdcol] + standard_name = vertically_integrated_x_momentum_flux_due_to_form_drag + long_name = integrated x momentum flux from form drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[dv_ofdcol] + standard_name = vertically_integrated_y_momentum_flux_due_to_form_drag + long_name = integrated y momentum flux from form drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[du3_ogwcol] + standard_name = cumulative_vertically_integrated_x_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = cumulative integrated x momentum flux from mesoscale orographic gravity wave drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dv3_ogwcol] + standard_name = cumulative_vertically_integrated_y_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = cumulative integrated y momentum flux from mesoscale orographic gravity wave drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[du3_oblcol] + standard_name = cumulative_vertically_integrated_x_momentum_flux_due_to_blocking_drag + long_name = cumulative integrated x momentum flux from blocking drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dv3_oblcol] + standard_name = cumulative_vertically_integrated_y_momentum_flux_due_to_blocking_drag + long_name = cumulative integrated y momentum flux from blocking drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[du3_osscol] + standard_name = cumulative_vertically_integrated_x_momentum_flux_due_to_small_scale_gravity_wave_drag + long_name = cumulative integrated x momentum flux from small scale gravity wave drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dv3_osscol] + standard_name = cumulative_vertically_integrated_y_momentum_flux_due_small_scale_gravity_wave_drag + long_name = cumulative integrated y momentum flux from small scale gravity wave drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[du3_ofdcol] + standard_name = cumulative_vertically_integrated_x_momentum_flux_due_to_form_drag + long_name = cumulative integrated x momentum flux from form drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dv3_ofdcol] + standard_name = cumulative_vertically_integrated_y_momentum_flux_due_to_form_drag + long_name = cumulative integrated y momentum flux from form drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout [dtdt] standard_name = process_split_cumulative_tendency_of_air_temperature long_name = air temperature tendency due to model physics diff --git a/physics/unified_ugwp.F90 b/physics/unified_ugwp.F90 index 6192e1053..0bcbc4f62 100644 --- a/physics/unified_ugwp.F90 +++ b/physics/unified_ugwp.F90 @@ -5,7 +5,7 @@ !! a) the "traditional" EMC orograhic gravity wave drag and flow blocking scheme of gwdps.f !! b) the v0 cires ugwp non-stationary GWD scheme !! 2) The GSL orographic drag suite (drag_suite.F90), as implmeneted in the RAP/HRRR, which includes: -!! a) large-scale gravity wave drag and low-level flow blocking -- active at horizontal scales +!! a) mesoscale gravity wave drag and low-level flow blocking -- active at horizontal scales !! down to ~5km (Kim and Arakawa, 1995 \cite kim_and_arakawa_1995; Kim and Doyle, 2005 \cite kim_and_doyle_2005) !! b) small-scale gravity wave drag scheme -- active typically in stable PBL at horizontal grid resolutions down to ~1km !! (Steeneveld et al, 2008 \cite steeneveld_et_al_2008; Tsiringakis et al, 2017 \cite tsiringakis_et_al_2017) @@ -25,10 +25,10 @@ !! do_ugwp_v0 -- activates V0 CIRES UGWP scheme - both orographic and non-stationary GWD !! do_ugwp_v0_orog_only -- activates V0 CIRES UGWP scheme - orographic GWD only !! do_ugwp_v0_nst_only -- activates V0 CIRES UGWP scheme - non-stationary GWD only -!! do_gsl_drag_ls_bl -- activates RAP/HRRR (GSL) large-scale GWD and blocking +!! do_gsl_drag_ls_bl -- activates RAP/HRRR (GSL) mesoscale GWD and blocking !! do_gsl_drag_ss -- activates RAP/HRRR (GSL) small-scale GWD !! do_gsl_drag_tofd -- activates RAP/HRRR (GSL) turbulent orographic drag -!! Note that only one "large-scale" scheme can be activated at a time. +!! Note that only one "mesoscale" scheme can be activated at a time. !! module unified_ugwp @@ -116,12 +116,12 @@ subroutine unified_ugwp_init (me, master, nlunit, input_nml_file, logunit, & return end if - ! Test to make sure that at most only one large-scale/blocking + ! Test to make sure that at most only one mesoscale/blocking ! orographic drag scheme is chosen if ( (do_ugwp_v0.and.(do_ugwp_v0_orog_only.or.do_gsl_drag_ls_bl)) .or. & (do_ugwp_v0_orog_only.and.do_gsl_drag_ls_bl) ) then - write(errmsg,'(*(a))') "Logic error: Only one large-scale& + write(errmsg,'(*(a))') "Logic error: Only one mesoscale& &/blocking scheme (do_ugwp_v0,do_ugwp_v0_orog_only,& &do_gsl_drag_ls_bl can be chosen" errflg = 1 @@ -244,21 +244,23 @@ end subroutine unified_ugwp_finalize !! \htmlinclude unified_ugwp_run.html !! ! \section det_unified_ugwp GFS Unified GWP Scheme Detailed Algorithm - subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, & + subroutine unified_ugwp_run(me, master, im, levs, ak,bk, ntrac, dtp, fhzero, kdt, & lonr, oro, oro_uf, hprime, nmtvr, oc, theta, sigma, gamma, elvmax, clx, oa4, & - varss,oc1ss,oa4ss,ol4ss,dx,dusfc_ls,dvsfc_ls,dusfc_bl,dvsfc_bl,dusfc_ss, & - dvsfc_ss,dusfc_fd,dvsfc_fd,dtaux2d_ls,dtauy2d_ls,dtaux2d_bl,dtauy2d_bl, & - dtaux2d_ss,dtauy2d_ss,dtaux2d_fd,dtauy2d_fd,br1,hpbl,slmsk, & - do_tofd, ldiag_ugwp, cdmbgwd, jdat, xlat, xlat_d, sinlat, coslat, area, & + varss,oc1ss,oa4ss,ol4ss,dx,dusfc_ms,dvsfc_ms,dusfc_bl,dvsfc_bl,dusfc_ss, & + dvsfc_ss,dusfc_fd,dvsfc_fd,dtaux2d_ms,dtauy2d_ms,dtaux2d_bl,dtauy2d_bl, & + dtaux2d_ss,dtauy2d_ss,dtaux2d_fd,dtauy2d_fd,dudt_ngw,dvdt_ngw,dtdt_ngw, & + br1,hpbl,slmsk, do_tofd, ldiag_ugwp, ugwp_seq_update, & + cdmbgwd, jdat, xlat, xlat_d, sinlat, coslat, area, & ugrs, vgrs, tgrs, q1, prsi, prsl, prslk, phii, phil, & del, kpbl, dusfcg, dvsfcg, gw_dudt, gw_dvdt, gw_dtdt, gw_kdis, & tau_tofd, tau_mtb, tau_ogw, tau_ngw, zmtb, zlwb, zogw, & dudt_mtb, dudt_tms, du3dt_mtb, du3dt_ogw, du3dt_tms, & dudt, dvdt, dtdt, rdxzb, con_g, con_omega, con_pi, con_cp, con_rd, con_rv, & con_rerth, con_fvirt, rain, ntke, q_tke, dqdt_tke, lprnt, ipr, & - dtend, dtidx, index_of_temperature, index_of_x_wind, index_of_y_wind, & - index_of_process_orographic_gwd, index_of_process_nonorographic_gwd, & - ldiag3d, lssav, flag_for_gwd_generic_tend, do_ugwp_v0, do_ugwp_v0_orog_only, & + ldiag3d, dtend, dtidx, index_of_temperature, index_of_x_wind, & + index_of_y_wind, index_of_process_orographic_gwd, & + index_of_process_nonorographic_gwd, & + lssav, flag_for_gwd_generic_tend, do_ugwp_v0, do_ugwp_v0_orog_only, & do_ugwp_v0_nst_only, do_gsl_drag_ls_bl, do_gsl_drag_ss, do_gsl_drag_tofd, & gwd_opt, spp_wts_gwd, spp_gwd, errmsg, errflg) @@ -268,6 +270,7 @@ subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, integer, intent(in) :: me, master, im, levs, ntrac, kdt, lonr, nmtvr integer, intent(in) :: gwd_opt integer, intent(in), dimension(:) :: kpbl + real(kind=kind_phys), intent(in), dimension(:) :: ak, bk real(kind=kind_phys), intent(in), dimension(:) :: oro, oro_uf, hprime, oc, theta, sigma, gamma real(kind=kind_phys), intent(in), dimension(:) :: varss,oc1ss, dx @@ -286,18 +289,20 @@ subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, real(kind=kind_phys), intent(in), dimension(:,:) :: q1 real(kind=kind_phys), intent(in) :: dtp, fhzero, cdmbgwd(:) integer, intent(in) :: jdat(:) - logical, intent(in) :: do_tofd, ldiag_ugwp + logical, intent(in) :: do_tofd, ldiag_ugwp, ugwp_seq_update !Output (optional): real(kind=kind_phys), intent(out) :: & - & dusfc_ls(:),dvsfc_ls(:), & + & dusfc_ms(:),dvsfc_ms(:), & & dusfc_bl(:),dvsfc_bl(:), & & dusfc_ss(:),dvsfc_ss(:), & & dusfc_fd(:),dvsfc_fd(:) real(kind=kind_phys), intent(out) :: & + & dtaux2d_ms(:,:),dtauy2d_ms(:,:), & & dtaux2d_bl(:,:),dtauy2d_bl(:,:), & & dtaux2d_ss(:,:),dtauy2d_ss(:,:), & - & dtaux2d_fd(:,:),dtauy2d_fd(:,:) + & dtaux2d_fd(:,:),dtauy2d_fd(:,:), & + & dudt_ngw(:,:),dvdt_ngw(:,:),dtdt_ngw(:,:) real(kind=kind_phys), intent(in) :: br1(:), & & hpbl(:), & @@ -308,7 +313,6 @@ subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, real(kind=kind_phys), intent(out), dimension(:) :: tau_mtb, tau_ogw, tau_tofd, tau_ngw real(kind=kind_phys), intent(out), dimension(:,:) :: gw_dudt, gw_dvdt, gw_dtdt, gw_kdis real(kind=kind_phys), intent(out), dimension(:,:) :: dudt_mtb, dudt_tms - real(kind=kind_phys), intent(out), dimension(:,:) :: dtaux2d_ls, dtauy2d_ls real(kind=kind_phys), intent(inout) :: dtend(:,:,:) integer, intent(in) :: dtidx(:,:), index_of_temperature, index_of_x_wind, & @@ -349,6 +353,13 @@ subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, real(kind=kind_phys), dimension(im) :: sgh30 real(kind=kind_phys), dimension(im, levs) :: Pdvdt, Pdudt real(kind=kind_phys), dimension(im, levs) :: Pdtdt, Pkdis + + ! Variables for optional sequential updating of winds between the + ! LSGWD+BLOCKING and SSGWD+TOFD steps. They are placeholders + ! for the u,v winds that are updated within the scheme if + ! ugwp_seq_update == T, otherwise, they retain the values + ! passed to the scheme. + real(kind=kind_phys), dimension(im, levs) :: uwnd1, vwnd1 real(kind=kind_phys), parameter :: tamp_mpa=30.e-3 @@ -366,38 +377,34 @@ subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, errmsg = '' errflg = 0 + ! 1) ORO stationary GWs ! ------------------ - ! Run the appropriate large-scale (large-scale GWD + blocking) scheme - ! Note: In case of GSL drag_suite, this includes ss and tofd - - if ( do_gsl_drag_ls_bl.or.do_gsl_drag_ss.or.do_gsl_drag_tofd ) then - - call drag_suite_run(im,levs,dvdt,dudt,dtdt,ugrs,vgrs,tgrs,q1, & - kpbl,prsi,del,prsl,prslk,phii,phil,dtp, & - kdt,hprime,oc,oa4,clx,varss,oc1ss,oa4ss, & - ol4ss,theta,sigma,gamma,elvmax,dtaux2d_ls, & - dtauy2d_ls,dtaux2d_bl,dtauy2d_bl,dtaux2d_ss, & - dtauy2d_ss,dtaux2d_fd,dtauy2d_fd,dusfcg, & - dvsfcg,dusfc_ls,dvsfc_ls,dusfc_bl,dvsfc_bl, & - dusfc_ss,dvsfc_ss,dusfc_fd,dvsfc_fd, & - slmsk,br1,hpbl,con_g,con_cp,con_rd,con_rv, & - con_fvirt,con_pi,lonr, & - cdmbgwd,me,master,lprnt,ipr,rdxzb,dx,gwd_opt, & - do_gsl_drag_ls_bl,do_gsl_drag_ss,do_gsl_drag_tofd, & - dtend, dtidx, index_of_process_orographic_gwd, & - index_of_temperature, index_of_x_wind, & - index_of_y_wind, ldiag3d, spp_wts_gwd, spp_gwd, & - errmsg, errflg) -! -! put zeros due to xy GSL-drag style: dtaux2d_bl,dtauy2d_bl,dtaux2d_ss.......dusfc_ls,dvsfc_ls -! - tau_mtb = 0. ; tau_ogw = 0. ; tau_tofd = 0. - dudt_mtb = 0. ; dudt_tms = 0. - + ! Initialize optional diagnostic variables for ORO drag + if ( ldiag_ugwp ) then + dusfc_ms(:) = 0.0 + dvsfc_ms(:) = 0.0 + dusfc_bl(:) = 0.0 + dvsfc_bl(:) = 0.0 + dusfc_ss(:) = 0.0 + dvsfc_ss(:) = 0.0 + dusfc_fd(:) = 0.0 + dvsfc_fd(:) = 0.0 + dtaux2d_ms(:,:)= 0.0 + dtauy2d_ms(:,:)= 0.0 + dtaux2d_bl(:,:)= 0.0 + dtauy2d_bl(:,:)= 0.0 + dtaux2d_ss(:,:)= 0.0 + dtauy2d_ss(:,:)= 0.0 + dtaux2d_fd(:,:)= 0.0 + dtauy2d_fd(:,:)= 0.0 end if + + ! Prepare to run UGWP_v0 mesoscale GWD + blocking scheme + ! These tendency initializations pertain to the non-stationary GWD + ! scheme as well if ( do_ugwp_v0.or.do_ugwp_v0_orog_only.or.do_ugwp_v0_nst_only ) then do k=1,levs @@ -411,11 +418,17 @@ subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, end if + ! Initialize winds and temperature for sequential updating + ! NOTE: These will only be updated if ugwp_seq_update == .true. + uwnd1(:,:) = ugrs(:,:) + vwnd1(:,:) = vgrs(:,:) + if ( do_ugwp_v0.or.do_ugwp_v0_orog_only ) then if (cdmbgwd(1) > 0.0 .or. cdmbgwd(2) > 0.0) then - ! Override nmtvr with nmtvr_temp = 14 for passing into gwdps_run if necessary + ! Override nmtvr with nmtvr_temp = 14 for passing into gwdps_run if + ! necessary if ( nmtvr == 24 ) then ! gwd_opt = 2, 22, 3, or 33 nmtvr_temp = 14 else @@ -426,11 +439,21 @@ subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, ugrs, vgrs, tgrs, q1, & kpbl, prsi, del, prsl, prslk, phii, phil, dtp, kdt, & hprime, oc, oa4, clx, theta, sigma, gamma, & - elvmax, dusfcg, dvsfcg, & + elvmax, dusfcg, dvsfcg, dtaux2d_ms, dtauy2d_ms, & + dtaux2d_bl, dtauy2d_bl, dusfc_ms, dvsfc_ms, & + dusfc_bl, dvsfc_bl, & con_g, con_cp, con_rd, con_rv, lonr, & nmtvr_temp, cdmbgwd, me, lprnt, ipr, rdxzb, & - errmsg, errflg) + ldiag_ugwp, errmsg, errflg) if (errflg/=0) return + + ! Update winds if sequential updating is selected + ! and SSGWD and TOFD will be calculated + if ( ugwp_seq_update .and. (do_gsl_drag_ss.or.do_gsl_drag_tofd) ) then + uwnd1(:,:) = uwnd1(:,:) + Pdudt(:,:)*dtp + vwnd1(:,:) = vwnd1(:,:) + Pdvdt(:,:)*dtp + endif + endif tau_mtb = 0.0 ; tau_ogw = 0.0 ; tau_tofd = 0.0 @@ -444,7 +467,7 @@ subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, if(idtend>=1) then dtend(:,:,idtend) = dtend(:,:,idtend) + Pdudt*dtp endif - + idtend = dtidx(index_of_y_wind,index_of_process_orographic_gwd) if(idtend>=1) then dtend(:,:,idtend) = dtend(:,:,idtend) + Pdvdt*dtp @@ -455,8 +478,39 @@ subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, dtend(:,:,idtend) = dtend(:,:,idtend) + Pdtdt*dtp endif endif - - end if + + end if + + + + ! Run the appropriate mesoscale (mesoscale GWD + blocking) scheme + ! Note: In case of GSL drag_suite, this includes ss and tofd + + if ( do_gsl_drag_ls_bl.or.do_gsl_drag_ss.or.do_gsl_drag_tofd ) then + + call drag_suite_run(im,levs,dvdt,dudt,dtdt,uwnd1,vwnd1, & + tgrs,q1,kpbl,prsi,del,prsl,prslk,phii,phil,dtp, & + kdt,hprime,oc,oa4,clx,varss,oc1ss,oa4ss, & + ol4ss,theta,sigma,gamma,elvmax,dtaux2d_ms, & + dtauy2d_ms,dtaux2d_bl,dtauy2d_bl,dtaux2d_ss, & + dtauy2d_ss,dtaux2d_fd,dtauy2d_fd,dusfcg, & + dvsfcg,dusfc_ms,dvsfc_ms,dusfc_bl,dvsfc_bl, & + dusfc_ss,dvsfc_ss,dusfc_fd,dvsfc_fd, & + slmsk,br1,hpbl,con_g,con_cp,con_rd,con_rv, & + con_fvirt,con_pi,lonr, & + cdmbgwd,me,master,lprnt,ipr,rdxzb,dx,gwd_opt, & + do_gsl_drag_ls_bl,do_gsl_drag_ss,do_gsl_drag_tofd, & + dtend, dtidx, index_of_process_orographic_gwd, & + index_of_temperature, index_of_x_wind, & + index_of_y_wind, ldiag3d, ldiag_ugwp, & + ugwp_seq_update, spp_wts_gwd, spp_gwd, errmsg, errflg) +! +! put zeros due to xy GSL-drag style: dtaux2d_bl,dtauy2d_bl,dtaux2d_ss.......dusfc_ms,dvsfc_ms +! + tau_mtb = 0. ; tau_ogw = 0. ; tau_tofd = 0. + dudt_mtb = 0. ; dudt_tms = 0. + + end if @@ -513,6 +567,11 @@ subroutine unified_ugwp_run(me, master, im, levs, ntrac, dtp, fhzero, kdt, prsl, prsi, phil, xlat_d, sinlat, coslat, gw_dudt, gw_dvdt, gw_dtdt, gw_kdis, & tau_ngw, me, master, kdt) + ! Save u, v, and t non-orogarphic tendencies for diagnostic output + dudt_ngw = gw_dudt + dvdt_ngw = gw_dvdt + dtdt_ngw = gw_dtdt + do k=1,levs do i=1,im gw_dtdt(i,k) = gw_dtdt(i,k)+ Pdtdt(i,k) diff --git a/physics/unified_ugwp.meta b/physics/unified_ugwp.meta index 2ff65e3d3..8af99957a 100644 --- a/physics/unified_ugwp.meta +++ b/physics/unified_ugwp.meta @@ -191,21 +191,21 @@ type = logical intent = in [do_gsl_drag_ls_bl] - standard_name = flag_for_gsl_drag_suite_large_scale_orographic_and_blocking_drag - long_name = flag to activate GSL drag suite - large-scale GWD and blocking + standard_name = do_gsl_drag_suite_mesoscale_orographic_and_blocking_drag + long_name = flag to activate GSL drag suite - mesoscale GWD and blocking units = flag dimensions = () type = logical intent = in [do_gsl_drag_ss] - standard_name = flag_for_gsl_drag_suite_small_scale_orographic_drag + standard_name = do_gsl_drag_suite_small_scale_orographic_drag long_name = flag to activate GSL drag suite - small-scale GWD units = flag dimensions = () type = logical intent = in [do_gsl_drag_tofd] - standard_name = flag_for_gsl_drag_suite_turbulent_orographic_form_drag + standard_name = do_gsl_drag_suite_turbulent_orographic_form_drag long_name = flag to activate GSL drag suite - turb orog form drag units = flag dimensions = () @@ -300,6 +300,22 @@ dimensions = () type = integer intent = in +[ak] + standard_name = sigma_pressure_hybrid_coordinate_a_coefficient + long_name = a parameter for sigma pressure level calculations + units = Pa + dimensions = (vertical_interface_dimension) + type = real + kind = kind_phys + intent = in +[bk] + standard_name = sigma_pressure_hybrid_coordinate_b_coefficient + long_name = b parameter for sigma pressure level calculations + units = none + dimensions = (vertical_interface_dimension) + type = real + kind = kind_phys + intent = in [ntrac] standard_name = number_of_tracers long_name = number of tracers @@ -464,17 +480,17 @@ type = real kind = kind_phys intent = in -[dusfc_ls] +[dusfc_ms] standard_name = vertically_integrated_x_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag - long_name = integrated x momentum flux from large scale gwd + long_name = integrated x momentum flux from mesoscale gwd units = Pa dimensions = (horizontal_loop_extent) type = real kind = kind_phys intent = out -[dvsfc_ls] +[dvsfc_ms] standard_name = vertically_integrated_y_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag - long_name = integrated y momentum flux from large scale gwd + long_name = integrated y momentum flux from mesoscale gwd units = Pa dimensions = (horizontal_loop_extent) type = real @@ -528,7 +544,7 @@ type = real kind = kind_phys intent = out -[dtaux2d_ls] +[dtaux2d_ms] standard_name = tendency_of_x_wind_due_to_mesoscale_orographic_gravity_wave_drag long_name = instantaneous change in x wind due to orographic gw drag units = m s-2 @@ -536,7 +552,7 @@ type = real kind = kind_phys intent = out -[dtauy2d_ls] +[dtauy2d_ms] standard_name = tendency_of_y_wind_due_to_mesoscale_orographic_gravity_wave_drag long_name = instantaneous change in y wind due to orographic gw drag units = m s-2 @@ -545,53 +561,77 @@ kind = kind_phys intent = out [dtaux2d_bl] - standard_name = tendency_of_x_momentum_due_to_blocking_drag - long_name = x momentum tendency from blocking drag + standard_name = tendency_of_x_wind_due_to_blocking_drag + long_name = x wind tendency from blocking drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = out [dtauy2d_bl] - standard_name = tendency_of_y_momentum_due_to_blocking_drag - long_name = y momentum tendency from blocking drag + standard_name = tendency_of_y_wind_due_to_blocking_drag + long_name = y wind tendency from blocking drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = out [dtaux2d_ss] - standard_name = tendency_of_x_momentum_due_to_small_scale_gravity_wave_drag - long_name = x momentum tendency from small scale gwd + standard_name = tendency_of_x_wind_due_to_small_scale_gravity_wave_drag + long_name = x wind tendency from small scale gwd units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = out [dtauy2d_ss] - standard_name = tendency_of_y_momentum_due_to_small_scale_gravity_wave_drag - long_name = y momentum tendency from small scale gwd + standard_name = tendency_of_y_wind_due_to_small_scale_gravity_wave_drag + long_name = y wind tendency from small scale gwd units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = out [dtaux2d_fd] - standard_name = tendency_of_x_momentum_due_to_form_drag - long_name = x momentum tendency from form drag + standard_name = tendency_of_x_wind_due_to_form_drag + long_name = x wind tendency from form drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = out [dtauy2d_fd] - standard_name = tendency_of_y_momentum_due_to_form_drag - long_name = y momentum tendency from form drag + standard_name = tendency_of_y_wind_due_to_form_drag + long_name = y wind tendency from form drag units = m s-2 dimensions = (horizontal_loop_extent,vertical_layer_dimension) type = real kind = kind_phys intent = out +[dudt_ngw] + standard_name = tendency_of_x_wind_due_to_nonorographic_gravity_wave_drag + long_name = zonal wind tendency due to non-stationary GWs + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = out +[dvdt_ngw] + standard_name = tendency_of_y_wind_due_to_nonorographic_gravity_wave_drag + long_name = meridional wind tendency due to non-stationary GWs + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = out +[dtdt_ngw] + standard_name = tendency_of_air_temperature_due_to_nonorographic_gravity_wave_drag + long_name = air temperature tendency due to non-stationary GWs + units = K s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = out [br1] standard_name = bulk_richardson_number_at_lowest_model_level long_name = bulk Richardson number at the surface @@ -630,6 +670,13 @@ dimensions = () type = logical intent = in +[ugwp_seq_update] + standard_name = do_ugwp_sequential_update + long_name = flag for ugwp sequential update + units = flag + dimensions = () + type = logical + intent = in [cdmbgwd] standard_name = multiplicative_tunable_parameters_for_mountain_blocking_and_orographic_gravity_wave_drag long_name = multiplication factors for cdmb and gwd @@ -1151,21 +1198,21 @@ type = logical intent = in [do_gsl_drag_ls_bl] - standard_name = flag_for_gsl_drag_suite_large_scale_orographic_and_blocking_drag - long_name = flag to activate GSL drag suite - large-scale GWD and blocking + standard_name = do_gsl_drag_suite_mesoscale_orographic_and_blocking_drag + long_name = flag to activate GSL drag suite - mesoscale GWD and blocking units = flag dimensions = () type = logical intent = in [do_gsl_drag_ss] - standard_name = flag_for_gsl_drag_suite_small_scale_orographic_drag + standard_name = do_gsl_drag_suite_small_scale_orographic_drag long_name = flag to activate GSL drag suite - small-scale GWD units = flag dimensions = () type = logical intent = in [do_gsl_drag_tofd] - standard_name = flag_for_gsl_drag_suite_turbulent_orographic_form_drag + standard_name = do_gsl_drag_suite_turbulent_orographic_form_drag long_name = flag to activate GSL drag suite - turb orog form drag units = flag dimensions = () diff --git a/physics/unified_ugwp_post.F90 b/physics/unified_ugwp_post.F90 index e137df43f..9c3717546 100644 --- a/physics/unified_ugwp_post.F90 +++ b/physics/unified_ugwp_post.F90 @@ -10,12 +10,21 @@ module unified_ugwp_post !! \section arg_table_unified_ugwp_post_run Argument Table !! \htmlinclude unified_ugwp_post_run.html !! - subroutine unified_ugwp_post_run (ldiag_ugwp, dtf, im, levs, & + subroutine unified_ugwp_post_run (ldiag3d, ldiag_ugwp, & + dtf, im, levs, & gw_dtdt, gw_dudt, gw_dvdt, tau_tofd, tau_mtb, tau_ogw, & - tau_ngw, zmtb, zlwb, zogw, dudt_mtb, dudt_ogw, dudt_tms, & - tot_zmtb, tot_zlwb, tot_zogw, & + tau_ngw, zmtb, zlwb, zogw, dudt_mtb, dudt_ogw, dvdt_ogw, & + dudt_tms, tot_zmtb, tot_zlwb, tot_zogw, & tot_tofd, tot_mtb, tot_ogw, tot_ngw, & du3dt_mtb,du3dt_ogw, du3dt_tms, du3dt_ngw, dv3dt_ngw, & + ldu3dt_ogw, ldu3dt_obl, ldu3dt_oss, ldu3dt_ofd, & + dudt_ngw, dvdt_ngw, dtdt_ngw, & + ldu3dt_ngw, ldv3dt_ngw, ldt3dt_ngw, dudt_obl, dvdt_obl, & + dudt_oss, dvdt_oss, dudt_ofd, dvdt_ofd, dws3dt_ogw, & + dws3dt_obl, dws3dt_oss, dws3dt_ofd, du_ogwcol, dv_ogwcol, & + du_oblcol, dv_oblcol, du_osscol, dv_osscol, du_ofdcol, & + dv_ofdcol, du3_ogwcol, dv3_ogwcol, du3_oblcol, dv3_oblcol, & + du3_osscol, dv3_osscol, du3_ofdcol, dv3_ofdcol, & dtdt, dudt, dvdt, errmsg, errflg) use machine, only: kind_phys @@ -26,13 +35,30 @@ subroutine unified_ugwp_post_run (ldiag_ugwp, dtf, im, levs, & integer, intent(in) :: im, levs real(kind=kind_phys), intent(in) :: dtf logical, intent(in) :: ldiag_ugwp !< flag for CIRES UGWP Diagnostics + logical, intent(in) :: ldiag3d real(kind=kind_phys), intent(in), dimension(:) :: zmtb, zlwb, zogw real(kind=kind_phys), intent(in), dimension(:) :: tau_mtb, tau_ogw, tau_tofd, tau_ngw real(kind=kind_phys), intent(inout), dimension(:) :: tot_mtb, tot_ogw, tot_tofd, tot_ngw real(kind=kind_phys), intent(inout), dimension(:) :: tot_zmtb, tot_zlwb, tot_zogw - real(kind=kind_phys), intent(in), dimension(:,:) :: gw_dtdt, gw_dudt, gw_dvdt, dudt_mtb, dudt_ogw, dudt_tms + real(kind=kind_phys), intent(in), dimension(:,:) :: gw_dtdt, gw_dudt, gw_dvdt, dudt_mtb + real(kind=kind_phys), intent(in), dimension(:,:) :: dudt_ogw, dvdt_ogw, dudt_tms real(kind=kind_phys), intent(inout), dimension(:,:) :: du3dt_mtb, du3dt_ogw, du3dt_tms, du3dt_ngw, dv3dt_ngw + real(kind=kind_phys), intent(inout), dimension(:,:) :: ldu3dt_ogw, ldu3dt_obl, ldu3dt_oss, ldu3dt_ofd + real(kind=kind_phys), intent(in), dimension(:,:) :: dudt_ngw, dvdt_ngw, dtdt_ngw + real(kind=kind_phys), intent(inout), dimension(:,:) :: ldu3dt_ngw, ldv3dt_ngw, ldt3dt_ngw + real(kind=kind_phys), intent(in), dimension(:,:) :: dudt_obl, dvdt_obl + real(kind=kind_phys), intent(in), dimension(:,:) :: dudt_oss, dvdt_oss, dudt_ofd, dvdt_ofd + real(kind=kind_phys), intent(inout), dimension(:,:) :: dws3dt_obl, dws3dt_ogw + real(kind=kind_phys), intent(inout), dimension(:,:) :: dws3dt_oss, dws3dt_ofd + real(kind=kind_phys), intent(in), dimension(:) :: du_ogwcol, dv_ogwcol + real(kind=kind_phys), intent(in), dimension(:) :: du_oblcol, dv_oblcol + real(kind=kind_phys), intent(in), dimension(:) :: du_osscol, dv_osscol + real(kind=kind_phys), intent(in), dimension(:) :: du_ofdcol, dv_ofdcol + real(kind=kind_phys), intent(inout), dimension(:) :: du3_ogwcol, dv3_ogwcol + real(kind=kind_phys), intent(inout), dimension(:) :: du3_oblcol, dv3_oblcol + real(kind=kind_phys), intent(inout), dimension(:) :: du3_osscol, dv3_osscol + real(kind=kind_phys), intent(inout), dimension(:) :: du3_ofdcol, dv3_ofdcol real(kind=kind_phys), intent(inout), dimension(:,:) :: dtdt, dudt, dvdt character(len=*), intent(out) :: errmsg @@ -57,7 +83,28 @@ subroutine unified_ugwp_post_run (ldiag_ugwp, dtf, im, levs, & du3dt_ogw = du3dt_ogw + dtf *dudt_ogw du3dt_ngw = du3dt_ngw + dtf *gw_dudt dv3dt_ngw = dv3dt_ngw + dtf *gw_dvdt - endif + + dws3dt_ogw = dws3dt_ogw + dtf *sqrt(dudt_ogw**2+dvdt_ogw**2) + dws3dt_obl = dws3dt_obl + dtf *sqrt(dudt_obl**2+dvdt_obl**2) + dws3dt_oss = dws3dt_oss + dtf *sqrt(dudt_oss**2+dvdt_oss**2) + dws3dt_ofd = dws3dt_ofd + dtf *sqrt(dudt_ofd**2+dvdt_ofd**2) + ldu3dt_ogw = ldu3dt_ogw + dtf *dudt_ogw + ldu3dt_obl = ldu3dt_obl + dtf *dudt_obl + ldu3dt_oss = ldu3dt_oss + dtf *dudt_oss + ldu3dt_ofd = ldu3dt_ofd + dtf *dudt_ofd + du3_ogwcol = du3_ogwcol + dtf *du_ogwcol + dv3_ogwcol = dv3_ogwcol + dtf *dv_ogwcol + du3_oblcol = du3_oblcol + dtf *du_oblcol + dv3_oblcol = dv3_oblcol + dtf *dv_oblcol + du3_osscol = du3_osscol + dtf *du_osscol + dv3_osscol = dv3_osscol + dtf *dv_osscol + du3_ofdcol = du3_ofdcol + dtf *du_ofdcol + dv3_ofdcol = dv3_ofdcol + dtf *dv_ofdcol + ! Special treatment for non-stationary GWD diagnostics + ldu3dt_ngw = ldu3dt_ngw + dtf *dudt_ngw + ldv3dt_ngw = ldv3dt_ngw + dtf *dvdt_ngw + ldt3dt_ngw = ldt3dt_ngw + dtf *dtdt_ngw + end if dtdt = dtdt + gw_dtdt dudt = dudt + gw_dudt diff --git a/physics/unified_ugwp_post.meta b/physics/unified_ugwp_post.meta index 1df5cc5b5..6da6342df 100644 --- a/physics/unified_ugwp_post.meta +++ b/physics/unified_ugwp_post.meta @@ -7,6 +7,13 @@ [ccpp-arg-table] name = unified_ugwp_post_run type = scheme +[ldiag3d] + standard_name = flag_for_diagnostics_3D + long_name = flag for 3d diagnostic fields + units = flag + dimensions = () + type = logical + intent = in [ldiag_ugwp] standard_name = flag_for_unified_gravity_wave_physics_diagnostics long_name = flag for CIRES UGWP Diagnostics @@ -132,6 +139,14 @@ type = real kind = kind_phys intent = in +[dvdt_ogw] + standard_name = tendency_of_y_wind_due_to_mesoscale_orographic_gravity_wave_drag + long_name = y momentum tendency from meso scale ogw + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in [dudt_tms] standard_name = tendency_of_x_wind_due_to_turbulent_orographic_form_drag long_name = instantaneous change in x wind due to TOFD @@ -236,6 +251,294 @@ type = real kind = kind_phys intent = inout +[ldu3dt_ogw] + standard_name = cumulative_change_in_x_wind_due_to_mesoscale_orographic_gravity_wave_drag + long_name = cumulative change in x wind due to mesoscale orographic gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldu3dt_obl] + standard_name = cumulative_change_in_x_wind_due_to_blocking_drag + long_name = cumulative change in x wind due to blocking drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldu3dt_oss] + standard_name = cumulative_change_in_x_wind_due_to_small_scale_gravity_wave_drag + long_name = cumulative change in x wind due to small scale gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldu3dt_ofd] + standard_name = cumulative_change_in_x_wind_due_to_form_drag + long_name = cumulative change in x wind due to form drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dudt_ngw] + standard_name = tendency_of_x_wind_due_to_nonorographic_gravity_wave_drag + long_name = zonal wind tendency due to non-stationary GWs + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dvdt_ngw] + standard_name = tendency_of_y_wind_due_to_nonorographic_gravity_wave_drag + long_name = meridional wind tendency due to non-stationary GWs + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dtdt_ngw] + standard_name = tendency_of_air_temperature_due_to_nonorographic_gravity_wave_drag + long_name = air temperature tendency due to non-stationary GWs + units = K s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[ldu3dt_ngw] + standard_name = cumulative_change_in_x_wind_due_to_convective_gravity_wave_drag + long_name = cumulative change in x wind due to convective gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldv3dt_ngw] + standard_name = cumulative_change_in_y_wind_due_to_convective_gravity_wave_drag + long_name = cumulative change in y wind due to convective gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[ldt3dt_ngw] + standard_name = cumulative_change_in_temperature_due_to_convective_gravity_wave_drag + long_name = cumulative change in temperature due to convective gravity wave drag + units = K + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dudt_obl] + standard_name = tendency_of_x_wind_due_to_blocking_drag + long_name = x wind tendency from blocking drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dvdt_obl] + standard_name = tendency_of_y_wind_due_to_blocking_drag + long_name = y wind tendency from blocking drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dudt_oss] + standard_name = tendency_of_x_wind_due_to_small_scale_gravity_wave_drag + long_name = x wind tendency from small scale gwd + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dvdt_oss] + standard_name = tendency_of_y_wind_due_to_small_scale_gravity_wave_drag + long_name = y wind tendency from small scale gwd + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dudt_ofd] + standard_name = tendency_of_x_wind_due_to_form_drag + long_name = x wind tendency from form drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dvdt_ofd] + standard_name = tendency_of_y_wind_due_to_form_drag + long_name = y wind tendency from form drag + units = m s-2 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = in +[dws3dt_ogw] + standard_name = cumulative_change_in_wind_speed_due_to_mesoscale_orographic_gravity_wave_drag + long_name = cumulative change in wind speed due to mesoscale orographic gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dws3dt_obl] + standard_name = cumulative_change_in_wind_speed_due_to_blocking_drag + long_name = cumulative change in wind speed due to blocking drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dws3dt_oss] + standard_name = cumulative_change_in_wind_speed_due_to_small_scale_orographic_gravity_wave_drag + long_name = cumulative change in wind speed due to small scale orographic gravity wave drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[dws3dt_ofd] + standard_name = cumulative_change_in_wind_speed_due_to_turbulent_orographic_form_drag + long_name = cumulative change in wind speed due to turbulent orographic form drag + units = m s-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + type = real + kind = kind_phys + intent = inout +[du_ogwcol] + standard_name = vertically_integrated_x_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = integrated x momentum flux from meso scale ogw + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[dv_ogwcol] + standard_name = vertically_integrated_y_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = integrated y momentum flux from meso scale ogw + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[du_oblcol] + standard_name = vertically_integrated_x_momentum_flux_due_to_blocking_drag + long_name = integrated x momentum flux from blocking drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[dv_oblcol] + standard_name = vertically_integrated_y_momentum_flux_due_to_blocking_drag + long_name = integrated y momentum flux from blocking drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[du_osscol] + standard_name = vertically_integrated_x_momentum_flux_due_to_small_scale_gravity_wave_drag + long_name = integrated x momentum flux from small scale gwd + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[dv_osscol] + standard_name = vertically_integrated_y_momentum_flux_due_to_small_scale_gravity_wave_drag + long_name = integrated y momentum flux from small scale gwd + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[du_ofdcol] + standard_name = vertically_integrated_x_momentum_flux_due_to_form_drag + long_name = integrated x momentum flux from form drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[dv_ofdcol] + standard_name = vertically_integrated_y_momentum_flux_due_to_form_drag + long_name = integrated y momentum flux from form drag + units = Pa + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[du3_ogwcol] + standard_name = cumulative_vertically_integrated_x_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = cumulative integrated x momentum flux from mesoscale orographic gravity wave drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dv3_ogwcol] + standard_name = cumulative_vertically_integrated_y_momentum_flux_due_to_mesoscale_orographic_gravity_wave_drag + long_name = cumulative integrated y momentum flux from mesoscale orographic gravity wave drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[du3_oblcol] + standard_name = cumulative_vertically_integrated_x_momentum_flux_due_to_blocking_drag + long_name = cumulative integrated x momentum flux from blocking drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dv3_oblcol] + standard_name = cumulative_vertically_integrated_y_momentum_flux_due_to_blocking_drag + long_name = cumulative integrated y momentum flux from blocking drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[du3_osscol] + standard_name = cumulative_vertically_integrated_x_momentum_flux_due_to_small_scale_gravity_wave_drag + long_name = cumulative integrated x momentum flux from small scale gravity wave drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dv3_osscol] + standard_name = cumulative_vertically_integrated_y_momentum_flux_due_small_scale_gravity_wave_drag + long_name = cumulative integrated y momentum flux from small scale gravity wave drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[du3_ofdcol] + standard_name = cumulative_vertically_integrated_x_momentum_flux_due_to_form_drag + long_name = cumulative integrated x momentum flux from form drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[dv3_ofdcol] + standard_name = cumulative_vertically_integrated_y_momentum_flux_due_to_form_drag + long_name = cumulative integrated y momentum flux from form drag + units = Pa s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout [dtdt] standard_name = process_split_cumulative_tendency_of_air_temperature long_name = air temperature tendency due to model physics diff --git a/smoke/dep_dry_gocart_mod.F90 b/smoke/dep_dry_gocart_mod.F90 deleted file mode 100755 index 9fb5edfd1..000000000 --- a/smoke/dep_dry_gocart_mod.F90 +++ /dev/null @@ -1,302 +0,0 @@ -!>\file dep_dry_gocart_mod.F90 -!! This file is GOCART dry deposition module to calculate the dry deposition -!! velocities of smoke and dust. - -module dep_dry_gocart_mod - - use machine , only : kind_phys - use rrfs_smoke_data - - implicit none - - private - - public :: gocart_drydep_driver - -CONTAINS - -subroutine gocart_drydep_driver(numgas, & - moist,p8w,chem,rho_phy,dz8w,ddvel,xland,hfx, & - ivgtyp,tsk,pbl,ust,znt,g, & - num_moist,num_chem, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - - IMPLICIT NONE - INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - num_moist,num_chem, & - its,ite, jts,jte, kts,kte,numgas - REAL(kind_phys), INTENT(IN ) :: g - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ),& - INTENT(IN ) :: moist - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ) ,& - INTENT(INOUT) :: chem - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) ,& - INTENT(IN ) :: dz8w, p8w,rho_phy - INTEGER, DIMENSION( ims:ime , jms:jme ) ,& - INTENT(IN ) :: ivgtyp - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) ,& - INTENT(INOUT) :: tsk, & - pbl, & - ust, & - xland,znt,hfx - -!! .. Local Scalars .. - - INTEGER :: iland, iprt, iseason, jce, jcs, & - n, nr, ipr, jpr, nvr, & - idrydep_onoff,imx,jmx,lmx - integer :: ii,jj,kk,i,j,k,nv - integer, dimension (1,1) :: ilwi - real(kind_phys), DIMENSION (5) :: tc,bems - real(kind_phys), dimension (1,1) :: z0,w10m,gwet,airden,airmas,& - delz_sfc,hflux,ts,pblz,ustar,& - ps,dvel,drydf - REAL(kind_phys), DIMENSION( its:ite, jts:jte, num_chem ) :: ddvel - - do nv=1,num_chem - do j=jts,jte - do i=its,ite - ddvel(i,j,nv)=0. - enddo - enddo - enddo - imx=1 - jmx=1 - lmx=1 - do j=jts,jte - do i=its,ite - dvel(1,1)=0. - ilwi(1,1)=0 - if(xland(i,j).gt.1.5)ilwi=1 -! for aerosols, ii=1 or ii=2 - ii=1 - if(ivgtyp(i,j).eq.19.or.ivgtyp(i,j).eq.23)ii=1 - airden(1,1)=rho_phy(i,kts,j) - delz_sfc(1,1)=dz8w(i,kts,j) - ustar(1,1)=ust(i,j) - hflux(1,1)=hfx(i,j) - pblz(1,1)=pbl(i,j) - ps(1,1)=p8w(i,kts,j)*.01 - z0(1,1)=znt(i,j) - ts(1,1)=tsk(i,j) - - call depvel_gocart(ii,imx,jmx,lmx,& - airden, delz_sfc, pblz, ts, ustar, hflux, ilwi, & - ps, z0, dvel, drydf,g) - do nv=1,num_chem - ddvel(i,j,nv)=dvel(1,1) - enddo - enddo - enddo -end subroutine gocart_drydep_driver - - - -SUBROUTINE depvel_gocart( & - ii,imx,jmx,lmx,& - airden, delz_sfc, pblz, ts, ustar, hflux, ilwi, & - ps, z0, dvel, drydf,g0) - -! **************************************************************************** -! * * -! * Calculate dry deposition velocity. * -! * * -! * Input variables: * -! * AEROSOL(k) - Logical, T = aerosol species, F = gas species * -! * IREG(i,j) - # of landtypes in grid square * -! * ILAND(i,j,ldt) - Land type ID for element ldt =1,IREG(i,j) * -! * IUSE(i,j,ldt) - Fraction of gridbox area occupied by land type * -! * element ldt * -! * USTAR(i,j) - Friction velocity (m s-1) * -! * DELZ_SFC(i,j) - Thickness of layer above surface * -! * PBLZ(i,j) - Mixing depth (m) * -! * Z0(i,j) - Roughness height (m) * -! * * -! * Determined in this subroutine (local): * -! * OBK - Monin-Obukhov length (m): set to 1.E5 m under * -! * neutral conditions * -! * Rs(ldt) - Bulk surface resistance(s m-1) for species k to * -! * surface ldt * -! * Ra - Aerodynamic resistance. * -! * Rb - Sublayer resistance. * -! * Rs - Surface resistance. * -! * Rttl - Total deposition resistance (s m-1) for species k * -! * Rttl(k) = Ra + Rb + Rs. * -! * * -! * Returned: * -! * DVEL(i,j,k) - Deposition velocity (m s-1) of species k * -! * DRYDf(i,j,k) - Deposition frequency (s-1) of species k, * -! * = DVEL / DELZ_SFC * -! * * -! **************************************************************************** - - - IMPLICIT NONE - INTEGER, INTENT(IN) :: imx,jmx,lmx - REAL(kind_phys), INTENT(IN) :: airden(imx,jmx), delz_sfc(imx,jmx) - REAL(kind_phys), INTENT(IN) :: hflux(imx,jmx), ts(imx,jmx) - REAL(kind_phys), INTENT(IN) :: ustar(imx,jmx), pblz(imx,jmx) - REAL(kind_phys), INTENT(IN) :: ps(imx,jmx) - INTEGER, INTENT(IN) :: ilwi(imx,jmx) - REAL(kind_phys), INTENT(IN) :: z0(imx,jmx) - REAL(kind=kind_phys), INTENT(IN) :: g0 - REAL(kind_phys), INTENT(OUT) :: dvel(imx,jmx), drydf(imx,jmx) - - REAL(kind_phys) :: obk, vds, czh, rttl, frac, logmfrac, psi_h, cz, eps - REAL(kind_phys) :: vd, ra, rb, rs - INTEGER :: i, j, k, ldt, iolson, ii - CHARACTER(LEN=50) :: msg - REAL(kind_phys) :: prss, tempk, tempc, xnu, ckustr, reyno, aird, diam, xm, z - REAL(kind_phys) :: frpath, speed, dg, dw, rt - REAL(kind_phys) :: rad0, rix, gfact, gfaci, rdc, rixx, rluxx, rgsx, rclx - REAL(kind_phys) :: dtmp1, dtmp2, dtmp3, dtmp4 - REAL(kind_phys) :: biofit,vk - - psi_h=0.0 - ! executable statements - j_loop: DO j = 1,jmx - i_loop: DO i = 1,imx - vk=.4 - vd = 0.0 - ra = 0.0 - rb = 0.0 ! only required for gases (SO2) - rs = 0.0 - -! **************************************************************************** -! * Compute the the Monin-Obhukov length. * -! * The direct computation of the Monin-Obhukov length is: * -! * * -! * - Air density * Cp * T(surface air) * Ustar^3 * -! * OBK = ---------------------------------------------- * -! * vK * g * Sensible Heat flux * -! * * -! * Cp = 1000 J/kg/K = specific heat at constant pressure * -! * vK = 0.4 = von Karman's constant * -! **************************************************************************** - - IF (hflux(i,j) == 0.0) THEN - obk = 1.0E5 - ELSE - ! MINVAL(hflux), MINVAL(airden), MINVAL(ustar) =?? - obk = -airden(i,j) * 1000.0 * ts(i,j) * (ustar(i,j))**3 & - / (vk * g0 * hflux(i,j)) -! -- debug: - IF ( obk == 0.0 ) WRITE(*,211) obk, i, j -211 FORMAT(1X,'OBK=', E11.2, 1X,' i,j = ', 2I4) - - END IF - - cz = delz_sfc(i,j) / 2.0 ! center of the grid box above surface - -! **************************************************************************** -! * (1) Aerosodynamic resistance Ra and sublayer resistance Rb. * -! * * -! * The Reynolds number REYNO diagnoses whether a surface is * -! * aerodynamically rough (REYNO > 10) or smooth. Surface is * -! * rough in all cases except over water with low wind speeds. * -! * * -! * For gas species over land and ice (REYNO >= 10) and for aerosol * -! * species for all surfaces: * -! * * -! * Ra = 1./VT (VT from GEOS Kzz at L=1, m/s). * -! * * -! * The following equations are from Walcek et al, 1986: * -! * * -! * For gas species when REYNO < 10 (smooth), Ra and Rb are combined * -! * as Ra: * -! * * -! * Ra = { ln(ku* z1/Dg) - Sh } / ku* eq.(13) * -! * * -! * where z1 is the altitude at the center of the lowest model layer * -! * (CZ); * -! * Sh is a stability correction function; * -! * k is the von Karman constant (0.4, vK); * -! * u* is the friction velocity (USTAR). * -! * * -! * Sh is computed as a function of z1 and L eq ( 4) and (5)): * -! * * -! * 0 < z1/L <= 1: Sh = -5 * z1/L * -! * z1/L < 0: Sh = exp{ 0.598 + 0.39*ln(E) - 0.09(ln(E))^2 } * -! * where E = min(1,-z1/L) (Balkanski, thesis). * -! * * -! * For gas species when REYNO >= 10, * -! * * -! * Rb = 2/ku* (Dair/Dg)**(2/3) eq.(12) * -! * where Dg is the gas diffusivity, and * -! * Dair is the air diffusivity. * -! * * -! * For aerosol species, Rb is combined with surface resistance as Rs. * -! * * -! **************************************************************************** - - frac = cz / obk - IF (frac > 1.0) frac = 1.0 - IF (frac > 0.0 .AND. frac <= 1.0) THEN - psi_h = -5.0*frac - ELSE IF (frac < 0.0) THEN - eps = MIN(1.0D0, -frac) - logmfrac = LOG(eps) - psi_h = EXP( 0.598 + 0.39 * logmfrac - 0.09 * (logmfrac)**2 ) - END IF - !-------------------------------------------------------------- - ! Aerosol species, Rs here is the combination of Rb and Rs. - - ra = (LOG(cz/z0(i,j)) - psi_h) / (vk*ustar(i,j)) - - vds = 0.002*ustar(i,j) - IF (obk < 0.0) & - vds = vds * (1.0+(-300.0/obk)**0.6667) - - czh = pblz(i,j)/obk - IF (czh < -30.0) vds = 0.0009*ustar(i,j)*(-czh)**0.6667 - - ! --Set Vds to be less than VDSMAX (entry in input file divided -- - ! by 1.E4). VDSMAX is taken from Table 2 of Walcek et al. [1986]. - ! Invert to get corresponding R - if(ii.eq.1)then - rs=1.0/MIN(vds,2.0D-2) - else - rs=1.0/MIN(vds,2.0D-3) - endif - - - ! ------ Set max and min values for bulk surface resistances ------ - - rs= MAX(1.0D0, MIN(rs, 9.9990D+3)) - -! **************************************************************************** -! * * -! * Compute dry deposition velocity. * -! * * -! * IUSE is the fraction of the grid square occupied by surface ldt in * -! * units of per mil (IUSE=500 -> 50% of the grid square). Add the * -! * contribution of surface type ldt to the deposition velocity; this is * -! * a loop over all surface types in the gridbox. * -! * * -! * Total resistance = Ra + Rb + Rs. -! * * -! **************************************************************************** - - rttl = ra + rb + rs - vd = vd + 1./rttl - - ! ------ Load array DVEL ------ - dvel(i,j) = vd * 1.2 - - ! -- Set a minimum value for DVEL - ! MIN(VdSO2) = 2.0e-3 m/s over ice - ! = 3.0e-3 m/s over land - ! MIN(vd_aerosol) = 1.0e-4 m/s - - IF (dvel(i,j) < 1.0E-4) dvel(i,j) = 1.0E-4 - drydf(i,j) = dvel(i,j) / delz_sfc(i,j) - - END DO i_loop - END DO j_loop - -END SUBROUTINE depvel_gocart - -end module dep_dry_gocart_mod diff --git a/smoke/dep_dry_mod.F90 b/smoke/dep_dry_mod.F90 deleted file mode 100755 index 9520d2897..000000000 --- a/smoke/dep_dry_mod.F90 +++ /dev/null @@ -1,303 +0,0 @@ -!>\file dep_dry_mod.F90 -!! This file is for the dry depostion driver. - -module dep_dry_mod - - use machine , only : kind_phys - use rrfs_smoke_config, only : epsilc, GOCART_SIMPLE => CHEM_OPT_GOCART, CTRA_OPT_NONE -! use chem_tracers_mod, only : p_o3,p_dust_1,p_vash_1,p_vash_4,p_vash_10,p_dms, -! & -! config_flags => chem_config - use dep_dry_gocart_mod - use dep_simple_mod - use dep_vertmx_mod -! use aero_soa_vbs_mod, only : soa_vbs_depdriver - - implicit none - - - private - - public :: dry_dep_driver - -contains - - subroutine dry_dep_driver(data,ktau,dtstep,julday,current_month,t_phy,p_phy, & - moist,p8w,rmol,alt,gmt,t8w,raincv, & - chem,rho_phy,dz8w,exch_h,hfx, & - ivgtyp,tsk,gsw,vegfra,pbl,ust,znt,z,z_at_w, & - xland,xlat,xlong,h2oaj,h2oai,nu3,ac3,cor3,asulf,ahno3, & - anh3,ddep,dep_vel_o3,g, & - e_co,kemit,snowh,numgas, & - num_chem,num_moist, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) -!---------------------------------------------------------------------- -! USE module_model_constants -! USE module_configure -! USE module_state_description -! USE module_dep_simple -! USE module_initial_chem_namelists,only:p_o3,p_dust_1,p_vash_1,p_vash_4,p_vash_10,p_dms -! USE module_vertmx_wrf -! USE module_chemvars,only:epsilc -! USE module_data_sorgam -! USE module_aerosols_sorgam -! USE module_gocart_settling -! use module_dep_simple -! USE module_gocart_drydep,only: gocart_drydep_driver -! USE module_aerosols_soa_vbs, only: soa_vbs_depdriver -! USE module_mosaic_drydep, only: mosaic_drydep_driver -! USE module_mixactivate_wrappers, only: mosaic_mixactivate, sorgam_mixactivate - IMPLICIT NONE - type(smoke_data), pointer, intent(inout) :: data - - INTEGER, INTENT(IN ) :: numgas, current_month, & - num_chem,num_moist, julday, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte - INTEGER, INTENT(IN ) :: & - ktau - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & - INTENT(IN ) :: moist - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), & - INTENT(INOUT ) :: chem - - INTEGER, INTENT(IN ) :: kemit - REAL(kind_phys), DIMENSION( ims:ime, kms:kemit, jms:jme ), & - INTENT(IN ) :: & - e_co - - - - - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) , & - INTENT(IN ) :: & - alt, & - t8w, & - dz8w, & - p8w,z_at_w , & - exch_h,rho_phy,z - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) , & - INTENT(INOUT) :: & - h2oaj,h2oai,nu3,ac3,cor3,asulf,ahno3,anh3 - INTEGER,DIMENSION( ims:ime , jms:jme ) , & - INTENT(IN ) :: & - ivgtyp - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) , & - INTENT(INOUT) :: & - tsk, & - gsw, & - vegfra, & - pbl, & - snowh, & - raincv, & - ust, & - hfx, & - xland, & - xlat, & - xlong, & - znt,rmol - REAL(kind_phys), DIMENSION( ims:ime, jms:jme, num_chem ), & - INTENT(OUT ) :: ddep - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) , & - INTENT(OUT) :: & - dep_vel_o3 - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & - INTENT(IN ) :: & - p_phy, & - t_phy - - REAL(kind_phys), INTENT(IN ) :: & - dtstep,g,gmt - -!--- deposition and emissions stuff -! .. Parameters .. -! .. -! .. Local Scalars .. - - REAL(kind_phys) :: cdt, factor - - INTEGER :: idrydep_onoff - -! INTEGER :: chem_conv_tr, chem_opt - -! CHARACTER (4) :: luse_typ,mminlu_loc -! .. -! .. Local Arrays .. - REAL(kind_phys), DIMENSION( its:ite, jts:jte, num_chem ) :: ddvel - -! REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) :: dryrho_phy - REAL(kind_phys), DIMENSION( kts:kte ) :: dryrho_1d - -! turbulent transport - real(kind_phys) :: pblst(kts:kte),ekmfull(kts:kte+1),zzfull(kts:kte+1),zz(kts:kte) - integer :: i,j,k,nv -! -! necessary for aerosols (module dependent) -! - REAL(kind_phys), DIMENSION( its:ite, jts:jte ) :: aer_res - REAL(kind_phys), DIMENSION( its:ite, jts:jte ) :: aer_res_def - REAL(kind_phys), DIMENSION( its:ite, jts:jte ) :: aer_res_zcen - -! .. -! .. Intrinsic Functions .. - INTRINSIC max, min - -! chem_opt = chem_opt -! chem_conv_tr = chem_conv_tr - -! -! compute dry deposition velocities = ddvel -! -! 28-jun-2005 rce - initialize ddvel=0; call aerosol drydep routine -! only when drydep_opt == WESELY -! the wesely_driver routine computes aer_res, and currently -! you cannot compute aerosol drydep without it !! -! 08-jul-2005 rce - pass idrydep_onoff to mixactivate routines -! -! write(6,*)'call dry dep driver' - dep_vel_o3(:,:)=0. - ddvel(:,:,:) = 0.0 - idrydep_onoff = 0 - -! drydep_select: SELECT CASE(drydep_opt) - -! CASE ( WESELY ) -! -! drydep_opt == WESELY means -! wesely for gases -! other (appropriate) routine for aerosols -! -! CALL wrf_debug(15,'DOING DRY DEP VELOCITIES WITH WESELY METHOD') - - IF( chem_opt /= GOCART_SIMPLE ) THEN - call wesely_driver(data,ktau,dtstep, & - current_month, & - gmt,julday,t_phy,moist,p8w,t8w,raincv, & - p_phy,chem,rho_phy,dz8w,ddvel,aer_res_def,aer_res_zcen, & - ivgtyp,tsk,gsw,vegfra,pbl,rmol,ust,znt,xlat,xlong,z,z_at_w,& - snowh,numgas, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - ENDIF - IF (( chem_opt == GOCART_SIMPLE ) .or. & - ( chem_opt == GOCARTRACM_KPP) .or. & - ( chem_opt == 316) .or. & - ( chem_opt == 317) .or. & -! ( chem_opt == 502) .or. & - (chem_opt == 304 )) then -! -! this does aerosol species (dust,seas, bc,oc) for gocart only -! this does aerosol species (dust,seas, bc,oc,sulf) for gocart only -!, - call gocart_drydep_driver(numgas, & - moist,p8w,chem,rho_phy,dz8w,ddvel,xland,hfx, & - ivgtyp,tsk,pbl,ust,znt,g, & - num_moist,num_chem, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - ELSE if (chem_opt == 501 ) then -! for caesium .1cm/s -! - ddvel(:,:,:)=.001 - ELSE if (chem_opt == 108 ) then -!! call soa_vbs_depdriver (ust,t_phy, & -!! moist,p8w,rmol,znt,pbl, & -!! alt,p_phy,chem,rho_phy,dz8w, & -!! h2oaj,h2oai,nu3,ac3,cor3,asulf,ahno3,anh3, & -!! aer_res,ddvel(:,:,numgas+1:num_chem), & -!! num_chem-numgas, & -!! ids,ide, jds,jde, kds,kde, & -!! ims,ime, jms,jme, kms,kme, & -!! its,ite, jts,jte, kts,kte ) -! limit aerosol ddvels to <= 0.5 m/s -! drydep routines occasionally produce unrealistically-large particle -! diameter leading to unrealistically-large sedimentation velocity - ddvel(:,:,numgas+1:num_chem) = min( 0.50, ddvel(:,:,numgas+1:num_chem)) - ELSE - !Set dry deposition velocity to zero when using the - !chemistry tracer mode. - ddvel(:,:,:) = 0. - END IF - idrydep_onoff = 1 - -! -! Compute dry deposition according to NGAC -! - cdt = real(dtstep, kind=kind_phys) - do nv = 1, num_chem - do j = jts, jte - do i = its, ite - factor = 1._kind_phys - exp(-ddvel(i,j,nv)*cdt/dz8w(i,kts,j)) - ddep(i,j,nv) = max(0.0, factor * chem(i,kts,j,nv)) & !ug/m2/s - * (p8w(i,kts,j)-p8w(i,kts+1,j))/g/dtstep - end do - end do - end do - - -! This will be called later from subgrd_transport_driver.F !!!!!!!! -! -! - do 100 j=jts,jte - do 100 i=its,ite - if(p_dust_1.gt.1)dep_vel_o3(i,j)=ddvel(i,j,p_dust_1) - pblst=0. -! -! -!-- start with vertical mixing -! - do k=kts,kte+1 - zzfull(k)=z_at_w(i,k,j)-z_at_w(i,kts,j) - enddo - - if (chem_conv_tr == CTRA_OPT_NONE) then - ekmfull = 0. - else - ekmfull(kts)=0. - do k=kts+1,kte - ekmfull(k)=max(1.e-6,exch_h(i,k,j)) - enddo - ekmfull(kte+1)=0. - end if - -!!$! UNCOMMENT THIS AND FINE TUNE LEVELS TO YOUR DOMAIN IF YOU WANT TO -!!$! FORCE MIXING TO A CERTAIN DEPTH: -!!$! -!!$! --- Mix the emissions up several layers -! - do k=kts,kte - zz(k)=z(i,k,j)-z_at_w(i,kts,j) - enddo -! vertical mixing routine (including deposition) -! need to be careful here with that dumm tracer in spot 1 -! do not need lho,lho2 -! (03-may-2006 rce - calc dryrho_1d and pass it to vertmx) -! -! if(p_o3.gt.1)dep_vel_o3(i,j)=ddvel(i,j,p_o3) - do nv=1,num_chem-0 - do k=kts,kte - pblst(k)=max(epsilc,chem(i,k,j,nv)) - dryrho_1d(k) = 1./alt(i,k,j) - enddo - - !mix_select: SELECT CASE(chem_opt) - !CASE DEFAULT - call vertmx(data,dtstep,pblst,ekmfull,dryrho_1d, & - zzfull,zz,ddvel(i,j,nv),kts,kte) - - !END SELECT mix_select - - do k=kts,kte - chem(i,k,j,nv)=max(epsilc,pblst(k)) - enddo - enddo -100 continue - -END SUBROUTINE dry_dep_driver - -end module dep_dry_mod diff --git a/smoke/dep_simple_mod.F90 b/smoke/dep_simple_mod.F90 deleted file mode 100755 index 37a8189b5..000000000 --- a/smoke/dep_simple_mod.F90 +++ /dev/null @@ -1,766 +0,0 @@ -!>\file dep_simple_mod.F90 -!! This file contains the Wesely dry deposition module. - -module dep_simple_mod - - use rrfs_smoke_data - use rrfs_smoke_config, GOCART_SIMPLE => CHEM_OPT_GOCART, chem_opt=>chem_opt -! use chem_tracers_mod, config_flags => chem_config - -! USE module_data_sorgam - - implicit none - -!-------------------------------------------------- -! .. Default Accessibility .. -!-------------------------------------------------- - PUBLIC - - - CONTAINS - -SUBROUTINE wesely_driver( data, ktau, dtstep, current_month, & - gmt, julday, t_phy,moist, p8w, t8w, raincv, & - p_phy, chem, rho_phy, dz8w, ddvel, aer_res_def, & - aer_res_zcen, ivgtyp, tsk, gsw, vegfra, pbl, & - rmol, ust, znt, xlat, xlong, & - z, z_at_w, snowh, numgas, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - implicit none -!-------------------------------------------------- -! Wesely dry dposition driver -!-------------------------------------------------- - -! USE module_model_constants -! USE module_wrf_control,only:num_moist,num_chem -! USE module_state_description -! USE module_initial_chem_namelists -! USE module_data_sorgam -! USE module_state_description, only: param_first_scalar - type(smoke_data), intent(inout), pointer :: data - INTEGER, INTENT(IN ) :: julday, & - numgas, current_month, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte - INTEGER, INTENT(IN ) :: ktau - REAL(kind_phys), INTENT(IN ) :: dtstep,gmt - -!-------------------------------------------------- -! advected moisture variables -!-------------------------------------------------- - REAL(KIND_PHYS), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), INTENT(IN ) :: & - moist -!-------------------------------------------------- -! advected chemical species -!-------------------------------------------------- - REAL(KIND_PHYS), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), INTENT(INOUT ) :: & - chem -!-------------------------------------------------- -! deposition velocities -!-------------------------------------------------- - REAL(KIND_PHYS), DIMENSION( its:ite, jts:jte, num_chem ), INTENT(INOUT ) :: & - ddvel -!-------------------------------------------------- -! input from met model -!-------------------------------------------------- - REAL(KIND_PHYS), DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: & - t_phy, & - p_phy, & - dz8w, & - z, & - t8w, & - p8w, & - z_at_w, & - rho_phy - INTEGER,DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: & - ivgtyp - REAL(KIND_PHYS), DIMENSION( ims:ime , jms:jme ), INTENT(INOUT ) :: & - tsk, & - gsw, & - vegfra, & - pbl, & - rmol, & - ust, & - xlat, & - xlong, & - raincv, & - znt - REAL(KIND_PHYS), intent(inout) :: aer_res_def(its:ite,jts:jte) - REAL(KIND_PHYS), intent(inout) :: aer_res_zcen(its:ite,jts:jte) - REAL(KIND_PHYS), INTENT(IN) :: snowh(ims:ime,jms:jme) - -!-------------------------------------------------- -! .. Local Scalars -!-------------------------------------------------- - REAL(kind_phys) :: clwchem, dvfog, dvpart, pa, rad, dep_vap - REAL(KIND_PHYS) :: rhchem, ta, ustar, vegfrac, z1, zntt - INTEGER :: i, iland, iprt, iseason, j, jce, jcs, n, nr, ipr,jpr,nvr - LOGICAL :: highnh3, rainflag, vegflag, wetflag -!-------------------------------------------------- -! .. Local Arrays -!-------------------------------------------------- - REAL(KIND_PHYS) :: p(kts:kte) - REAL(KIND_PHYS) :: srfres(numgas) - REAL(KIND_PHYS) :: ddvel0d(numgas) - -!----------------------------------------------------------- -! necessary for aerosols (module dependent) -!----------------------------------------------------------- - real(kind_phys) :: rcx(numgas) - - -!----------------------------------------------------------- -! .. Intrinsic Functions -!----------------------------------------------------------- -! integer :: chem_opt - - INTRINSIC max, min - - data => get_thread_smoke_data() - -! chem_opt = chem_opt - - dep_vap = depo_fact - !print*,'hli simple chem_opt',chem_opt - -! CALL wrf_debug(15,'in dry_dep_wesely') - - if( julday < 90 .or. julday > 270 ) then - iseason = 2 -! CALL wrf_debug(15,'setting iseason to 2') - else - iseason = 1 - endif - - -tile_lat_loop : & - do j = jts,jte -tile_lon_loop : & - do i = its,ite - iprt = 0 - - iland = luse2usgs( ivgtyp(i,j) ) -!-- - - ta = tsk(i,j) - rad = gsw(i,j) - vegfrac = vegfra(i,j) - pa = .01*p_phy(i,kts,j) - clwchem = moist(i,kts,j,p_qc) - ustar = ust(i,j) - zntt = znt(i,j) - z1 = z_at_w(i,kts+1,j) - z_at_w(i,kts,j) -!----------------------------------------------------------- -! Set logical default values -!----------------------------------------------------------- - rainflag = .FALSE. - wetflag = .FALSE. - highnh3 = .FALSE. -! if(p_qr > 1) then -! if(moist(i,kts,j,p_qr) > 1.e-18 .or. raincv(i,j) > 0.) then -! rainflag = .true. -! endif -! endif - rhchem = MIN( 100.,100. * moist(i,kts,j,p_qv) / & - (3.80*exp(17.27*(t_phy(i,kts,j)-273.)/(t_phy(i,kts,j)-36.))/pa)) - rhchem = MAX(5.,RHCHEM) - if (rhchem >= 95.) wetflag = .true. - -!----------------------------------------------------------- -!--- deposition -!----------------------------------------------------------- -! if(snowc(i,j).gt.0.)iseason=4 - CALL rc( data, rcx, ta, rad, rhchem, iland, & - iseason, numgas, wetflag, rainflag, highnh3, & - iprt, moist(i,kts,j,p_qv), p8w(i,kts,j) ) - srfres(1:numgas-2) = rcx(1:numgas-2) - srfres(numgas-1:numgas) = 0. - CALL deppart( data, rmol(i,j), ustar, rhchem, clwchem, iland, dvpart, dvfog ) - ddvel0d(1:numgas) = 0. - aer_res_def(i,j) = 0. - aer_res_zcen(i,j) = 0. - CALL landusevg( data, ddvel0d, ustar, rmol(i,j), zntt, z1, dvpart, iland, & - numgas, srfres, aer_res_def(i,j), aer_res_zcen(i,j), p_sulf ) - -!----------------------------------------------------------- -!wig: CBMZ does not have HO and HO2 last so need to copy all species -! ddvel(i,j,1:numgas-2)=ddvel0d(1:numgas-2) -!----------------------------------------------------------- - ddvel(i,j,1:numgas) = ddvel0d(1:numgas) - end do tile_lon_loop - end do tile_lat_loop - -!----------------------------------------------------------- -! For the additional CBMZ species, assign similar RADM counter parts for -! now. Short lived species get a zero velocity since dry dep should be -! unimportant. **ALSO**, treat p_sulf as h2so4 vapor, not aerosol sulfate -!----------------------------------------------------------- -! - -!----------------------------------------------------------- -! For gocartsimple : need msa. On the other hand sulf comes from aerosol routine -!----------------------------------------------------------- - if (chem_opt == GOCART_SIMPLE ) then - do j=jts,jte - do i=its,ite - ddvel(i,j,p_msa) = ddvel(i,j,p_sulf) - ddvel(i,j,p_sulf) = 0. - ddvel(i,j,p_dms) = 0. - end do - end do - end if - -END SUBROUTINE wesely_driver - - SUBROUTINE rc( data, rcx, t, rad, rh, iland, & - iseason, numgas, wetflag, rainflag, highnh3, & - iprt, spec_hum, p_srf ) -!---------------------------------------------------------------------- -! THIS SUBROUTINE CALCULATES SURFACE RESISTENCES ACCORDING -! TO THE MODEL OF -! M. L. WESELY, -! ATMOSPHERIC ENVIRONMENT 23 (1989), 1293-1304 -! WITH SOME ADDITIONS ACCORDING TO -! J. W. ERISMAN, A. VAN PUL, AND P. WYERS, -! ATMOSPHERIC ENVIRONMENT 28 (1994), 2595-2607 -! WRITTEN BY WINFRIED SEIDL, APRIL 1997 -! MODYFIED BY WINFRIED SEIDL, MARCH 2000 -! FOR MM5 VERSION 3 -!---------------------------------------------------------------------- - -! USE module_state_description -! USE module_initial_chem_namelists - implicit none - type(smoke_data), pointer, intent(inout) :: data -!---------------------------------------------------------------------- -! ... dummy arguments -!---------------------------------------------------------------------- - INTEGER, intent(in) :: iland, iseason, numgas - INTEGER, intent(in) :: iprt - REAL(KIND_PHYS), intent(in) :: rad, rh - REAL(KIND_PHYS), intent(in) :: t ! surface temp (K) - REAL(KIND_PHYS), intent(in) :: p_srf ! surface pressure (Pa) - REAL(KIND_PHYS), intent(in) :: spec_hum ! surface specific humidity (kg/kg) - real(kind_phys), intent(out) :: rcx(numgas) - LOGICAL, intent(in) :: highnh3, rainflag, wetflag - -!---------------------------------------------------------------------- -! .. Local Scalars .. -!---------------------------------------------------------------------- - REAL(KIND_PHYS), parameter :: t0 = 298. - REAL(KIND_PHYS), parameter :: tmelt = 273.16 - INTEGER :: lt, n - INTEGER :: chem_opt - REAL(KIND_PHYS) :: rclx, rdc, resice, rgsx, rluo1, rluo2 - REAL(KIND_PHYS) :: rlux, rmx, rs, rsmx, rdtheta, z, wrk - REAL(KIND_PHYS) :: qs, es, ws, dewm, dv_pan, drat - REAL(KIND_PHYS) :: crs, tc - REAL(KIND_PHYS) :: rs_pan, tc_pan - LOGICAL :: has_dew -!---------------------------------------------------------------------- -! .. Local Arrays .. -!---------------------------------------------------------------------- - REAL(KIND_PHYS) :: hstary(numgas) - -!---------------------------------------------------------------------- -! .. Intrinsic Functions .. -!---------------------------------------------------------------------- - INTRINSIC exp - - chem_opt = chem_opt - - rcx(1:numgas) = 1. - - tc = t - 273.15 - rdtheta = 0. - - z = 200./(rad+0.1) - -!!! HARDWIRE VALUES FOR TESTING -! z=0.4727409 -! tc=22.76083 -! t=tc+273.15 -! rad = 412.8426 -! rainflag=.false. -! wetflag=.false. - - IF ( tc<=0. .OR. tc>=40. ) THEN - rs = 9999. - ELSE - rs = data%ri(iland,iseason)*(1+z*z)*(400./(tc*(40.-tc))) - END IF - rdc = 100.*(1. + 1000./(rad + 10.))/(1. + 1000.*rdtheta) - rluo1 = 1./(1./3000. + 3./data%rlu(iland,iseason)) - rluo2 = 1./(1./1000. + 3./data%rlu(iland,iseason)) - resice = 1000.*exp( -(tc + 4.) ) - wrk = (t0 - t)/(t0*t) - - - DO n = 1, numgas - IF( data%hstar(n) /= 0. ) then - hstary(n) = data%hstar(n)*exp( data%dhr(n)*wrk ) -!---------------------------------------------------------------------- -! SPECIAL TREATMENT FOR HNO3, HNO4, H2O2, PAA -!---------------------------------------------------------------------- - rmx = 1./(hstary(n)/3000. + 100.*data%f0(n)) - rsmx = rs*data%dratio(n) + rmx - rclx = 1./(1.e-5*hstary(n)/data%rcls(iland,iseason) & - + data%f0(n)/data%rclo(iland,iseason)) + resice - rgsx = 1./(1.e-5*hstary(n)/data%rgss(iland,iseason) & - + data%f0(n)/data%rgso(iland,iseason)) + resice - rlux = data%rlu(iland,iseason)/(1.e-5*hstary(n) + data%f0(n)) + resice - IF( wetflag ) THEN - rlux = 1./(1./(3.*data%rlu(iland,iseason)) + 1.e-7*hstary(n) + data%f0(n)/rluo1) - END IF - IF( rainflag ) THEN - rlux = 1./(1./(3.*data%rlu(iland,iseason)) + 1.e-7*hstary(n) + data%f0(n)/rluo2) - END IF - rcx(n) = 1./(1./rsmx + 1./rlux + 1./(rdc + rclx) + 1./(data%rac(iland,iseason) + rgsx)) - rcx(n) = max( 1.,rcx(n) ) - end IF - END DO - -!-------------------------------------------------- -! SPECIAL TREATMENT FOR OZONE -!-------------------------------------------------- -! SPECIAL TREATMENT FOR SO2 (Wesely) -! HSTARY(P_SO2)=DATA%HSTAR(P_SO2)*EXP(DATA%DHR(P_SO2)*(1./T-1./298.)) -! RMX=1./(HSTARY(P_SO2)/3000.+100.*DATA%F0(P_SO2)) -! RSMX=RS*DATA%DRATIO(P_SO2)+RMX -! RLUX=DATA%RLU(ILAND,ISEASON)/(1.E-5*HSTARY(P_SO2)+DATA%F0(P_SO2)) -! & +RESICE -! RCLX=DATA%RCLS(ILAND,ISEASON)+RESICE -! RGSX=DATA%RGSS(ILAND,ISEASON)+RESICE -! IF ((wetflag).OR.(RAINFLAG)) THEN -! IF (ILAND.EQ.1) THEN -! RLUX=50. -! ELSE -! RLUX=100. -! END IF -! END IF -! RCX(P_SO2)=1./(1./RSMX+1./RLUX+1./(RDC+RCLX) -! & +1./(DATA%RAC(ILAND,ISEASON)+RGSX)) -! IF (RCX(P_SO2).LT.1.) RCX(P_SO2)=1. - -!-------------------------------------------------- -! SO2 according to Erisman et al. 1994 -! R_STOM -!-------------------------------------------------- -is_so2 : & - if( p_so2 > 1 ) then - rsmx = rs*data%dratio(p_so2) -!-------------------------------------------------- -! R_EXT -!-------------------------------------------------- - IF (tc> -1. ) THEN - IF (rh<81.3) THEN - rlux = 25000.*exp(-0.0693*rh) - ELSE - rlux = 0.58E12*exp(-0.278*rh) - END IF - END IF - IF (((wetflag) .OR. (rainflag)) .AND. (tc> -1. )) THEN - rlux = 1. - END IF - IF ((tc>= -5. ) .AND. (tc<= -1. )) THEN - rlux = 200. - END IF - IF (tc< -5. ) THEN - rlux = 500. - END IF -!-------------------------------------------------- -! INSTEAD OF R_INC R_CL and R_DC of Wesely are used -!-------------------------------------------------- - rclx = data%rcls(iland,iseason) -!-------------------------------------------------- -! DRY SURFACE -!-------------------------------------------------- - rgsx = 1000. -!-------------------------------------------------- -! WET SURFACE -!-------------------------------------------------- - IF ((wetflag) .OR. (rainflag)) THEN - IF (highnh3) THEN - rgsx = 0. - ELSE - rgsx = 500. - END IF - END IF -!-------------------------------------------------- -! WATER -!-------------------------------------------------- - IF (iland==iswater_temp) THEN - rgsx = 0. - END IF -!-------------------------------------------------- -! SNOW -!-------------------------------------------------- - IF( iseason==4 .OR. iland==isice_temp ) THEN - IF( tc > 2. ) THEN - rgsx = 0. - else IF ( tc >= -1. .AND. tc <= 2. ) THEN - rgsx = 70.*(2. - tc) - else IF ( tc < -1. ) THEN - rgsx = 500. - END IF - END IF -!-------------------------------------------------- -! TOTAL SURFACE RESISTENCE -!-------------------------------------------------- - IF ((iseason/=4) .AND. (data%ixxxlu(iland)/=1) .AND. (iland/=iswater_temp) .AND. & - (iland/=isice_temp)) THEN - rcx(p_so2) = 1./(1./rsmx+1./rlux+1./(rclx+rdc+rgsx)) - ELSE - rcx(p_so2) = rgsx - END IF - rcx(p_so2) = max( 1.,rcx(p_so2) ) - end if is_so2 -!-------------------------------------------------- -! NH3 according to Erisman et al. 1994 -! R_STOM -!-------------------------------------------------- - END SUBROUTINE rc - - SUBROUTINE deppart( data, rmol, ustar, rh, clw, iland, & - dvpart, dvfog ) -!-------------------------------------------------- -! THIS SUBROUTINE CALCULATES SURFACE DEPOSITION VELOCITIES -! FOR FINE AEROSOL PARTICLES ACCORDING TO THE MODEL OF -! J. W. ERISMAN, A. VAN PUL, AND P. WYERS, -! ATMOSPHERIC ENVIRONMENT 28 (1994), 2595-2607 -! WRITTEN BY WINFRIED SEIDL, APRIL 1997 -! MODIFIED BY WINFRIED SEIDL, MARCH 2000 -! FOR MM5 VERSION 3 -!-------------------------------------------------- - implicit none - type(smoke_data), pointer, intent(inout) :: data - -!-------------------------------------------------- -! .. Scalar Arguments .. -!-------------------------------------------------- - INTEGER, intent(in) :: iland - REAL(KIND_PHYS), intent(in) :: clw, rh, rmol, ustar - REAL(KIND_PHYS), intent(out) :: dvfog, dvpart - -!-------------------------------------------------- -! .. Intrinsic Functions .. -!-------------------------------------------------- - INTRINSIC exp - - dvpart = ustar/data%kpart(iland) - IF (rmol<0.) THEN -!-------------------------------------------------- -! UNSTABLE LAYERING CORRECTION -!-------------------------------------------------- - dvpart = dvpart*(1.+(-300.*rmol)**0.66667) - END IF - IF (rh>80.) THEN -!-------------------------------------------------- -! HIGH RELATIVE HUMIDITY CORRECTION -! ACCORDING TO J. W. ERISMAN ET AL. -! ATMOSPHERIC ENVIRONMENT 31 (1997), 321-332 -!-------------------------------------------------- - dvpart = dvpart*(1.+0.37*exp((rh-80.)/20.)) - END IF - -!-------------------------------------------------- -! SEDIMENTATION VELOCITY OF FOG WATER ACCORDING TO -! R. FORKEL, W. SEIDL, R. DLUGI AND E. DEIGELE -! J. GEOPHYS. RES. 95D (1990), 18501-18515 -!-------------------------------------------------- - dvfog = 0.06*clw - IF (data%ixxxlu(iland)==5) THEN -!-------------------------------------------------- -! TURBULENT DEPOSITION OF FOG WATER IN CONIFEROUS FOREST ACCORDI -! A. T. VERMEULEN ET AL. -! ATMOSPHERIC ENVIRONMENT 31 (1997), 375-386 -!-------------------------------------------------- - dvfog = dvfog + 0.195*ustar*ustar - END IF - - END SUBROUTINE deppart - - SUBROUTINE landusevg( data, vgs, ustar, rmol, z0, zz, & - dvparx, iland, numgas, srfres, aer_res_def, & - aer_res_zcen, p_sulf ) -!-------------------------------------------------- -! This subroutine calculates the species specific deposition velocit -! as a function of the local meteorology and land use. The depositi -! Velocity is also landuse specific. -! Reference: Hsieh, C.M., Wesely, M.L. and Walcek, C.J. (1986) -! A Dry Deposition Module for Regional Acid Deposition -! EPA report under agreement DW89930060-01 -! Revised version by Darrell Winner (January 1991) -! Environmental Engineering Science 138-78 -! California Institute of Technology -! Pasadena, CA 91125 -! Modified by Winfried Seidl (August 1997) -! Fraunhofer-Institut fuer Atmosphaerische Umweltforschung -! Garmisch-Partenkirchen, D-82467 -! for use of Wesely and Erisman surface resistances -! Inputs: -! Ustar : The grid average friction velocity (m/s) -! Rmol : Reciprocal of the Monin-Obukhov length (1/m) -! Z0 : Surface roughness height for the grid square (m) -! SrfRes : Array of landuse/atmospheric/species resistances (s/m) -! Slist : Array of chemical species codes -! Dvparx : Array of surface deposition velocity of fine aerosol p -! Outputs: -! Vgs : Array of species and landuse specific deposition -! velocities (m/s) -! Vg : Cell-average deposition velocity by species (m/s) -! Variables used: -! SCPR23 : (Schmidt #/Prandtl #)**(2/3) Diffusion correction fac -! Zr : Reference Height (m) -! Iatmo : Parameter specifying the stabilty class (Function of -! Z0 : Surface roughness height (m) -! karman : Von Karman constant (from module_model_constants) -!-------------------------------------------------- - -! USE module_model_constants, only: karman - implicit none - - type(smoke_data), pointer, intent(inout) :: data - -!-------------------------------------------------- -! .. Scalar Arguments .. -!-------------------------------------------------- - INTEGER, intent(in) :: iland, numgas, p_sulf - REAL(KIND_PHYS), intent(in) :: dvparx, ustar, z0, zz - REAL(KIND_PHYS), intent(inout) :: rmol - REAL(KIND_PHYS), intent(inout) :: aer_res_def - REAL(KIND_PHYS), intent(inout) :: aer_res_zcen -!-------------------------------------------------- -! .. Array Arguments .. -!-------------------------------------------------- - REAL(KIND_PHYS), intent(in) :: srfres(numgas) - REAL(KIND_PHYS), intent(out) :: vgs(numgas) - -!-------------------------------------------------- -! .. Local Scalars .. -!-------------------------------------------------- - INTEGER :: jspec - REAL(KIND_PHYS) :: vgp, vgpart, zr - REAL(KIND_PHYS) :: rmol_tmp -!-------------------------------------------------- -! .. Local Arrays .. -!-------------------------------------------------- - REAL(KIND_PHYS) :: vgspec(numgas) - -!-------------------------------------------------- -! Calculate aerodynamic resistance for reference -! height = layer center -!-------------------------------------------------- - zr = zz*.5 - rmol_tmp = rmol - CALL depvel( data, numgas, rmol_tmp, zr, z0, ustar, & - vgspec, vgpart, aer_res_zcen ) -!-------------------------------------------------- -! Set the reference height (2.0 m) -!-------------------------------------------------- -! zr = 10.0 - zr = 2.0 - -!-------------------------------------------------- -! CALCULATE THE DEPOSITION VELOCITY without any surface -! resistance term, i.e. 1 / (ra + rb) -!-------------------------------------------------- - CALL depvel( data, numgas, rmol, zr, z0, ustar, & - vgspec, vgpart, aer_res_def ) - -!-------------------------------------------------- -! Calculate the deposition velocity for each species -! and grid cell by looping through all the possibile combinations -! of the two -!-------------------------------------------------- - vgp = 1.0/((1.0/vgpart)+(1.0/dvparx)) -!-------------------------------------------------- -! Loop through the various species -!-------------------------------------------------- - DO jspec = 1, numgas -!-------------------------------------------------- -! Add in the surface resistance term, rc (SrfRes) -!-------------------------------------------------- - vgs(jspec) = 1.0/(1.0/vgspec(jspec) + srfres(jspec)) - END DO - vgs(p_sulf) = vgp - - CALL cellvg( data, vgs, ustar, zz, zr, rmol, numgas ) - - END SUBROUTINE landusevg - - SUBROUTINE cellvg( data, vgtemp, ustar, dz, zr, rmol, nspec ) -!-------------------------------------------------- -! THIS PROGRAM HAS BEEN DESIGNED TO CALCULATE THE CELL AVERAGE -! DEPOSITION VELOCITY GIVEN THE VALUE OF VG AT SOME REFERENCE -! HEIGHT ZR WHICH IS MUCH SMALLER THAN THE CELL HEIGHT DZ. -! PROGRAM WRITTEN BY GREGORY J.MCRAE (NOVEMBER 1977) -! Modified by Darrell A. Winner (February 1991) -!.....PROGRAM VARIABLES... -! VgTemp - DEPOSITION VELOCITY AT THE REFERENCE HEIGHT -! USTAR - FRICTION VELOCITY -! RMOL - RECIPROCAL OF THE MONIN-OBUKHOV LENGTH -! ZR - REFERENCE HEIGHT -! DZ - CELL HEIGHT -! CELLVG - CELL AVERAGE DEPOSITION VELOCITY -! VK - VON KARMAN CONSTANT -!-------------------------------------------------- - -! USE module_model_constants, only: karman - implicit none - type(smoke_data), pointer, intent(inout) :: data - -!-------------------------------------------------- -! .. Scalar Arguments .. -!-------------------------------------------------- - INTEGER, intent(in) :: nspec - REAL(KIND_PHYS), intent(in) :: dz, rmol, ustar, zr -!-------------------------------------------------- -! .. Array Arguments .. -!-------------------------------------------------- - REAL(KIND_PHYS), intent(out) :: vgtemp(nspec) -!-------------------------------------------------- -! .. Local Scalars .. -!-------------------------------------------------- - INTEGER :: nss - REAL(KIND_PHYS) :: a, fac, pdz, pzr, vk -!-------------------------------------------------- -! .. Intrinsic Functions .. -!-------------------------------------------------- - INTRINSIC alog, sqrt - -!-------------------------------------------------- -! Set the von Karman constant -!-------------------------------------------------- - vk = karman - -!-------------------------------------------------- -! DETERMINE THE STABILITY BASED ON THE CONDITIONS -! 1/L < 0 UNSTABLE -! 1/L = 0 NEUTRAL -! 1/L > 0 STABLE -!-------------------------------------------------- - DO nss = 1, nspec - IF (rmol < 0.) THEN - pdz = sqrt(1.0 - 9.0*dz*rmol) - pzr = sqrt(1.0 - 9.0*zr*rmol) - fac = ((pdz - 1.0)/(pzr - 1.0))*((pzr + 1.0)/(pdz + 1.0)) - a = 0.74*dz*alog(fac) + (0.164/rmol)*(pdz-pzr) - ELSE IF (rmol == 0.) THEN - a = 0.74*(dz*alog(dz/zr) - dz + zr) - ELSE - a = 0.74*(dz*alog(dz/zr) - dz + zr) + (2.35*rmol)*(dz - zr)**2 - END IF -!-------------------------------------------------- -! CALCULATE THE DEPOSITION VELOCITIY -!-------------------------------------------------- - vgtemp(nss) = vgtemp(nss)/(1.0 + vgtemp(nss)*a/(vk*ustar*(dz - zr))) - END DO - - END SUBROUTINE cellvg - - SUBROUTINE depvel( data, numgas, rmol, zr, z0, ustar, & - depv, vgpart, aer_res ) -!-------------------------------------------------- -! THIS FUNCTION HAS BEEN DESIGNED TO EVALUATE AN UPPER LIMIT -! FOR THE POLLUTANT DEPOSITION VELOCITY AS A FUNCTION OF THE -! SURFACE ROUGHNESS AND METEOROLOGICAL CONDITIONS. -! PROGRAM WRITTEN BY GREGORY J.MCRAE (NOVEMBER 1977) -! Modified by Darrell A. Winner (Feb. 1991) -! by Winfried Seidl (Aug. 1997) -!.....PROGRAM VARIABLES... -! RMOL - RECIPROCAL OF THE MONIN-OBUKHOV LENGTH -! ZR - REFERENCE HEIGHT -! Z0 - SURFACE ROUGHNESS HEIGHT -! SCPR23 - (Schmidt #/Prandtl #)**(2/3) Diffusion correction fact -! UBAR - ABSOLUTE VALUE OF SURFACE WIND SPEED -! DEPVEL - POLLUTANT DEPOSITION VELOCITY -! Vk - VON KARMAN CONSTANT -! USTAR - FRICTION VELOCITY U* -! POLINT - POLLUTANT INTEGRAL -! AER_RES - AERODYNAMIC RESISTANCE -!.....REFERENCES... -! MCRAE, G.J. ET AL. (1983) MATHEMATICAL MODELING OF PHOTOCHEMICAL -! AIR POLLUTION, ENVIRONMENTAL QUALITY LABORATORY REPORT 18, -! CALIFORNIA INSTITUTE OF TECHNOLOGY, PASADENA, CALIFORNIA. -!.....RESTRICTIONS... -! 1. THE MODEL EDDY DIFFUSIVITIES ARE BASED ON MONIN-OBUKHOV -! SIMILARITY THEORY AND SO ARE ONLY APPLICABLE IN THE -! SURFACE LAYER, A HEIGHT OF O(30M). -! 2. ALL INPUT UNITS MUST BE CONSISTENT -! 3. THE PHI FUNCTIONS USED TO CALCULATE THE FRICTION -! VELOCITY U* AND THE POLLUTANT INTEGRALS ARE BASED -! ON THE WORK OF BUSINGER ET AL.(1971). -! 4. THE MOMENTUM AND POLLUTANT DIFFUSIVITIES ARE NOT -! THE SAME FOR THE CASES L<0 AND L>0. -!-------------------------------------------------- - -! USE module_model_constants, only: karman - implicit none - type(smoke_data), pointer, intent(inout) :: data - -!-------------------------------------------------- -! .. Scalar Arguments .. -!-------------------------------------------------- - INTEGER, intent(in) :: numgas - REAL(KIND_PHYS), intent(in) :: ustar, z0, zr - REAL(KIND_PHYS), intent(out) :: vgpart, aer_res - REAL(KIND_PHYS), intent(inout) :: rmol -!-------------------------------------------------- -! .. Array Arguments .. -!-------------------------------------------------- - REAL(KIND_PHYS), intent(out) :: depv(numgas) -!-------------------------------------------------- -! .. Local Scalars .. -!-------------------------------------------------- - INTEGER :: l - REAL(KIND_PHYS) :: ao, ar, polint, vk -!-------------------------------------------------- -! .. Intrinsic Functions .. -!-------------------------------------------------- - INTRINSIC alog -!-------------------------------------------------- -! Set the von Karman constant -!-------------------------------------------------- - vk = karman - -!-------------------------------------------------- -! Calculate the diffusion correction factor -! SCPR23 is calculated as (Sc/Pr)**(2/3) using Sc= 1.15 and Pr= 1.0 -! DATA%SCPR23 = 1.10 -!-------------------------------------------------- -! DETERMINE THE STABILITY BASED ON THE CONDITIONS -! 1/L < 0 UNSTABLE -! 1/L = 0 NEUTRAL -! 1/L > 0 STABLE -!-------------------------------------------------- - - if(abs(rmol) < 1.E-6 ) rmol = 0. - - IF (rmol<0) THEN - ar = ((1.0-9.0*zr*rmol)**(0.25)+0.001)**2 - ao = ((1.0-9.0*z0*rmol)**(0.25)+0.001)**2 - polint = 0.74*(alog((ar-1.0)/(ar+1.0))-alog((ao-1.0)/(ao+1.0))) - ELSE IF (rmol==0.) THEN - polint = 0.74*alog(zr/z0) - ELSE - polint = 0.74*alog(zr/z0) + 4.7*rmol*(zr-z0) - END IF - -!-------------------------------------------------- -! CALCULATE THE Maximum DEPOSITION VELOCITY -!-------------------------------------------------- - DO l = 1, numgas - depv(l) = ustar*vk/(2.0*data%scpr23(l)+polint) - END DO - vgpart = ustar*vk/polint - aer_res = polint/(karman*max(ustar,1.0e-4)) - - END SUBROUTINE depvel - - ! NOTE: dep_init is now in rrfs_smoke_data - -end module dep_simple_mod diff --git a/smoke/dep_vertmx_mod.F90 b/smoke/dep_vertmx_mod.F90 deleted file mode 100755 index d56b1b87e..000000000 --- a/smoke/dep_vertmx_mod.F90 +++ /dev/null @@ -1,212 +0,0 @@ -!>\file dep_vertmx_mod.F90 -!! This file calculates change in time of phi due to vertical mixing and dry deposition. - -MODULE dep_vertmx_mod - use rrfs_smoke_data - use machine , only : kind_phys - -CONTAINS - -!----------------------------------------------------------------------- - SUBROUTINE vertmx( data, dt, phi, kt_turb, dryrho, & - zsigma, zsigma_half, vd, kts, ktem1 ) -! !! purpose - calculate change in time of phi due to vertical mixing -! !! and dry deposition (for 1 species, 1 vertical column, 1 time step) -! !! Mariusz Pagowski, March 2001 -! !! conventions used: -! !! input is lower case -! !! output is upper case -! -! !! modifications by R Easter, May 2006 -! !! added dryrho so this routine conserves column mass burde -! !! when dry deposition velocity is zero -! !! changed "kte" to "ktem1" for consistency with the kte in WRF -! -! ARGUMENTS -! -! dt = time step (s) -! phi = initial/final (at input/output) species mixing ratios at "T" points -! kt_turb = turbulent exchange coefficients (m^2/s) at "W" points -! dryrho = dry air density (kg/m^3) at "T" points -! zsigma = heights (m) at "W" points -! zsigma_half = heights (m) at "T" points -! vd = dry deposition velocity (m/s) -! kts, ktem1 = vertical indices of bottom and top "T" points -! - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - -! .. Scalar Arguments .. - INTEGER, INTENT(IN) :: kts,ktem1 - REAL(KIND=KIND_PHYS), INTENT(IN) :: dt, vd -! .. -! .. Array Arguments .. - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1+1) :: kt_turb, zsigma - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1) :: dryrho, zsigma_half - REAL(KIND=KIND_PHYS), INTENT(INOUT), DIMENSION (kts:ktem1) :: phi -! .. -! .. Local Scalars .. - INTEGER :: k -! .. -! .. Local Arrays .. - REAL(KIND=KIND_PHYS), DIMENSION (kts+1:ktem1) :: a_coeff - REAL(KIND=KIND_PHYS), DIMENSION (kts:ktem1) :: b_coeff, lhs1, lhs2, lhs3, rhs -! .. -! .. External Subroutines .. -! EXTERNAL coeffs, rlhside, tridiag -! .. - CALL coeffs( data, kts, ktem1, dryrho, zsigma, zsigma_half, a_coeff, b_coeff ) - - CALL rlhside( data, kts, ktem1, kt_turb, dryrho, a_coeff, b_coeff, & - phi, dt, vd, rhs, lhs1, lhs2, lhs3 ) - - CALL tridiag( data, kts, ktem1, lhs1, lhs2, lhs3, rhs ) - - DO k = kts,ktem1 - phi(k) = rhs(k) - END DO - - END SUBROUTINE vertmx - - -!----------------------------------------------------------------------- - SUBROUTINE rlhside( data, kts, ktem1, k_turb, dryrho, a_coeff, b_coeff, & - phi, dt, vd, rhs, lhs1, lhs2, lhs3 ) - !! to calculate right and left hand sides in diffusion equation - !! for the tridiagonal solver - !! Mariusz Pagowski, March 2001 - !! conventions used: - !! input is lower case - !! output is upper case - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - -! .. Scalar Arguments .. - INTEGER, INTENT(IN) :: kts,ktem1 - REAL(KIND=KIND_PHYS), INTENT(IN) :: dt, vd -! .. -! .. Array Arguments .. - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1+1) :: k_turb - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts+1:ktem1) :: a_coeff - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1) :: b_coeff, dryrho - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1) :: phi - REAL(KIND=KIND_PHYS), INTENT(OUT), DIMENSION (kts:ktem1) :: lhs1, lhs2, lhs3, rhs -! .. -! .. Local Scalars .. - !REAL(KIND_PHYS) :: a1, a2, alfa_explicit = .25, beta_implicit = .75 - REAL(KIND_PHYS) :: a1, a2, alfa_explicit = .0, beta_implicit = 1. - INTEGER :: i - -! .. - i = kts - a2 = a_coeff(i+1)*k_turb(i+1) - rhs(i) = (1./(dt*b_coeff(i)) - alfa_explicit*(vd*dryrho(i)+a2))*phi(i) + & - alfa_explicit*(a2*phi(i+1)) - lhs1(i) = 0. - lhs2(i) = 1./(dt*b_coeff(i)) + beta_implicit*(vd*dryrho(i)+a2) - lhs3(i) = -beta_implicit*a2 - - DO i = kts+1, ktem1-1 - a1 = a_coeff(i)*k_turb(i) - a2 = a_coeff(i+1)*k_turb(i+1) - - rhs(i) = (1./(dt*b_coeff(i)) - alfa_explicit*(a1+a2))*phi(i) + & - alfa_explicit*(a1*phi(i-1) + a2*phi(i+1)) - - lhs1(i) = -beta_implicit*a1 - lhs2(i) = 1./(dt*b_coeff(i)) + beta_implicit*(a1+a2) - lhs3(i) = -beta_implicit*a2 - END DO - - i = ktem1 - a1 = a_coeff(i)*k_turb(i) - rhs(i) = (1./(dt*b_coeff(i)) - alfa_explicit*(a1 ))*phi(i) + & - alfa_explicit*(a1*phi(i-1)) - lhs1(i) = -beta_implicit*a1 - lhs2(i) = 1./(dt*b_coeff(i)) + beta_implicit*(a1 ) - lhs3(i) = 0. - - END SUBROUTINE rlhside - - -!----------------------------------------------------------------------- - SUBROUTINE tridiag( data, kts, ktem1, a, b, c, f ) - !! to solve system of linear eqs on tridiagonal matrix n times n - !! after Peaceman and Rachford, 1955 - !! a,b,c,F - are vectors of order n - !! a,b,c - are coefficients on the LHS - !! F - is initially RHS on the output becomes a solution vector - !! Mariusz Pagowski, March 2001 - !! conventions used: - !! input is lower case - !! output is upper case - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - -! .. Scalar Arguments .. - INTEGER, INTENT(IN) :: kts,ktem1 -! .. -! .. Array Arguments .. - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1) :: a, b, c - REAL(KIND=KIND_PHYS), INTENT(INOUT), DIMENSION (kts:ktem1) :: f -! .. -! .. Local Scalars .. - REAL(KIND_PHYS) :: p - INTEGER :: i -! .. -! .. Local Arrays .. - REAL(KIND=KIND_PHYS), DIMENSION (kts:ktem1) :: q -! .. - q(kts) = -c(kts)/b(kts) - f(kts) = f(kts)/b(kts) - - DO i = kts+1, ktem1 - p = 1./(b(i)+a(i)*q(i-1)) - q(i) = -c(i)*p - f(i) = (f(i)-a(i)*f(i-1))*p - END DO - - DO i = ktem1 - 1, kts, -1 - f(i) = f(i) + q(i)*f(i+1) - END DO - - END SUBROUTINE tridiag - - -!----------------------------------------------------------------------- - SUBROUTINE coeffs( data, kts, ktem1, dryrho, & - z_sigma, z_sigma_half, a_coeff, b_coeff ) -! !! to calculate coefficients in diffusion equation -! !! Mariusz Pagowski, March 2001 -! !! conventions used: -! !! input is lower case -! !! output is upper case -! .. Scalar Arguments .. - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - - INTEGER, INTENT(IN) :: kts,ktem1 -! .. -! .. Array Arguments .. - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1+1) :: z_sigma - REAL(KIND=KIND_PHYS), INTENT(IN), DIMENSION (kts:ktem1) :: z_sigma_half, dryrho - REAL(KIND=KIND_PHYS), INTENT(OUT), DIMENSION (kts+1:ktem1) :: a_coeff - REAL(KIND=KIND_PHYS), INTENT(OUT), DIMENSION (kts:ktem1) :: b_coeff -! .. -! .. Local Scalars .. - INTEGER :: i - REAL(KIND=KIND_PHYS) :: dryrho_at_w -! .. - DO i = kts, ktem1 - b_coeff(i) = 1./(dryrho(i)*(z_sigma(i+1)-z_sigma(i))) - END DO - - DO i = kts+1, ktem1 - dryrho_at_w = 0.5*(dryrho(i)+dryrho(i-1)) - a_coeff(i) = dryrho_at_w/(z_sigma_half(i)-z_sigma_half(i-1)) - END DO - - END SUBROUTINE coeffs - -!----------------------------------------------------------------------- -END MODULE dep_vertmx_mod diff --git a/smoke/dep_wet_ls_mod.F90 b/smoke/dep_wet_ls_mod.F90 deleted file mode 100755 index 3a7a186ea..000000000 --- a/smoke/dep_wet_ls_mod.F90 +++ /dev/null @@ -1,562 +0,0 @@ -!>\file dep_wet_ls_mod.F90 -!! This file contains aerosol wet deposition module. - -module dep_wet_ls_mod - use rrfs_smoke_data - use machine , only : kind_phys - use rrfs_smoke_config -! use chem_tracers_mod -! use chem_rc_mod -! use chem_tracers_mod -! use chem_const_mod, only : grav => grvity - - implicit none - - ! -- large scale wet deposition scavenging factors - - private - - public :: dep_wet_ls_init - public :: wetdep_ls - public :: WetRemovalGOCART - -contains - -! subroutine dep_wet_ls_init(config, rc) - subroutine dep_wet_ls_init(data) - implicit none - type(smoke_data), intent(inout) :: data - - ! -- I/O arguments -! type(chem_config_type), intent(in) :: config -! integer, intent(out) :: rc - - ! -- local variables - integer :: ios, n - - ! -- begin - !rc = CHEM_RC_SUCCESS - - ! -- set aerosol wet scavenging coefficients - if (associated(data%alpha)) then - deallocate(data%alpha, stat=ios) - !if (chem_rc_test((ios /= 0), msg="Failed to deallocate memory", & - ! file=__FILE__, line=__LINE__, rc=rc)) return - end if - - allocate(data%alpha(num_chem), stat=ios) - !if (chem_rc_test((ios /= 0), msg="Failed to allocate memory", & - ! file=__FILE__, line=__LINE__, rc=rc)) return - - data%alpha = 0. - - select case (wetdep_ls_opt) - case (WDLS_OPT_GSD) - - select case (chem_opt) - case (CHEM_OPT_GOCART) - data%alpha = 1.0 - end select - - case (WDLS_OPT_NGAC) - - select case (chem_opt) - case (CHEM_OPT_GOCART) - data%alpha(p_so2 ) = 0. - data%alpha(p_sulf ) = 1.5 - data%alpha(p_dms ) = 0. - data%alpha(p_msa ) = 0. - data%alpha(p_p25 ) = 1. - data%alpha(p_bc1 ) = 0.7 - data%alpha(p_bc2 ) = 0.7 - data%alpha(p_oc1 ) = 1. - data%alpha(p_oc2 ) = 1. - data%alpha(p_dust_1) = 1. - data%alpha(p_dust_2) = 1. - data%alpha(p_dust_3) = 1. - data%alpha(p_dust_4) = 1. - data%alpha(p_dust_5) = 1. - data%alpha(p_seas_1) = 1. - data%alpha(p_seas_2) = 1. - data%alpha(p_seas_3) = 1. - data%alpha(p_seas_4) = 1. - data%alpha(p_seas_5) = 1. - data%alpha(p_p10 ) = 1. - case default - ! -- NGAC large scale wet deposition only works with GOCART - end select - - case default - end select - - ! -- replace first default wet scavenging coefficients with input values if - ! available - if (any(wetdep_ls_alpha > 0._kind_phys)) then - n = min(size(data%alpha), size(wetdep_ls_alpha)) - data%alpha(1:n) = real(wetdep_ls_alpha(1:n)) - end if - - end subroutine dep_wet_ls_init - - - - subroutine wetdep_ls(data,dt,var,rain,moist,rho,var_rmv, & - num_moist,num_chem,p_qc,p_qi,dz8w,vvel, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - - INTEGER, INTENT(IN ) :: num_chem,num_moist,p_qc, p_qi, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte - real(kind_phys), INTENT(IN ) :: dt - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & - INTENT(IN ) :: moist - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & - INTENT(IN ) :: rho,dz8w,vvel - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ,1:num_chem), & - INTENT(INOUT) :: var - REAL(kind_phys), DIMENSION( ims:ime, jms:jme ), & - INTENT(IN ) :: rain - REAL(kind_phys), DIMENSION( ims:ime , jms:jme,num_chem ), & - INTENT(INOUT ) :: var_rmv - REAL(kind_phys), DIMENSION( its:ite , jts:jte ) :: var_sum - REAL(kind_phys), DIMENSION( its:ite , kts:kte, jts:jte ) :: var_rmvl - REAL(kind_phys), DIMENSION( its:ite , jts:jte ) :: frc,var_sum_clw,rain_clw - real(kind_phys) :: dvar,factor,rho_water - integer :: nv,i,j,k - - rho_water = 1000. - var_rmv (:,:,:)=0. - - do nv=1,num_chem -! -! simple LS removal -! - -! -! proportionality constant -! - frc(:,:)=0.1 - do i=its,ite - do j=jts,jte - var_sum_clw(i,j)=0. - var_sum(i,j)=0. - var_rmvl(i,:,j)=0. - rain_clw(i,j)=0. - if(rain(i,j).gt.1.e-6)then -! convert rain back to rate -! - rain_clw(i,j)=rain(i,j)/dt -! total cloud water -! - do k=1,kte - dvar=max(0.,(moist(i,k,j,p_qc)+moist(i,k,j,p_qi))) - var_sum_clw(i,j)=var_sum_clw(i,j)+dvar - enddo - endif - enddo - enddo -! -! get rid of it -! - do i=its,ite - do j=jts,jte - if(rain(i,j).gt.1.e-6 .and. var_sum_clw(i,j).gt.1.e-10 ) then - do k=kts,kte - if(var(i,k,j,nv).gt.1.e-08 .and. (moist(i,k,j,p_qc)+moist(i,k,j,p_qi)).gt.1.e-8)then - factor = max(0.,frc(i,j)*rho(i,k,j)*dz8w(i,k,j)*vvel(i,k,j)) - dvar=max(0.,data%alpha(nv)*factor/(1+factor)*var(i,k,j,nv)) - dvar=min(dvar,var(i,k,j,nv)) - var_rmvl(i,k,j)=dvar - if((var(i,k,j,nv)-dvar).lt.1.e-16)then - dvar=var(i,k,j,nv)-1.e-16 - var_rmvl(i,k,j)=dvar !lzhang - var(i,k,j,nv)=var(i,k,j,nv)-dvar - else - var(i,k,j,nv)=var(i,k,j,nv)-dvar - endif - !var_rmv(i,j,nv)=var_rmv(i,j,nv)+var_rmvl(i,k,j) - !!convert wetdeposition into ug/m2/s - var_rmv(i,j,nv)=var_rmv(i,j,nv)+(var_rmvl(i,k,j)*rho(i,k,j)*dz8w(i,k,j)/dt) !lzhang - endif - enddo - var_rmv(i,j,nv)=max(0.,var_rmv(i,j,nv)) - endif - enddo - enddo - enddo - - end subroutine wetdep_ls - -!------------------------------------------------------------------------- -! NASA/GSFC, Global Modeling and Assimilation Office, Code 900.3 ! -!------------------------------------------------------------------------- -!BOP -! -! !IROUTINE: WetRemovalGOCART - Calculate aerosol wet removal due -! to large scale processes. -! -! !INTERFACE: -! - - subroutine WetRemovalGOCART ( data,i1, i2, j1, j2, k1, k2, n1, n2, cdt, & - num_chem, var_rmv, chem, ple, tmpu, & - rhoa, dqcond, precc, precl, grav, & - ims, ime, jms, jme, kms, kme) -! ims, ime, jms, jme, kms, kme, rc ) - -! !USES: - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - -! !INPUT PARAMETERS: - integer, intent(in) :: i1, i2, j1, j2, k1, k2, n1, n2, num_chem, & - ims, ime, jms, jme, kms, kme - real(kind_phys), intent(in) :: cdt, grav - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ,1:num_chem),& - INTENT(INOUT) :: chem - REAL(kind_phys), DIMENSION( ims:ime , jms:jme,num_chem ), & - INTENT(INOUT ) :: var_rmv !! tracer loss flux [kg m-2 s-1] - real(kind_phys), dimension(ims:ime, kms:kme, jms:jme),& - INTENT(IN) :: ple, tmpu, rhoa, dqcond - real(kind_phys), dimension(ims:ime , jms:jme) , & - INTENT(IN) :: precc, precl ! cv, ls precip [mm day-1] - -! !OUTPUT PARAMETERS: -! integer, intent(out) :: rc ! Error return code: - ! 0 - all is well - ! 1 - - -! !DESCRIPTION: Calculates the updated species concentration due to wet -! removal. As written, intended to function for large -! scale (not convective) wet removal processes - -! -! !REVISION HISTORY: -! -! 08Jan2010 - Colarco, based on GOCART implementation, does not -! include any size dependent term -! -!EOP -!------------------------------------------------------------------------- - -! !Local Variables - character(len=*), parameter :: myname = 'WetRemovalGOCART' - integer :: i, j, k, n, nbins, LH, kk, ios,nv - real(kind_phys) :: pdog(i1:i2,k1:k2,j1:j2) ! air mass factor dp/g [kg m-2] - real(kind_phys) :: pls, pcv, pac ! ls, cv, tot precip [mm day-1] - real(kind_phys) :: qls(k1:k2), qcv(k1:k2) ! ls, cv portion dqcond [kg m-3 s-1] - real(kind_phys) :: qmx, qd, A ! temporary variables on moisture - real(kind_phys) :: F, B, BT ! temporary variables on cloud, freq. - real(kind_phys), allocatable :: fd(:,:) ! flux across layers [kg m-2] - real(kind_phys), allocatable :: DC(:) ! scavenge change in mass mixing ratio -! Rain parameters from Liu et al. - real(kind_phys), parameter :: B0_ls = 1.0e-4 - real(kind_phys), parameter :: F0_ls = 1.0 - real(kind_phys), parameter :: XL_ls = 5.0e-4 - real(kind_phys), parameter :: B0_cv = 1.5e-3 - real(kind_phys), parameter :: F0_cv = 0.3 - real(kind_phys), parameter :: XL_cv = 2.0e-3 -! Duration of rain: ls = model timestep, cv = 1800 s (<= cdt) - real(kind_phys) :: Td_ls - real(kind_phys) :: Td_cv - - -! Efficiency of dust wet removal (since dust is really not too hygroscopic) -! Applied only to in-cloud scavenging - real(kind_phys) :: effRemoval -! real(kind_phys),dimension(20) ::fwet -! tracer: p_so2=1 p_sulf=2 p_dms=3 p_msa=4 p_p25=5 p_bc1=6 p_bc2=7 p_oc1=8 -! p_oc2=9 p_dust_1=10 p_dust_2=11 p_dust_3=12 p_dust_4=13 p_dust_5=14 -! p_seas_1=15 p_seas_2=16 p_seas_3=17 p_seas_4=18 p_seas_5=19 p_p10 =20 -! data fwet /0.,1.5,0.,0.,1.,0.7,0.7,0.4,0.4,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1./ -! rc=0. - -! Initialize local variables -! -------------------------- -! rc = CHEM_RC_SUCCESS - - Td_ls = cdt - Td_cv = cdt - nbins = n2-n1+1 - var_rmv = 0.0 - -! Allocate the dynamic arrays - allocate(fd(k1:k2,nbins),stat=ios) -! if (chem_rc_test((ios .ne. 0), msg="Failed to allocate memory", & -! file=__FILE__, line=__LINE__, rc=rc)) return - allocate(dc(nbins),stat=ios) -! if (chem_rc_test((ios .ne. 0), msg="Failed to allocate memory", & -! file=__FILE__, line=__LINE__, rc=rc)) return - -! Accumulate the 3-dimensional arrays of rhoa and pdog - do j = j1, j2 - do i = i1, i2 - !pdog(i,k1:k2,j) = (ple(i,k1+1:k2+1,j)-ple(i,k1:k2,j)) / grav - pdog(i,k1:k2,j) = (ple(i,k1:k2,j)-ple(i,k1+1:k2+1,j)) / grav !lzhang - enddo - enddo - - do nv=1, num_chem -! Loop over spatial indices - do j = j1, j2 - big_i_loop: do i = i1, i2 - -! Check for total precipitation amount -! Assume no precip in column if precl+precc = 0 - pac = precl(i,j) + precc(i,j) - if(pac .le. 0.) cycle big_i_loop - pls = precl(i,j) - pcv = precc(i,j) - -! Initialize the precipitation fields - qls(:) = 0. - qcv(:) = 0. - fd(:,:) = 0. - -! Find the highest model layer experiencing rainout. Assumes no -! scavenging if T < 258 K - !LH = 0 - LH = k2+1 !lzhang - !do k = k1, k2 - do k = k2, k1,-1 !lzhang - if(dqcond(i,k,j) .lt. 0. .and. tmpu(i,k,j) .gt. 258.) then - LH = k - exit - endif - end do - if(LH .gt. k2) cycle big_i_loop !lzhang - -! convert dqcond from kg water/kg air/s to kg water/m3/s and reverse -! sign so that dqcond < 0. (positive precip) means qls and qcv > 0. - !do k = LH, k2 - do k = LH, k1, -1 !lzhang - qls(k) = -dqcond(i,k,j)*pls/pac*rhoa(i,k,j) - qcv(k) = -dqcond(i,k,j)*pcv/pac*rhoa(i,k,j) - end do - -! Loop over vertical to do the scavenging! - !do k = LH, k2 - do k = LH, k1, -1 !lzhang - -!----------------------------------------------------------------------------- -! (1) LARGE-SCALE RAINOUT: -! Tracer loss by rainout = TC0 * F * exp(-B*dt) -! where B = precipitation frequency, -! F = fraction of grid box covered by precipitating clouds. -! We assume that tracer scavenged by rain is falling down to the -! next level, where a fraction could be re-evaporated to gas phase -! if Qls is less then 0 in that level. -!----------------------------------------------------------------------------- - if (qls(k) .gt. 0.) then - F = F0_ls / (1. + F0_ls*B0_ls*XL_ls/(qls(k)*cdt/Td_ls)) - B = B0_ls/F0_ls +1./(F0_ls*XL_ls/qls(k)) - BT = B * Td_ls - if (BT.gt.10.) BT = 10. !< Avoid overflow > -! Adjust du level: - do n = 1, nbins - effRemoval = data%alpha(nv) - DC(n) = chem(i,k,j,nv) * F * effRemoval *(1.-exp(-BT)) - if (DC(n).lt.0.) DC(n) = 0. - chem(i,k,j,nv) = chem(i,k,j,nv)-DC(n) - if (chem(i,k,j,nv) .lt. 1.0E-32) chem(i,k,j,nv) = 1.0E-32 - end do -! Flux down: unit is kg m-2 -! Formulated in terms of production in the layer. In the revaporation step -! we consider possibly adding flux from above... - do n = 1, nbins - Fd(k,n) = DC(n)*pdog(i,k,j) - end do - - end if ! if Qls > 0 >>> - -!----------------------------------------------------------------------------- -! * (2) LARGE-SCALE WASHOUT: -! * Occurs when rain at this level is less than above. -!----------------------------------------------------------------------------- - !if(k .gt. LH .and. qls(k) .ge. 0.) then - if(k .lt. LH .and. qls(k) .ge. 0.) then !lzhang - !if(qls(k) .lt. qls(k-1)) then - if(qls(k) .lt. qls(k+1)) then !lzhang -! Find a maximum F overhead until the level where Qls<0. - Qmx = 0. - !do kk = k-1,LH,-1 - do kk = k+1,LH !lzhang - if (Qls(kk).gt.0.) then - Qmx = max(Qmx,Qls(kk)) - else - exit - end if - end do - - F = F0_ls / (1. + F0_ls*B0_ls*XL_ls/(Qmx*cdt/Td_ls)) - if (F.lt.0.01) F = 0.01 -!----------------------------------------------------------------------------- -! The following is to convert Q(k) from kgH2O/m3/sec to mm/sec in order -! to use the Harvard formula. Convert back to mixing ratio by multiplying -! by rhoa. Multiply by pdog gives kg/m2/s of precip. Divide by density -! of water (=1000 kg/m3) gives m/s of precip and multiply by 1000 gives -! units of mm/s (omit the multiply and divide by 1000). -!----------------------------------------------------------------------------- - - Qd = Qmx /rhoa(i,k,j)*pdog(i,k,j) - if (Qd.ge.50.) then - B = 0. - else - B = Qd * 0.1 - end if - BT = B * cdt - if (BT.gt.10.) BT = 10. - -! Adjust du level: - do n = 1, nbins - DC(n) = chem(i,k,j,nv) * F * (1.-exp(-BT)) - if (DC(n).lt.0.) DC(n) = 0. - chem(i,k,j,nv) = chem(i,k,j,nv)-DC(n) - if (chem(i,k,j,nv) .lt. 1.0E-32) & - chem(i,k,j,nv) = 1.0E-32 - var_rmv(i,j,nv) = var_rmv(i,j,nv)+DC(n)*pdog(i,k,j)/cdt !ug/m2/s - end do - - end if - end if ! if ls washout >>> -#if 0 -!----------------------------------------------------------------------------- -! (3) CONVECTIVE RAINOUT: -! Tracer loss by rainout = dd0 * F * exp(-B*dt) -! where B = precipitation frequency, -! F = fraction of grid box covered by precipitating clouds. -!----------------------------------------------------------------------------- - - if (qcv(k) .gt. 0.) then - F = F0_cv / (1. + F0_cv*B0_cv*XL_cv/(Qcv(k)*cdt/Td_cv)) - B = B0_cv - BT = B * Td_cv - if (BT.gt.10.) BT = 10. !< Avoid overflow > - -! Adjust du level: - do n = 1, nbins - effRemoval = data%alpha(nv) - DC(n) = chem(i,k,j,nv) * F * effRemoval * (1.-exp(-BT)) - if (DC(n).lt.0.) DC(n) = 0. - chem(i,k,j,nv) = chem(i,k,j,nv)-DC(n) - if (chem(i,k,j,nv) .lt. 1.0E-32) chem(i,k,j,nv) = 1.0E-32 - end do - -!------ Flux down: unit is kg. Including both ls and cv. - do n = 1, nbins - Fd(k,n) = Fd(k,n) + DC(n)*pdog(i,k,j) - end do - - end if ! if Qcv > 0 >>> - -!----------------------------------------------------------------------------- -! (4) CONVECTIVE WASHOUT: -! Occurs when rain at this level is less than above. -!----------------------------------------------------------------------------- - - !if (k.gt.LH .and. Qcv(k).ge.0.) then - if (k.lt.LH .and. Qcv(k).ge.0.) then !lzhang - !if (Qcv(k).lt.Qcv(k-1)) then - if (Qcv(k).lt.Qcv(k+1)) then !lzhang -!----- Find a maximum F overhead until the level where Qls<0. - Qmx = 0. - !do kk = k-1, LH, -1 - do kk = k+1, LH !lzhang - if (Qcv(kk).gt.0.) then - Qmx = max(Qmx,Qcv(kk)) - else - exit - end if - end do - - F = F0_cv / (1. + F0_cv*B0_cv*XL_cv/(Qmx*cdt/Td_cv)) - if (F.lt.0.01) F = 0.01 -!----------------------------------------------------------------------------- -! The following is to convert Q(k) from kgH2O/m3/sec to mm/sec in order -! to use the Harvard formula. Convert back to mixing ratio by multiplying -! by rhoa. Multiply by pdog gives kg/m2/s of precip. Divide by density -! of water (=1000 kg/m3) gives m/s of precip and multiply by 1000 gives -! units of mm/s (omit the multiply and divide by 1000). -!----------------------------------------------------------------------------- - - Qd = Qmx / rhoa(i,k,j)*pdog(i,k,j) - if (Qd.ge.50.) then - B = 0. - else - B = Qd * 0.1 - end if - BT = B * cdt - if (BT.gt.10.) BT = 10. - -! Adjust du level: - do n = 1, nbins - DC(n) = chem(i,k,j,nv) * F * (1.-exp(-BT)) - if (DC(n).lt.0.) DC(n) = 0. - chem(i,k,j,nv) = chem(i,k,j,nv)-DC(n) - if (chem(i,k,j,nv) .lt. 1.0E-32) & - chem(i,k,j,nv) = 1.0E-32 - var_rmv(i,j,nv) = var_rmv(i,j,nv)+DC(n)*pdog(i,k,j)/cdt !ug/m2/s - end do - - end if - end if ! if cv washout >>> -#endif -!----------------------------------------------------------------------------- -! (5) RE-EVAPORATION. Assume that SO2 is re-evaporated as SO4 since it -! has been oxidized by H2O2 at the level above. -!----------------------------------------------------------------------------- -! Add in the flux from above, which will be subtracted if reevaporation occurs - !if(k .gt. LH) then - if(k .lt. LH) then !lzhang - do n = 1, nbins - !Fd(k,n) = Fd(k,n) + Fd(k-1,n) - Fd(k,n) = Fd(k,n) + Fd(k+1,n) !lzhang - end do - -! Is there evaporation in the currect layer? - if (-dqcond(i,k,j) .lt. 0.) then -! Fraction evaporated = H2O(k)evap / H2O(next condensation level). - !if (-dqcond(i,k-1,j) .gt. 0.) then - if (-dqcond(i,k+1,j) .gt. 0.) then !lzhang - - A = abs( dqcond(i,k,j) * pdog(i,k,j) & - !/ ( dqcond(i,k-1,j) * pdog(i,k-1,j)) ) - / ( dqcond(i,k+1,j) * pdog(i,k+1,j)) ) !lzhang - if (A .gt. 1.) A = 1. - -! Adjust tracer in the level - do n = 1, nbins - !DC(n) = Fd(k-1,n) / pdog(i,k,j) * A - DC(n) = Fd(k+1,n) / pdog(i,k,j) * A !lzhang - chem(i,k,j,nv) = chem(i,k,j,nv) + DC(n) - chem(i,k,j,nv) = max(chem(i,k,j,nv),1.e-32) -! Adjust the flux out of the bottom of the layer - Fd(k,n) = Fd(k,n) - DC(n)*pdog(i,k,j) - end do - - endif - endif ! if -moistq < 0 - endif - end do ! k - - do n = 1, nbins - !var_rmv(i,j,nv) = var_rmv(i,j,nv)+Fd(k2,n)/cdt !lzhang - var_rmv(i,j,nv) = var_rmv(i,j,nv)+Fd(k1,n)/cdt ! ug/m2/s - end do - - end do big_i_loop ! i - end do ! j - end do !nv for num_chem - - deallocate(fd,DC,stat=ios) -! if (chem_rc_test((ios .ne. 0), msg="Failed to deallocate memory", & -! file=__FILE__, line=__LINE__, rc=rc)) return - - end subroutine WetRemovalGOCART - -end module dep_wet_ls_mod diff --git a/smoke/dust_fengsha_mod.F90 b/smoke/dust_fengsha_mod.F90 deleted file mode 100755 index fbf87aa56..000000000 --- a/smoke/dust_fengsha_mod.F90 +++ /dev/null @@ -1,601 +0,0 @@ -!>\file dust_fengsha_mod.F90 -!! This file contains the FENGSHA dust scheme. - -module dust_fengsha_mod -! -! This module developed by Barry Baker (NOAA ARL) -! For serious questions contact barry.baker@noaa.gov -! -! 07/16/2019 - Adapted for NUOPC/GOCART, R. Montuoro -! 02/01/2020 - Adapted for FV3/CCPP, Haiqin Li - - use rrfs_smoke_data - use machine , only : kind_phys - use dust_data_mod - - implicit none - - private - - public :: gocart_dust_fengsha_driver - -contains - - subroutine gocart_dust_fengsha_driver(data, dt, & - chem,rho_phy,smois,p8w,ssm, & - isltyp,vegfra,snowh,xland,area,g,emis_dust, & - ust,znt,clay,sand,rdrag,uthr, & - num_emis_dust,num_moist,num_chem,num_soil_layers, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) - IMPLICIT NONE - type(smoke_data), intent(inout) :: data - INTEGER, INTENT(IN ) :: & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte, & - num_emis_dust,num_moist,num_chem,num_soil_layers - INTEGER,DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: isltyp - REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), INTENT(INOUT) :: chem - REAL(kind_phys), DIMENSION( ims:ime, 1, jms:jme,num_emis_dust),OPTIONAL, INTENT(INOUT) :: emis_dust - REAL(kind_phys), DIMENSION( ims:ime, num_soil_layers, jms:jme ), INTENT(IN) :: smois - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: ssm - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: vegfra, & - snowh, & - xland, & - area, & - ust, & - znt, & - clay, & - sand, & - rdrag, & - uthr - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(IN ) :: & - p8w, & - rho_phy - REAL(kind_phys), INTENT(IN) :: dt,g - - ! Local variables - - integer :: nmx,smx,i,j,k,imx,jmx,lmx - integer,dimension (1,1) :: ilwi - real(kind_phys), DIMENSION (1,1) :: erodtot - REAL(kind_phys), DIMENSION (1,1) :: gravsm - REAL(kind_phys), DIMENSION (1,1) :: drylimit - real(kind_phys), DIMENSION (5) :: tc,bems - real(kind_phys), dimension (1,1) :: airden,airmas,ustar - real(kind_phys), dimension (1) :: dxy - real(kind_phys), dimension (3) :: massfrac - real(kind_phys) :: conver,converi - real(kind_phys) :: R - - ! threshold values - conver=1.e-9 - converi=1.e9 - - ! Number of dust bins - - imx=1 - jmx=1 - lmx=1 - nmx=ndust - smx=nsalt - - k=kts - do j=jts,jte - do i=its,ite - - ! Don't do dust over water!!! - - ilwi(1,1)=0 - if(xland(i,j).lt.1.5)then - ilwi(1,1)=1 - - ! Total concentration at lowest model level. This is still hardcoded for 5 bins. - - ! if(config_flags%chem_opt == 2 .or. config_flags%chem_opt == 11 ) then - ! tc(:)=1.e-16*conver - ! else - tc(1)=chem(i,kts,j,p_dust_1)*conver - tc(2)=chem(i,kts,j,p_dust_2)*conver - tc(3)=chem(i,kts,j,p_dust_3)*conver - tc(4)=chem(i,kts,j,p_dust_4)*conver - tc(5)=chem(i,kts,j,p_dust_5)*conver - ! endif - - ! Air mass and density at lowest model level. - - airmas(1,1)=-(p8w(i,kts+1,j)-p8w(i,kts,j))*area(i,j)/g - airden(1,1)=rho_phy(i,kts,j) - ustar(1,1)=ust(i,j) - dxy(1)=area(i,j) - - ! Mass fractions of clay, silt, and sand. - massfrac(1)=clay(i,j) - massfrac(2)=1-(clay(i,j)+sand(i,j)) - massfrac(3)=sand(i,j) - - - ! Total erodibility. - - erodtot(1,1) = ssm(i,j) ! SUM(erod(i,j,:)) - - ! Don't allow roughness lengths greater than 20 cm to be lofted. - ! This kludge accounts for land use types like urban areas and - ! forests which would otherwise show up as high dust emitters. - ! This is a placeholder for a more widely accepted kludge - ! factor in the literature, which reduces lofting for rough areas. - ! Forthcoming... - - IF (znt(i,j) .gt. 0.2) then - ilwi(1,1)=0 - endif - - ! limit where there is lots of vegetation - if (vegfra(i,j) .gt. .17) then - ilwi(1,1) = 0 - endif - - ! limit where there is snow on the ground - if (snowh(i,j) .gt. 0) then - ilwi(1,1) = 0 - endif - - ! Do not allow areas with bedrock, lava, or land-ice to loft - - IF (isltyp(i,j) .eq. 15 .or. isltyp(i,j) .eq. 16. .or. & - isltyp(i,j) .eq. 18) then - ilwi(1,1)=0 - ENDIF - IF (isltyp(i,j) .eq. 0)then - ilwi(1,1)=0 - endif - if(ilwi(1,1) == 0 ) cycle - - ! Calculate gravimetric soil moisture and drylimit. - gravsm(1,1)=100.*smois(i,1,j)/((1.-maxsmc(isltyp(i,j)))*(2.65*(1.-clay(i,j))+2.50*clay(i,j))) - drylimit(1,1)=14.0*clay(i,j)*clay(i,j)+17.0*clay(i,j) - - ! get drag partition - ! FENGSHA uses the drag partition correction of MacKinnon et al 2004 - ! doi:10.1016/j.geomorph.2004.03.009 - if (dust_calcdrag .ne. 1) then - call fengsha_drag(data,znt(i,j),R) - else - ! use the precalculated version derived from ASCAT; Prigent et al. (2012,2015) - ! doi:10.1109/TGRS.2014.2338913 & doi:10.5194/amt-5-2703-2012 - ! pick only valid values - if (rdrag(i,j) > 0.) then - R = real(rdrag(i,j), kind=kind_phys) - else - cycle - endif - endif - - ! Call dust emission routine. - call source_dust(data, imx, jmx, lmx, nmx, smx, dt, tc, ustar, massfrac, & - erodtot, dxy, gravsm, airden, airmas, & - bems, g, drylimit, dust_alpha, dust_gamma, R, uthr(i,j)) - - ! if(config_flags%chem_opt == 2 .or. config_flags%chem_opt == 11 ) then - ! dustin(i,j,1:5)=tc(1:5)*converi - ! else - chem(i,kts,j,p_dust_1)=tc(1)*converi - chem(i,kts,j,p_dust_2)=tc(2)*converi - chem(i,kts,j,p_dust_3)=tc(3)*converi - chem(i,kts,j,p_dust_4)=tc(4)*converi - chem(i,kts,j,p_dust_5)=tc(5)*converi - ! endif - - ! chem(i,kts,j,p_dust_1)=tc(1)*converi - ! chem(i,kts,j,p_dust_2)=tc(2)*converi - ! chem(i,kts,j,p_dust_3)=tc(3)*converi - ! chem(i,kts,j,p_dust_4)=tc(4)*converi - ! chem(i,kts,j,p_dust_5)=tc(5)*converi - - ! For output diagnostics - - emis_dust(i,1,j,p_edust1)=bems(1) - emis_dust(i,1,j,p_edust2)=bems(2) - emis_dust(i,1,j,p_edust3)=bems(3) - emis_dust(i,1,j,p_edust4)=bems(4) - emis_dust(i,1,j,p_edust5)=bems(5) - endif - enddo - enddo - ! - - end subroutine gocart_dust_fengsha_driver - - - SUBROUTINE source_dust(data, imx, jmx, lmx, nmx, smx, dt1, tc, ustar, massfrac, & - erod, dxy, gravsm, airden, airmas, bems, g0, drylimit, alpha, & - gamma, R, uthres) - - ! **************************************************************************** - ! * Evaluate the source of each dust particles size bin by soil emission - ! * - ! * Input: - ! * EROD Fraction of erodible grid cell (-) - ! * GRAVSM Gravimetric soil moisture (g/g) - ! * DRYLIMIT Upper GRAVSM limit for air-dry soil (g/g) - ! * ALPHA Constant to fudge the total emission of dust (1/m) - ! * GAMMA Tuning constant for erodibility (-) - ! * DXY Surface of each grid cell (m2) - ! * AIRMAS Mass of air for each grid box (kg) - ! * AIRDEN Density of air for each grid box (kg/m3) - ! * USTAR Friction velocity (m/s) - ! * DT1 Time step (s) - ! * NMX Number of dust bins (-) - ! * SMX Number of saltation bins (-) - ! * IMX Number of I points (-) - ! * JMX Number of J points (-) - ! * LMX Number of L points (-) - ! * R Drag Partition (-) - ! * UTHRES FENGSHA Dry Threshold Velocities (m/s) - ! * - ! * Data: - ! * MASSFRAC Fraction of mass in each of 3 soil classes (-) - ! * SPOINT Pointer to 3 soil classes (-) - ! * DEN_DUST Dust density (kg/m3) - ! * DEN_SALT Saltation particle density (kg/m3) - ! * REFF_SALT Reference saltation particle diameter (m) - ! * REFF_DUST Reference dust particle diameter (m) - ! * LO_DUST Lower diameter limits for dust bins (m) - ! * UP_DUST Upper diameter limits for dust bins (m) - ! * FRAC_SALT Soil class mass fraction for saltation bins (-) - ! * - ! * Parameters: - ! * CMB Constant of proportionality (-) - ! * MMD_DUST Mass median diameter of dust (m) - ! * GSD_DUST Geometric standard deviation of dust (-) - ! * LAMBDA Side crack propagation length (m) - ! * CV Normalization constant (-) - ! * G0 Gravitational acceleration (m/s2) - ! * G Gravitational acceleration in cgs (cm/s2) - ! * - ! * Working: - ! * U_TS0 "Dry" threshold friction velocity (m/s) - ! * U_TS Moisture-adjusted threshold friction velocity (m/s) - ! * RHOA Density of air in cgs (g/cm3) - ! * DEN Dust density in cgs (g/cm3) - ! * DIAM Dust diameter in cgs (cm) - ! * DMASS Saltation mass distribution (-) - ! * DSURFACE Saltation surface area per unit mass (m2/kg) - ! * DS_REL Saltation surface area distribution (-) - ! * SALT Saltation flux (kg/m/s) - ! * DLNDP Dust bin width (-) - ! * EMIT Total vertical mass flux (kg/m2/s) - ! * EMIT_VOL Total vertical volume flux (m/s) - ! * DSRC Mass of emitted dust (kg/timestep/cell) - ! * - ! * Output: - ! * TC Total concentration of dust (kg/kg/timestep/cell) - ! * BEMS Source of each dust type (kg/timestep/cell) - ! * - ! **************************************************************************** - implicit none - type(smoke_data), intent(inout) :: data - - INTEGER, INTENT(IN) :: imx,jmx,lmx,nmx,smx - REAL(kind_phys), INTENT(IN) :: dt1 - REAL(kind_phys), INTENT(INOUT) :: tc(imx,jmx,lmx,nmx) - REAL(kind_phys), INTENT(IN) :: ustar(imx,jmx) - REAL(kind_phys), INTENT(IN) :: massfrac(3) - REAL(kind_phys), INTENT(IN) :: erod(imx,jmx) - REAL(kind_phys), INTENT(IN) :: dxy(jmx) - REAL(kind_phys), INTENT(IN) :: gravsm(imx,jmx) - REAL(kind_phys), INTENT(IN) :: airden(imx,jmx,lmx) - REAL(kind_phys), INTENT(IN) :: airmas(imx,jmx,lmx) - REAL(kind_phys), INTENT(OUT) :: bems(imx,jmx,nmx) - REAL(kind_phys), INTENT(IN) :: g0 - REAL(kind_phys), INTENT(IN) :: drylimit(imx,jmx) - !! Sandblasting mass efficiency, aka "fudge factor" (based on Tegen et al, - !! 2006 and Hemold et al, 2007) - ! - ! REAL, PARAMETER :: alpha=1.8E-8 ! (m^-1) - REAL(kind_phys), INTENT(IN) :: alpha - ! Experimental optional exponential tuning constant for erodibility. - ! 0 < gamma < 1 -> more relative impact by low erodibility regions. - REAL(kind_phys), INTENT(IN) :: gamma - REAL(kind_phys), INTENT(IN) :: R - REAL(kind_phys), INTENT(IN) :: uthres - - REAL(kind_phys) :: den(smx), diam(smx) - REAL(kind_phys) :: dvol(nmx), distr_dust(nmx), dlndp(nmx) - REAL(kind_phys) :: dsurface(smx), ds_rel(smx) - REAL(kind_phys) :: u_ts0, u_ts, dsrc, dmass, dvol_tot - REAL(kind_phys) :: salt,emit, emit_vol, stotal - REAL(kind_phys) :: rhoa, g - INTEGER :: i, j, n - - ! Sandblasting mass efficiency, beta. - ! Beta maxes out for clay fractions above 0.2 = betamax. - - REAL(kind_phys), PARAMETER :: betamax=5.25E-4 - REAL(kind_phys) :: beta - integer :: styp - - ! Constant of proportionality from Marticorena et al, 1997 (unitless) - ! Arguably more ~consistent~ fudge than alpha, which has many walnuts - ! sprinkled throughout the literature. - GC - - REAL(kind_phys), PARAMETER :: cmb=1.0 - ! REAL, PARAMETER :: cmb=2.61 ! from White,1979 - - ! Parameters used in Kok distribution function. Advise not to play with - ! these without the expressed written consent of someone who knows what - ! they're doing. - GC - - REAL(kind_phys), PARAMETER :: mmd_dust=3.4D-6 ! median mass diameter (m) - REAL(kind_phys), PARAMETER :: gsd_dust=3.0 ! geom. std deviation - REAL(kind_phys), PARAMETER :: lambda=12.0D-6 ! crack propagation length (m) - REAL(kind_phys), PARAMETER :: cv=12.62D-6 ! normalization constant - - ! Calculate saltation surface area distribution from sand, silt, and clay - ! mass fractions and saltation bin fraction. This will later become a - ! modifier to the total saltation flux. The reasoning here is that the - ! size and availability of saltators affects saltation efficiency. Based - ! on Eqn. (32) in Marticorena & Bergametti, 1995 (hereon, MB95). - - DO n=1,smx - dmass=massfrac(spoint(n))*frac_salt(n) - dsurface(n)=0.75*dmass/(den_salt(n)*reff_salt(n)) - ENDDO - - ! The following equation yields relative surface area fraction. It will only - ! work if you are representing the "full range" of all three soil classes. - ! For this reason alone, we have incorporated particle sizes that encompass - ! the clay class, to account for the its relative area over the basal - ! surface, even though these smaller bins would be unlikely to play any large - ! role in the actual saltation process. - GC - - stotal=SUM(dsurface(:)) - DO n=1,smx - ds_rel(n)=dsurface(n)/stotal - ENDDO - - ! Calculate total dust emission due to saltation of sand sized particles. - ! Begin by calculating DRY threshold friction velocity (u_ts0). Next adjust - ! u_ts0 for moisture to get threshold friction velocity (u_ts). Then - ! calculate saltation flux (salt) where ustar has exceeded u_ts. Finally, - ! calculate total dust emission (tot_emit), taking into account erodibility. - - ! Set DRY threshold friction velocity to input value - u_ts0 = uthres - - g = g0*1.0E2 - emit=0.0 - - DO n = 1, smx - den(n) = den_salt(n)*1.0D-3 ! (g cm^-3) - diam(n) = 2.0*reff_salt(n)*1.0D2 ! (cm) - DO i = 1,imx - DO j = 1,jmx - rhoa = airden(i,j,1)*1.0D-3 ! (g cm^-3) - - ! FENGSHA uses the 13 category soil type from the USDA - ! call calc_fengsha_styp(massfrac(1),massfrac(3),massfrac(2),styp) - ! Fengsha uses threshold velocities based on dale gilletes data - ! call fengsha_utst(styp,uthres,u_ts0) - - ! Friction velocity threshold correction function based on physical - ! properties related to moisture tension. Soil moisture greater than - ! dry limit serves to increase threshold friction velocity (making - ! it more difficult to loft dust). When soil moisture has not reached - ! dry limit, treat as dry - - IF (gravsm(i,j) > drylimit(i,j)) THEN - u_ts = MAX(0.0D+0,u_ts0*(sqrt(1.0+1.21*(gravsm(i,j)-drylimit(i,j))**0.68)) / R) - ELSE - u_ts = u_ts0 / R - END IF - - ! Calculate total vertical mass flux (note beta has units of m^-1) - ! Beta acts to tone down dust in areas with so few dust-sized particles that the - ! lofting efficiency decreases. Otherwise, super sandy zones would be huge dust - ! producers, which is generally not the case. Equation derived from wind-tunnel - ! experiments (see MB95). - - beta=10**(13.6*massfrac(1)-6.0) ! (unitless) - if (massfrac(1) <= 0.2) then - beta=10**(13.4*massfrac(1)-6.0) - else - beta = 2.E-4 - endif - - !--------------------------------------------------------------------- - ! formula of Draxler & Gillette (2001) Atmos. Environ. - ! F = K A (r/g) U* ( U*^2 - Ut*^2 ) - ! - ! where: - ! F = vertical emission flux [g/m**2-s] - ! K = constant 2.0E-04 [1/m] - ! A = 0~3.5 mean = 2.8 (fudge factor) - ! U* = friction velocity [m/s] - ! Ut* = threshold friction velocity [m/s] - ! - !-------------------------------------------------------------------- - - IF (ustar(i,j) .gt. u_ts) then - call fengsha_hflux(data,ustar(i,j),u_ts,beta, salt) - salt = alpha * cmb * ds_rel(n) * airden(i,j,1) / g0 * salt * (erod(i,j)**gamma) * beta - else - salt = 0. - endif - ! EROD is taken into account above - emit = emit + salt - END DO - END DO - END DO - - ! Now that we have the total dust emission, distribute into dust bins using - ! lognormal distribution (Dr. Jasper Kok, in press), and - ! calculate total mass emitted over the grid box over the timestep. - ! - ! In calculating the Kok distribution, we assume upper and lower limits to each bin. - ! For reff_dust=(/0.73D-6,1.4D-6,2.4D-6,4.5D-6,8.0D-6/) (default), - ! lower limits were ASSUMED at lo_dust=(/0.1D-6,1.0D-6,1.8D-6,3.0D-6,6.0D-6/) - ! upper limits were ASSUMED at up_dust=(/1.0D-6,1.8D-6,3.0D-6,6.0D-6,10.0D-6/) - ! These may be changed within module_data_gocart_dust.F, but make sure it is - ! consistent with reff_dust values. These values were taken from the original - ! GOCART bin configuration. We use them here to calculate dust bin width, dlndp. - ! dVol is the volume distribution. You know...if you were wondering. GC - - dvol_tot=0. - DO n=1,nmx - dlndp(n)=LOG(up_dust(n)/lo_dust(n)) - dvol(n)=(2.0*reff_dust(n)/cv)*(1.+ERF(LOG(2.0*reff_dust(n)/mmd_dust)/(SQRT(2.)*LOG(gsd_dust))))*& - EXP(-(2.0*reff_dust(n)/lambda)**3.0)*dlndp(n) - dvol_tot=dvol_tot+dvol(n) - ! Convert mass flux to volume flux - !emit_vol=emit/den_dust(n) ! (m s^-1) - END DO - DO n=1,nmx - distr_dust(n)=dvol(n)/dvol_tot - !print *,"distr_dust(",n,")=",distr_dust(n) - END DO - - ! Now distribute total vertical emission into dust bins and update concentration. - - DO n=1,nmx - DO i=1,imx - DO j=1,jmx - ! Calculate total mass emitted - dsrc = emit*distr_dust(n)*dxy(j)*dt1 ! (kg) - IF (dsrc < 0.0) dsrc = 0.0 - - ! Update dust mixing ratio at first model level. - tc(i,j,1,n) = tc(i,j,1,n) + dsrc / airmas(i,j,1) ! (kg/kg) - ! bems(i,j,n) = dsrc ! diagnostic - !bems(i,j,n) = 1000.*dsrc/(dxy(j)*dt1) ! diagnostic (g/m2/s) - bems(i,j,n) = 1.e+9*dsrc/(dxy(j)*dt1) ! diagnostic (ug/m2/s) !lzhang - END DO - END DO - END DO - - END SUBROUTINE source_dust - - subroutine fengsha_utst(data,styp,uth, ut) - implicit none - type(smoke_data), intent(inout) :: data - - integer, intent(in) :: styp - real(kind_phys), dimension(fengsha_maxstypes), intent(in) :: uth - real(kind_phys), intent(out) :: ut - ut = uth(styp) -! real (kind_phys) :: uth(13) = & -! (/ 0.08, & ! Sand - 1 -! 0.20, & ! Loamy Sand - 2 -! 0.30, & ! Sandy Loam - 3 -! 0.30, & ! Silt Loam - 4 -! 0.35, & ! Silt - 5 -! 0.60, & ! Loam - 6 -! 0.30, & ! Sandy Clay Loam - 7 -! 0.35, & ! Silty Clay Loam - 8 -! 0.45, & ! Clay Loam - 9 -! 0.45, & ! Sandy Clay - 10 -! 0.45, & ! Silty Clay - 11 -! 0.60, & ! Clay - 12 -! 9.999 /) ! Other - 13 - return - end subroutine fengsha_utst - - subroutine calc_fengsha_styp(data, clay, sand, silt, type) - implicit none - type(smoke_data), intent(inout) :: data - - !--------------------------------------------------------------- - ! Function: calculate soil type based on USDA definition. - ! Source: USDA soil texture calculator - ! - ! Defintion of soil types: - ! - ! - ! NOAH 1 2 3 4 5 6 7 8 9 10 11 12 - ! PX 1 2 3 4 - 5 6 7 8 9 10 11 - ! Soil "Sand" "Loamy Sand" "Sandy Loam" "Silt Loam" "Silt" "Loam" "Sandy Clay Loam" "Silt Clay Loam" "Clay Loam" "Sandy Clay" "Silty Clay" "Clay" - !--------------------------------------------------------------- - REAL(kind_phys), intent(in) :: clay, sand, silt - integer, intent(out) :: type - real(kind_phys) :: cly, snd, slt - - type = 0 - - snd = sand * 100. - cly = clay * 100. - slt = silt * 100. - if (slt+1.5*cly .lt. 15) type = 1 ! snd - if (slt+1.5*cly .ge. 15 .and.slt+1.5*cly .lt. 30) type = 2 ! loamy snd - if (cly .ge. 7 .and. cly .lt. 20 .and. snd .gt. 52 .and. slt+2*cly .ge. 30) type = 3 ! sndy loam (cond 1) - if (cly .lt. 7 .and. slt .lt. 50 .and. slt+2*cly .ge. 30) type = 3 ! sndy loam (cond 2) - if (slt .ge. 50 .and. cly .ge. 12 .and.cly .lt. 27 ) type = 4 ! slt loam (cond 1) - if (slt .ge. 50 .and. slt .lt. 80 .and.cly .lt. 12) type = 4 ! slt loam (cond 2) - if (slt .ge. 80 .and. cly .lt. 12) type = 5 ! slt - if (cly .ge. 7 .and. cly .lt. 27 .and.slt .ge. 28 .and. slt .lt. 50 .and.snd .le. 52) type = 6 ! loam - if (cly .ge. 20 .and. cly .lt. 35 .and.slt .lt. 28 .and. snd .gt. 45) type = 7 ! sndy cly loam - if (cly .ge. 27 .and. cly .lt. 40 .and.snd .lt. 20) type = 8 ! slt cly loam - if (cly .ge. 27 .and. cly .lt. 40 .and.snd .ge. 20 .and. snd .le. 45) type = 9 ! cly loam - if (cly .ge. 35 .and. snd .gt. 45) type = 10 ! sndy cly - if (cly .ge. 40 .and. slt .ge. 40) type = 11 ! slty cly - if (cly .ge. 40 .and. snd .le. 45 .and.slt .lt. 40) type = 12 ! clay - return - end subroutine calc_fengsha_styp - - subroutine fengsha_drag(data,z0,R) - implicit none - type(smoke_data), intent(inout) :: data - - real(kind_phys), intent(in) :: z0 - real(kind_phys), intent(out) :: R - real(kind_phys), parameter :: z0s = 1.0e-04 !Surface roughness for ideal bare surface [m] - ! ------------------------------------------------------------------------ - ! Function: Calculates the MacKinnon et al. 2004 Drag Partition Correction - ! - ! R = 1.0 - log(z0 / z0s) / log( 0.7 * (12255./z0s) ** 0.8) - ! - !-------------------------------------------------------------------------- - ! Drag partition correction. See MacKinnon et al. (2004), - ! doi:10.1016/j.geomorph.2004.03.009 - R = 1.0 - log(z0 / z0s) / log( 0.7 * (12255./z0s) ** 0.8) - - ! Drag partition correction. See Marticorena et al. (1997), - ! doi:10.1029/96JD02964 - !R = 1.0 - log(z0 / z0s) / log( 0.7 * (10./z0s) ** 0.8) - - return - end subroutine fengsha_drag - - subroutine fengsha_hflux(data,ust,utst, kvh, salt) - !--------------------------------------------------------------------- - ! Function: Calculates the Horizontal Saltation Flux, Q, and then - ! calculates the vertical flux. - ! - ! formula of Draxler & Gillette (2001) Atmos. Environ. - ! F = K A (r/g) U* ( U*^2 - Ut*^2 ) - ! - ! where: - ! F = vertical emission flux [g/m**2-s] - ! K = constant 2.0E-04 [1/m] - ! A = 0~3.5 mean = 2.8 (fudge factor) - ! U* = friction velocity [m/s] - ! Ut* = threshold friction velocity [m/s] - ! - !-------------------------------------------------------------------- - implicit none - type(smoke_data), intent(inout) :: data - real(kind_phys), intent(in) :: ust, & ! friction velocity - utst, & ! threshold friction velocity - kvh ! vertical to horizontal mass flux ratio - - real(kind_phys), intent(out) :: salt - real(kind_phys) :: Q - Q = ust * (ust * ust - utst * utst) - salt = Q ! sdep * kvh * Q - - return - end subroutine fengsha_hflux - - -end module dust_fengsha_mod diff --git a/smoke/rrfs_smoke_data.F90 b/smoke/rrfs_smoke_data.F90 deleted file mode 100755 index cb9cc25e6..000000000 --- a/smoke/rrfs_smoke_data.F90 +++ /dev/null @@ -1,651 +0,0 @@ -!>\file rrfs_smoke_data.F90 -!! This file contains data for the RRFS-Smoke modules. - -module rrfs_smoke_data - use machine , only : kind_phys - implicit none - INTEGER, PARAMETER :: dep_seasons = 5 - INTEGER, PARAMETER :: nlu = 25 - - type wesely_pft - integer :: npft - integer :: months - INTEGER, pointer :: seasonal_wes(:,:,:,:) => NULL() - contains - final :: wesely_pft_destructor - end type wesely_pft - - interface wesely_pft - procedure :: wesely_pft_constructor - end interface wesely_pft - -!-------------------------------------------------- -! many of these parameters will depend on the RADM mechanism! -! if you change it, lets talk about it and get it done!!! -!-------------------------------------------------- - - REAL(kind_phys), parameter :: small_value = 1.e-36 - REAL(kind_phys), parameter :: large_value = 1.e36 - -!-------------------------------------------------- -! following currently hardwired to USGS -!-------------------------------------------------- - integer, parameter :: isice_temp = 24 - integer, parameter :: iswater_temp = 16 - integer, parameter :: wrf2mz_lt_map(nlu) = (/ 1, 2, 2, 2, 2, & - 4, 3, 3, 3, 3, & - 4, 5, 4, 5, 6, & - 7, 9, 6, 8, 9, & - 6, 6, 8, 0, 0 /) - real(kind_phys), parameter :: wh2o = 18.0153 - real(kind_phys), parameter :: wpan = 121.04793 - real(kind_phys), PARAMETER :: KARMAN=0.4 - INTEGER, parameter :: luse2usgs(21) = (/14,13,12,11,15,8,9,10,10,7, & - 17,4,1,5,24,19,16,21,22,23,16 /) - character(len=4), parameter :: mminlu = 'USGS' - - ! integer, parameter :: pan_seasons = 5 - ! integer, parameter :: pan_lands = 11 - - type smoke_data - ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Taken from dep_simple_mod - INTEGER :: ixxxlu(nlu) - REAL(KIND_PHYS) :: kpart(nlu) - REAL(KIND_PHYS) :: rac(nlu,dep_seasons), rclo(nlu,dep_seasons), rcls(nlu,dep_seasons) - REAL(KIND_PHYS) :: rgso(nlu,dep_seasons), rgss(nlu,dep_seasons) - REAL(KIND_PHYS) :: ri(nlu,dep_seasons), rlu(nlu,dep_seasons) - ! REAL(KIND_PHYS) :: ri_pan(pan_seasons,pan_lands) - ! never used: real(kind_phys) :: c0_pan(pan_lands) - ! never used: real(kind_phys) :: k_pan (pan_lands) - - ! never used: integer :: month - REAL(KIND_PHYS) :: dratio(1000), hstar(1000), hstar4(1000) - REAL(KIND_PHYS) :: f0(1000), dhr(1000), scpr23(1000) - - ! Note: scpr23 is only read, never written - - ! never used: type(wesely_pft) :: seasonal_pft - - ! never used: logical, pointer :: is_aerosol(:) => NULL() - - ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Taken from dep_wet_ls_mod - real(kind_phys), dimension(:), pointer :: alpha => NULL() - contains - final :: smoke_data_destructor - procedure :: dep_init - end type smoke_data - - interface smoke_data - procedure :: smoke_data_constructor - end interface smoke_data - - type(smoke_data), target, private :: private_thread_data - logical, private :: rrfs_smoke_data_initialized = .false. - - !$OMP THREADPRIVATE(private_thread_data) - !$OMP THREADPRIVATE(rrfs_smoke_data_initialized) - -contains - - function get_thread_smoke_data() result(data) - implicit none - class(smoke_data), pointer :: data - if(.not. rrfs_smoke_data_initialized) then - private_thread_data = smoke_data() - rrfs_smoke_data_initialized = .true. - endif - data => private_thread_data - end function get_thread_smoke_data - - subroutine wesely_pft_destructor(this) - implicit none - type(wesely_pft) :: this - if(associated(this%seasonal_wes)) then - deallocate(this%seasonal_wes) - nullify(this%seasonal_wes) - endif - end subroutine wesely_pft_destructor - - function wesely_pft_constructor() result(this) - implicit none - class(wesely_pft), pointer :: this - nullify(this%seasonal_wes) - end function wesely_pft_constructor - - function smoke_data_constructor() result(this) - implicit none - type(smoke_data) :: this - ! These are never used: - ! this%c0_pan = (/ 0.000, 0.006, 0.002, 0.009, 0.015, & - ! 0.006, 0.000, 0.000, 0.000, 0.002, 0.002 /) - ! this%k_pan = (/ 0.000, 0.010, 0.005, 0.004, 0.003, & - ! 0.005, 0.000, 0.000, 0.000, 0.075, 0.002 /) - ! this%month = 0 - ! this%seasonal_pft = wesely_pft() - ! nullify(this%is_aerosol) - nullify(this%alpha) - ! This is not called in the original non-thread-safe code: - ! call this%dep_init() - end function smoke_data_constructor - - subroutine smoke_data_destructor(this) - implicit none - type(smoke_data) :: this - if(associated(this%alpha)) then - deallocate(this%alpha) - nullify(this%alpha) - endif - ! Never used: - ! if(associated(this%is_aerosol)) then - ! deallocate(this%is_aerosol) - ! nullify(this%is_aerosolo) - ! endif - end subroutine smoke_data_destructor - - -! SUBROUTINE dep_init( id, numgas, mminlu_loc, & -! ips, ipe, jps, jpe, ide, jde ) - SUBROUTINE dep_init(this,errmsg,errflg) - ! Lifted out of dep_simple_mod, this initializes - ! member variables that were module variables in - ! that module. -!-- - implicit none - class(smoke_data) :: this - character(*), intent(inout) :: errmsg - integer, intent(inout) :: errflg - -!-------------------------------------------------- -! .. Scalar Arguments .. -!-------------------------------------------------- - ! Unused: - ! integer, intent(in) :: numgas - ! integer, intent(in) :: ips, ipe, jps, jpe - ! integer, intent(in) :: ide, jde - ! mmin_lu_loc had no definition, but is also unused - -!-------------------------------------------------- -! .. Local Scalars -!-------------------------------------------------- - INTEGER :: iland, iseason, l - integer :: iprt - integer :: astat - integer :: ncid - integer :: dimid - integer :: varid - integer :: cpos, slen - integer :: lon_e, lat_e - integer :: iend, jend - integer :: chem_opt - integer, allocatable :: input_wes_seasonal(:,:,:,:) - REAL(KIND_PHYS) :: sc - character(len=128) :: err_msg - character(len=128) :: filename - character(len=3) :: id_num -!-------------------------------------------------- -! .. Local Arrays -!-------------------------------------------------- - REAL(KIND_PHYS) :: dat1(nlu,dep_seasons), dat2(nlu,dep_seasons), & - dat3(nlu,dep_seasons), dat4(nlu,dep_seasons), & - dat5(nlu,dep_seasons), dat6(nlu,dep_seasons), & - dat7(nlu,dep_seasons) - ! REAL(KIND_PHYS) :: dat8(pan_seasons,pan_lands) - chem_opt = chem_opt - -!-------------------------------------------------- -! .. Data Statements .. -! THIS%RI for stomatal resistance -! data ((this%ri(ILAND,ISEASON),ILAND=1,nlu),ISEASON=1,dep_seasons)/0.10E+11, & - DATA ((dat1(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.10E+11, & - 0.60E+02, 0.60E+02, 0.60E+02, 0.60E+02, 0.70E+02, 0.12E+03, & - 0.12E+03, 0.12E+03, 0.12E+03, 0.70E+02, 0.13E+03, 0.70E+02, & - 0.13E+03, 0.10E+03, 0.10E+11, 0.80E+02, 0.10E+03, 0.10E+11, & - 0.80E+02, 0.10E+03, 0.10E+03, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.12E+03, 0.10E+11, 0.10E+11, & - 0.70E+02, 0.25E+03, 0.50E+03, 0.10E+11, 0.10E+11, 0.50E+03, & - 0.10E+11, 0.10E+11, 0.50E+03, 0.50E+03, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.12E+03, 0.10E+11, & - 0.10E+11, 0.70E+02, 0.25E+03, 0.50E+03, 0.10E+11, 0.10E+11, & - 0.50E+03, 0.10E+11, 0.10E+11, 0.50E+03, 0.50E+03, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.70E+02, 0.40E+03, 0.80E+03, 0.10E+11, & - 0.10E+11, 0.80E+03, 0.10E+11, 0.10E+11, 0.80E+03, 0.80E+03, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.12E+03, 0.12E+03, & - 0.12E+03, 0.12E+03, 0.14E+03, 0.24E+03, 0.24E+03, 0.24E+03, & - 0.12E+03, 0.14E+03, 0.25E+03, 0.70E+02, 0.25E+03, 0.19E+03, & - 0.10E+11, 0.16E+03, 0.19E+03, 0.10E+11, 0.16E+03, 0.19E+03, & - 0.19E+03, 0.10E+11, 0.10E+11, 0.10E+11/ -! .. - IF (nlu/=25) THEN - errmsg='number of land use classifications not correct ' - errflg=1 - return - END IF - IF (dep_seasons/=5) THEN - errmsg='number of dep_seasons not correct ' - errflg=1 - return - END IF - -! SURFACE RESISTANCE DATA FOR DEPOSITION MODEL OF -! M. L. WESELY, ATMOSPHERIC ENVIRONMENT 23 (1989) 1293-1304 - -! Seasonal categories: -! 1: midsummer with lush vegetation -! 2: autumn with unharvested cropland -! 3: late autumn with frost, no snow -! 4: winter, snow on ground and subfreezing -! 5: transitional spring with partially green short annuals - -! Land use types: -! USGS type Wesely type -! 1: Urban and built-up land 1 -! 2: Dryland cropland and pasture 2 -! 3: Irrigated cropland and pasture 2 -! 4: Mix. dry/irrg. cropland and pasture 2 -! 5: Cropland/grassland mosaic 2 -! 6: Cropland/woodland mosaic 4 -! 7: Grassland 3 -! 8: Shrubland 3 -! 9: Mixed shrubland/grassland 3 -! 10: Savanna 3, always summer -! 11: Deciduous broadleaf forest 4 -! 12: Deciduous needleleaf forest 5, autumn and winter modi -! 13: Evergreen broadleaf forest 4, always summer -! 14: Evergreen needleleaf forest 5 -! 15: Mixed Forest 6 -! 16: Water Bodies 7 -! 17: Herbaceous wetland 9 -! 18: Wooded wetland 6 -! 19: Barren or sparsely vegetated 8 -! 20: Herbaceous Tundra 9 -! 21: Wooded Tundra 6 -! 22: Mixed Tundra 6 -! 23: Bare Ground Tundra 8 -! 24: Snow or Ice -, always winter -! 25: No data 8 - - -! Order of data: -! | -! | seasonal category -! \|/ -! ---> landuse type -! 1 2 3 4 5 6 7 8 9 -! THIS%RLU for outer surfaces in the upper canopy - DO iseason = 1, dep_seasons - this%ri(1:nlu,iseason) = dat1(1:nlu,iseason) - END DO -! data ((this%rlu(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.10E+11, & - DATA ((dat2(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.10E+11, & - 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.10E+11, 0.25E+04, 0.20E+04, 0.10E+11, & - 0.25E+04, 0.20E+04, 0.20E+04, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, & - 0.90E+04, 0.90E+04, 0.90E+04, 0.20E+04, 0.90E+04, 0.90E+04, & - 0.20E+04, 0.40E+04, 0.80E+04, 0.10E+11, 0.90E+04, 0.80E+04, & - 0.10E+11, 0.90E+04, 0.80E+04, 0.80E+04, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, & - 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, 0.20E+04, 0.90E+04, & - 0.90E+04, 0.20E+04, 0.40E+04, 0.80E+04, 0.10E+11, 0.90E+04, & - 0.80E+04, 0.10E+11, 0.90E+04, 0.80E+04, 0.80E+04, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.20E+04, 0.60E+04, 0.90E+04, 0.10E+11, & - 0.90E+04, 0.90E+04, 0.10E+11, 0.90E+04, 0.90E+04, 0.90E+04, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.40E+04, 0.40E+04, & - 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, & - 0.20E+04, 0.40E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.30E+04, & - 0.10E+11, 0.40E+04, 0.30E+04, 0.10E+11, 0.40E+04, 0.30E+04, & - 0.30E+04, 0.10E+11, 0.10E+11, 0.10E+11/ - DO iseason = 1, dep_seasons - this%rlu(1:nlu,iseason) = dat2(1:nlu,iseason) - END DO -! THIS%RAC for transfer that depends on canopy height and density -! data ((this%rac(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.10E+03, & - DATA ((dat3(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.10E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+04, 0.10E+03, & - 0.10E+03, 0.10E+03, 0.10E+03, 0.20E+04, 0.20E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.00E+00, 0.30E+03, 0.20E+04, 0.00E+00, & - 0.30E+03, 0.20E+04, 0.20E+04, 0.00E+00, 0.00E+00, 0.00E+00, & - 0.10E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+04, & - 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, 0.15E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.17E+04, 0.00E+00, 0.20E+03, 0.17E+04, & - 0.00E+00, 0.20E+03, 0.17E+04, 0.17E+04, 0.00E+00, 0.00E+00, & - 0.00E+00, 0.10E+03, 0.10E+02, 0.10E+02, 0.10E+02, 0.10E+02, & - 0.10E+04, 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+04, & - 0.20E+04, 0.20E+04, 0.20E+04, 0.15E+04, 0.00E+00, 0.10E+03, & - 0.15E+04, 0.00E+00, 0.10E+03, 0.15E+04, 0.15E+04, 0.00E+00, & - 0.00E+00, 0.00E+00, 0.10E+03, 0.10E+02, 0.10E+02, 0.10E+02, & - 0.10E+02, 0.10E+04, 0.10E+02, 0.10E+02, 0.10E+02, 0.10E+02, & - 0.10E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.15E+04, 0.00E+00, & - 0.50E+02, 0.15E+04, 0.00E+00, 0.50E+02, 0.15E+04, 0.15E+04, & - 0.00E+00, 0.00E+00, 0.00E+00, 0.10E+03, 0.50E+02, 0.50E+02, & - 0.50E+02, 0.50E+02, 0.12E+04, 0.80E+02, 0.80E+02, 0.80E+02, & - 0.10E+03, 0.12E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.15E+04, & - 0.00E+00, 0.20E+03, 0.15E+04, 0.00E+00, 0.20E+03, 0.15E+04, & - 0.15E+04, 0.00E+00, 0.00E+00, 0.00E+00/ - DO iseason = 1, dep_seasons - this%rac(1:nlu,iseason) = dat3(1:nlu,iseason) - END DO -! THIS%RGSS for ground surface SO2 -! data ((this%rgss(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.40E+03, & - DATA ((dat4(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.40E+03, & - 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.50E+03, 0.35E+03, & - 0.35E+03, 0.35E+03, 0.35E+03, 0.50E+03, 0.50E+03, 0.50E+03, & - 0.50E+03, 0.10E+03, 0.10E+01, 0.10E+01, 0.10E+03, 0.10E+04, & - 0.10E+01, 0.10E+03, 0.10E+03, 0.10E+04, 0.10E+03, 0.10E+04, & - 0.40E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.50E+03, & - 0.35E+03, 0.35E+03, 0.35E+03, 0.35E+03, 0.50E+03, 0.50E+03, & - 0.50E+03, 0.50E+03, 0.10E+03, 0.10E+01, 0.10E+01, 0.10E+03, & - 0.10E+04, 0.10E+01, 0.10E+03, 0.10E+03, 0.10E+04, 0.10E+03, & - 0.10E+04, 0.40E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, & - 0.50E+03, 0.35E+03, 0.35E+03, 0.35E+03, 0.35E+03, 0.50E+03, & - 0.50E+03, 0.50E+03, 0.50E+03, 0.20E+03, 0.10E+01, 0.10E+01, & - 0.20E+03, 0.10E+04, 0.10E+01, 0.20E+03, 0.20E+03, 0.10E+04, & - 0.10E+03, 0.10E+04, 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, & - 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, 0.10E+03, & - 0.10E+03, 0.10E+03, 0.50E+03, 0.10E+03, 0.10E+03, 0.10E+01, & - 0.10E+03, 0.10E+03, 0.10E+04, 0.10E+03, 0.10E+03, 0.10E+03, & - 0.10E+04, 0.10E+03, 0.10E+04, 0.50E+03, 0.15E+03, 0.15E+03, & - 0.15E+03, 0.15E+03, 0.50E+03, 0.35E+03, 0.35E+03, 0.35E+03, & - 0.35E+03, 0.50E+03, 0.50E+03, 0.50E+03, 0.50E+03, 0.20E+03, & - 0.10E+01, 0.10E+01, 0.20E+03, 0.10E+04, 0.10E+01, 0.20E+03, & - 0.20E+03, 0.10E+04, 0.10E+03, 0.10E+04/ - DO iseason = 1, dep_seasons - this%rgss(1:nlu,iseason) = dat4(1:nlu,iseason) - END DO -! THIS%RGSO for ground surface O3 -! data ((this%rgso(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.30E+03, & - DATA ((dat5(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.30E+03, & - 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.20E+03, 0.20E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, & - 0.20E+03, 0.30E+03, 0.20E+04, 0.10E+04, 0.30E+03, 0.40E+03, & - 0.10E+04, 0.30E+03, 0.30E+03, 0.40E+03, 0.35E+04, 0.40E+03, & - 0.30E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.20E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, & - 0.20E+03, 0.20E+03, 0.30E+03, 0.20E+04, 0.80E+03, 0.30E+03, & - 0.40E+03, 0.80E+03, 0.30E+03, 0.30E+03, 0.40E+03, 0.35E+04, & - 0.40E+03, 0.30E+03, 0.15E+03, 0.15E+03, 0.15E+03, 0.15E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.30E+03, 0.20E+04, 0.10E+04, & - 0.30E+03, 0.40E+03, 0.10E+04, 0.30E+03, 0.30E+03, 0.40E+03, & - 0.35E+04, 0.40E+03, 0.60E+03, 0.35E+04, 0.35E+04, 0.35E+04, & - 0.35E+04, 0.35E+04, 0.35E+04, 0.35E+04, 0.35E+04, 0.35E+04, & - 0.35E+04, 0.35E+04, 0.20E+03, 0.35E+04, 0.35E+04, 0.20E+04, & - 0.35E+04, 0.35E+04, 0.40E+03, 0.35E+04, 0.35E+04, 0.35E+04, & - 0.40E+03, 0.35E+04, 0.40E+03, 0.30E+03, 0.15E+03, 0.15E+03, & - 0.15E+03, 0.15E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, & - 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.20E+03, 0.30E+03, & - 0.20E+04, 0.10E+04, 0.30E+03, 0.40E+03, 0.10E+04, 0.30E+03, & - 0.30E+03, 0.40E+03, 0.35E+04, 0.40E+03/ - DO iseason = 1, dep_seasons - this%rgso(1:nlu,iseason) = dat5(1:nlu,iseason) - END DO -! THIS%RCLS for exposed surfaces in the lower canopy SO2 -! data ((this%rcls(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.10E+11, & - DATA ((dat6(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.10E+11, & - 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.20E+04, & - 0.20E+04, 0.20E+04, 0.10E+11, 0.25E+04, 0.20E+04, 0.10E+11, & - 0.25E+04, 0.20E+04, 0.20E+04, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, & - 0.90E+04, 0.90E+04, 0.90E+04, 0.20E+04, 0.90E+04, 0.90E+04, & - 0.20E+04, 0.20E+04, 0.40E+04, 0.10E+11, 0.90E+04, 0.40E+04, & - 0.10E+11, 0.90E+04, 0.40E+04, 0.40E+04, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.90E+04, 0.90E+04, 0.90E+04, 0.90E+04, 0.20E+04, 0.90E+04, & - 0.90E+04, 0.20E+04, 0.30E+04, 0.60E+04, 0.10E+11, 0.90E+04, & - 0.60E+04, 0.10E+11, 0.90E+04, 0.60E+04, 0.60E+04, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.90E+04, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.90E+04, 0.90E+04, 0.20E+04, 0.20E+03, 0.40E+03, 0.10E+11, & - 0.90E+04, 0.40E+03, 0.10E+11, 0.90E+04, 0.40E+03, 0.40E+03, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.40E+04, 0.40E+04, & - 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, 0.40E+04, & - 0.20E+04, 0.40E+04, 0.20E+04, 0.20E+04, 0.20E+04, 0.30E+04, & - 0.10E+11, 0.40E+04, 0.30E+04, 0.10E+11, 0.40E+04, 0.30E+04, & - 0.30E+04, 0.10E+11, 0.10E+11, 0.10E+11/ - DO iseason = 1, dep_seasons - this%rcls(1:nlu,iseason) = dat6(1:nlu,iseason) - END DO -! THIS%RCLO for exposed surfaces in the lower canopy O3 -! data ((this%rclo(ILAND,ISEASON),ILAND=1,25),ISEASON=1,5)/0.10E+11, & - DATA ((dat7(iland,iseason),iland=1,nlu),iseason=1,dep_seasons)/0.10E+11, & - 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, & - 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, & - 0.10E+04, 0.10E+04, 0.10E+11, 0.10E+04, 0.10E+04, 0.10E+11, & - 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+11, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.40E+03, 0.40E+03, 0.40E+03, 0.40E+03, 0.40E+03, & - 0.40E+03, 0.40E+03, 0.40E+03, 0.10E+04, 0.40E+03, 0.40E+03, & - 0.10E+04, 0.10E+04, 0.60E+03, 0.10E+11, 0.40E+03, 0.60E+03, & - 0.10E+11, 0.40E+03, 0.60E+03, 0.60E+03, 0.10E+11, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, & - 0.40E+03, 0.40E+03, 0.40E+03, 0.40E+03, 0.10E+04, 0.40E+03, & - 0.40E+03, 0.10E+04, 0.10E+04, 0.60E+03, 0.10E+11, 0.80E+03, & - 0.60E+03, 0.10E+11, 0.80E+03, 0.60E+03, 0.60E+03, 0.10E+11, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+04, 0.10E+04, 0.10E+04, & - 0.10E+04, 0.40E+03, 0.10E+04, 0.10E+04, 0.10E+04, 0.10E+04, & - 0.40E+03, 0.40E+03, 0.10E+04, 0.15E+04, 0.60E+03, 0.10E+11, & - 0.80E+03, 0.60E+03, 0.10E+11, 0.80E+03, 0.60E+03, 0.60E+03, & - 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+11, 0.10E+04, 0.10E+04, & - 0.10E+04, 0.10E+04, 0.50E+03, 0.50E+03, 0.50E+03, 0.50E+03, & - 0.10E+04, 0.50E+03, 0.15E+04, 0.10E+04, 0.15E+04, 0.70E+03, & - 0.10E+11, 0.60E+03, 0.70E+03, 0.10E+11, 0.60E+03, 0.70E+03, & - 0.70E+03, 0.10E+11, 0.10E+11, 0.10E+11/ - - DO iseason = 1, dep_seasons - this%rclo(1:nlu,iseason) = dat7(1:nlu,iseason) - END DO - - ! data ((dat8(iseason,iland),iseason=1,pan_seasons),iland=1,pan_lands) / & - ! 1.e36, 60., 120., 70., 130., 100.,1.e36,1.e36, 80., 100., 150., & - ! 1.e36,1.e36,1.e36,1.e36, 250., 500.,1.e36,1.e36,1.e36,1.e36,1.e36, & - ! 1.e36,1.e36,1.e36,1.e36, 250., 500.,1.e36,1.e36,1.e36,1.e36,1.e36, & - ! 1.e36,1.e36,1.e36,1.e36, 400., 800.,1.e36,1.e36,1.e36,1.e36,1.e36, & - ! 1.e36, 120., 240., 140., 250., 190.,1.e36,1.e36, 160., 200., 300. / - ! this%ri_pan(:,:) = dat8(:,:) - -!-------------------------------------------------- -! Initialize parameters -!-------------------------------------------------- - this%hstar = 0. - this%hstar4 = 0. - this%dhr = 0. - this%f0 = 0. - this%dratio = 1.0 ! FIXME: IS THIS RIGHT? - this%scpr23 = 1.0 ! FIXME: IS THIS RIGHT? - -!-------------------------------------------------- -! HENRY''S LAW COEFFICIENTS -! Effective Henry''s law coefficient at pH 7 -! [KH298]=mole/(l atm) -!-------------------------------------------------- - -! DATA FOR AEROSOL PARTICLE DEPOSITION FOR THE MODEL OF -! J. W. ERISMAN, A. VAN PUL AND P. WYERS -! ATMOSPHERIC ENVIRONMENT 28 (1994), 2595-2607 - -! vd = (u* / k) * CORRECTION FACTORS - -! CONSTANT K FOR LANDUSE TYPES: -! urban and built-up land - this%kpart(1) = 500. -! dryland cropland and pasture - this%kpart(2) = 500. -! irrigated cropland and pasture - this%kpart(3) = 500. -! mixed dryland/irrigated cropland and past - this%kpart(4) = 500. -! cropland/grassland mosaic - this%kpart(5) = 500. -! cropland/woodland mosaic - this%kpart(6) = 100. -! grassland - this%kpart(7) = 500. -! shrubland - this%kpart(8) = 500. -! mixed shrubland/grassland - this%kpart(9) = 500. -! savanna - this%kpart(10) = 500. -! deciduous broadleaf forest - this%kpart(11) = 100. -! deciduous needleleaf forest - this%kpart(12) = 100. -! evergreen broadleaf forest - this%kpart(13) = 100. -! evergreen needleleaf forest - this%kpart(14) = 100. -! mixed forest - this%kpart(15) = 100. -! water bodies - this%kpart(16) = 500. -! herbaceous wetland - this%kpart(17) = 500. -! wooded wetland - this%kpart(18) = 500. -! barren or sparsely vegetated - this%kpart(19) = 500. -! herbaceous tundra - this%kpart(20) = 500. -! wooded tundra - this%kpart(21) = 100. -! mixed tundra - this%kpart(22) = 500. -! bare ground tundra - this%kpart(23) = 500. -! snow or ice - this%kpart(24) = 500. -! Comments: - this%kpart(25) = 500. -! Erisman et al. (1994) give -! k = 500 for low vegetation and k = 100 for forests. - -! For desert k = 500 is taken according to measurements -! on bare soil by -! J. Fontan, A. Lopez, E. Lamaud and A. Druilhet (1997) -! Vertical Flux Measurements of the Submicronic Aerosol Particles -! and Parametrisation of the Dry Deposition Velocity -! in: Biosphere-Atmosphere Exchange of Pollutants -! and Trace Substances -! Editor: S. Slanina. Springer-Verlag Berlin, Heidelberg, 1997 -! pp. 381-390 - -! For coniferous forest the Erisman value of k = 100 is taken. -! Measurements of Erisman et al. (1997) in a coniferous forest -! in the Netherlands, lead to values of k between 20 and 38 -! (Atmospheric Environment 31 (1997), 321-332). -! However, these high values of vd may be reached during -! instable cases. The eddy correlation measurements -! of Gallagher et al. (1997) made during the same experiment -! show for stable cases (L>0) values of k between 200 and 250 -! at minimum (Atmospheric Environment 31 (1997), 359-373). -! Fontan et al. (1997) found k = 250 in a forest -! of maritime pine in southwestern France. - -! For gras, model calculations of Davidson et al. support -! the value of 500. -! C. I. Davidson, J. M. Miller and M. A. Pleskov -! The Influence of Surface Structure on Predicted Particles -! Dry Deposition to Natural Gras Canopies -! Water, Air, and Soil Pollution 18 (1982) 25-43 - -! Snow covered surface: The experiment of Ibrahim et al. (1983) -! gives k = 436 for 0.7 um diameter particles. -! The deposition velocity of Milford and Davidson (1987) -! gives k = 154 for continental sulfate aerosol. -! M. Ibrahim, L. A. Barrie and F. Fanaki -! Atmospheric Environment 17 (1983), 781-788 - -! J. B. Milford and C. I. Davidson -! The Sizes of Particulate Sulfate and Nitrate in the Atmosphere -! - A Review -! JAPCA 37 (1987), 125-134 -! no data -! WRITE (0,*) ' return from rcread ' -! ********************************************************* - -! Simplified landuse scheme for deposition and biogenic emission -! subroutines -! (ISWATER and ISICE are already defined elsewhere, -! therefore water and ice are not considered here) - -! 1 urban or bare soil -! 2 agricultural -! 3 grassland -! 4 deciduous forest -! 5 coniferous and mixed forest -! 6 other natural landuse categories - - - IF (mminlu=='OLD ') THEN - this%ixxxlu(1) = 1 - this%ixxxlu(2) = 2 - this%ixxxlu(3) = 3 - this%ixxxlu(4) = 4 - this%ixxxlu(5) = 5 - this%ixxxlu(6) = 5 - this%ixxxlu(7) = 0 - this%ixxxlu(8) = 6 - this%ixxxlu(9) = 1 - this%ixxxlu(10) = 6 - this%ixxxlu(11) = 0 - this%ixxxlu(12) = 4 - this%ixxxlu(13) = 6 - END IF - IF (mminlu=='USGS') THEN - this%ixxxlu(1) = 1 - this%ixxxlu(2) = 2 - this%ixxxlu(3) = 2 - this%ixxxlu(4) = 2 - this%ixxxlu(5) = 2 - this%ixxxlu(6) = 4 - this%ixxxlu(7) = 3 - this%ixxxlu(8) = 6 - this%ixxxlu(9) = 3 - this%ixxxlu(10) = 6 - this%ixxxlu(11) = 4 - this%ixxxlu(12) = 5 - this%ixxxlu(13) = 4 - this%ixxxlu(14) = 5 - this%ixxxlu(15) = 5 - this%ixxxlu(16) = 0 - this%ixxxlu(17) = 6 - this%ixxxlu(18) = 4 - this%ixxxlu(19) = 1 - this%ixxxlu(20) = 6 - this%ixxxlu(21) = 4 - this%ixxxlu(22) = 6 - this%ixxxlu(23) = 1 - this%ixxxlu(24) = 0 - this%ixxxlu(25) = 1 - END IF - IF (mminlu=='SiB ') THEN - this%ixxxlu(1) = 4 - this%ixxxlu(2) = 4 - this%ixxxlu(3) = 4 - this%ixxxlu(4) = 5 - this%ixxxlu(5) = 5 - this%ixxxlu(6) = 6 - this%ixxxlu(7) = 3 - this%ixxxlu(8) = 6 - this%ixxxlu(9) = 6 - this%ixxxlu(10) = 6 - this%ixxxlu(11) = 1 - this%ixxxlu(12) = 2 - this%ixxxlu(13) = 6 - this%ixxxlu(14) = 1 - this%ixxxlu(15) = 0 - this%ixxxlu(16) = 0 - this%ixxxlu(17) = 1 - END IF - - END SUBROUTINE dep_init -end module rrfs_smoke_data diff --git a/smoke/rrfs_smoke_lsdep_wrapper.F90 b/smoke/rrfs_smoke_lsdep_wrapper.F90 deleted file mode 100644 index 1fd7a2d3f..000000000 --- a/smoke/rrfs_smoke_lsdep_wrapper.F90 +++ /dev/null @@ -1,323 +0,0 @@ -!>\file rrfs_smoke_lsdep_wrapper.F90 -!! This file is RRFS-smoke large-scale wet deposition wrapper with CCPP -!! Haiqin.Li@noaa.gov 04/2021 - - module rrfs_smoke_lsdep_wrapper - - use machine , only : kind_phys - use rrfs_smoke_config - use dep_wet_ls_mod - use dust_data_mod - use rrfs_smoke_data - - implicit none - - private - - public :: rrfs_smoke_lsdep_wrapper_run - -contains - -!>\defgroup rrfs_smoke_lsdep_wrapper GSD Chem driver Module -!> \ingroup gsd_chem_group -!! This is the GSD Chem driver Module -!! \section arg_table_rrfs_smoke_lsdep_wrapper_run Argument Table -!! \htmlinclude rrfs_smoke_lsdep_wrapper_run.html -!! -!>\section rrfs_smoke_lsdep_wrapper GSD Chemistry Scheme General Algorithm -!> @{ - subroutine rrfs_smoke_lsdep_wrapper_run(im, kte, kme, ktau, dt, & - rain_cpl, rainc_cpl, g, & - pr3d, ph3d,phl3d, prl3d, tk3d, us3d, vs3d, spechum, & - w, dqdt, ntrac,ntsmoke,ntdust, & - gq0,qgrs,wetdep_ls_opt_in, & - errmsg,errflg) - - implicit none - - - integer, intent(in) :: im,kte,kme,ktau - integer, intent(in) :: ntrac,ntsmoke,ntdust - real(kind_phys),intent(in) :: dt,g - - integer, parameter :: ids=1,jds=1,jde=1, kds=1 - integer, parameter :: ims=1,jms=1,jme=1, kms=1 - integer, parameter :: its=1,jts=1,jte=1, kts=1 - - real(kind_phys), dimension(:), intent(in) :: rain_cpl, rainc_cpl - real(kind_phys), dimension(:,:), intent(in) :: ph3d, pr3d - real(kind_phys), dimension(:,:), intent(in) :: phl3d, prl3d, tk3d, & - us3d, vs3d, spechum, w, dqdt - real(kind_phys), dimension(:,:,:), intent(inout) :: gq0, qgrs - integer, intent(in) :: wetdep_ls_opt_in - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - - real(kind_phys), dimension(1:im, 1:kme,jms:jme) :: rri, t_phy, u_phy, v_phy, & - p_phy, z_at_w, dz8w, p8w, t8w, rho_phy, vvel, dqdti - - real(kind_phys), dimension(ims:im, jms:jme) :: rcav, rnav - -!>- vapor & chemistry variables - real(kind_phys), dimension(ims:im, kms:kme, jms:jme, 1:num_moist) :: moist - real(kind_phys), dimension(ims:im, kms:kme, jms:jme, 1:num_chem ) :: chem - real(kind_phys), dimension(ims:im, jms:jme, 1:num_chem ) :: var_rmv - - integer :: ide, ime, ite, kde - - real(kind_phys) :: dtstep - real(kind_phys), dimension(1:num_chem) :: ppm2ugkg - - type(smoke_data), pointer :: data - -!>-- local variables - integer :: i, j, jp, k, kp, n - - data=>get_thread_smoke_data() - - errmsg = '' - errflg = 0 - - wetdep_ls_opt = wetdep_ls_opt_in - !print*,'hli wetdep_ls_opt',wetdep_ls_opt - - ! -- set domain - ide=im - ime=im - ite=im - kde=kte - - ! -- volume to mass fraction conversion table (ppm -> ug/kg) - ppm2ugkg = 1._kind_phys - !ppm2ugkg(p_so2 ) = 1.e+03_kind_phys * mw_so2_aer / mwdry - ppm2ugkg(p_sulf) = 1.e+03_kind_phys * mw_so4_aer / mwdry - - ! -- initialize large-sacle wet depostion - if (ktau==1) then - call dep_wet_ls_init(data) - endif - - ! -- set control flags - - ! -- compute accumulated large-scale and convective rainfall since last call - if (ktau > 1) then - dtstep = call_chemistry * dt - else - dtstep = dt - end if - - ! -- compute incremental convective and large-scale rainfall - do i=its,ite - rcav(i,1)=max(rainc_cpl(i)*1000. , 0.) ! meter to mm - rnav(i,1)=max((rain_cpl(i)-rainc_cpl(i))*1000., 0.) ! meter to mm - enddo - -!!! - -!>- get ready for chemistry run - call rrfs_smoke_prep_lsdep(data,ktau,dtstep, & - pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,w, dqdt, & - rri,t_phy,u_phy,v_phy,p_phy,rho_phy,dz8w,p8w, & - t8w,dqdti,z_at_w,vvel,g, & - ntsmoke,ntdust, & - ntrac,gq0,num_chem, num_moist, & - ppm2ugkg,moist,chem, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) - - ! -- ls wet deposition - select case (wetdep_ls_opt) - case (WDLS_OPT_GSD) - call wetdep_ls(data,dt,chem,rnav,moist,rho_phy,var_rmv, & - num_moist,num_chem,p_qc,p_qi,dz8w,vvel, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) - case (WDLS_OPT_NGAC) - call WetRemovalGOCART(data,its,ite, jts,jte, kts,kte, 1,1, dt, & - num_chem,var_rmv,chem,p_phy,t_phy, & - rho_phy,dqdti,rcav,rnav, g, & - ims,ime, jms,jme, kms,kme) - !if (chem_rc_check(localrc, msg="Failure in NGAC wet removal scheme", & - ! file=__FILE__, line=__LINE__, rc=rc)) return - case default - ! -- no further option implemented - end select - - - ! -- put chem stuff back into tracer array - do k=kts,kte - do i=its,ite - gq0(i,k,ntsmoke)=ppm2ugkg(p_oc1 ) * max(epsilc,chem(i,k,1,p_oc1)) - gq0(i,k,ntdust )=ppm2ugkg(p_dust_1) * max(epsilc,chem(i,k,1,p_dust_1)) - enddo - enddo - - do k=kts,kte - do i=its,ite - qgrs(i,k,ntsmoke)=gq0(i,k,ntsmoke) - qgrs(i,k,ntdust )=gq0(i,k,ntdust ) - enddo - enddo - - -! - end subroutine rrfs_smoke_lsdep_wrapper_run -!> @} - - subroutine rrfs_smoke_prep_lsdep(data,ktau,dtstep, & - pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,w,dqdt, & - rri,t_phy,u_phy,v_phy,p_phy,rho_phy,dz8w,p8w, & - t8w,dqdti,z_at_w,vvel,g, & - ntsmoke,ntdust, & - ntrac,gq0,num_chem, num_moist, & - ppm2ugkg,moist,chem, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) - implicit none - type(smoke_data), intent(inout) :: data - - !Chem input configuration - integer, intent(in) :: ktau - real(kind=kind_phys), intent(in) :: dtstep,g - - !FV3 input variables - integer, intent(in) :: ntrac,ntsmoke,ntdust - real(kind=kind_phys), dimension(ims:ime, kms:kme), intent(in) :: pr3d,ph3d - real(kind=kind_phys), dimension(ims:ime, kts:kte), intent(in) :: & - phl3d,tk3d,prl3d,us3d,vs3d,spechum,w,dqdt - real(kind=kind_phys), dimension(ims:ime, kts:kte,ntrac), intent(in) :: gq0 - - - !GSD Chem variables - integer,intent(in) :: num_chem, num_moist - integer,intent(in) :: ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte - - real(kind_phys), dimension(num_chem), intent(in) :: ppm2ugkg - - real(kind_phys), dimension(ims:ime, kms:kme, jms:jme), intent(out) :: & - rri, t_phy, u_phy, v_phy, p_phy, rho_phy, dz8w, p8w, t8w, vvel, dqdti - real(kind_phys), dimension(ims:ime, kms:kme, jms:jme, num_moist), intent(out) :: moist - real(kind_phys), dimension(ims:ime, kms:kme, jms:jme, num_chem), intent(out) :: chem - - real(kind_phys), dimension(ims:ime, kms:kme, jms:jme), intent(out) :: z_at_w - - ! -- local variables -! real(kind=kind_phys), dimension(ims:ime, kms:kme, jms:jme) :: p_phy - real(kind_phys) :: factor,factor2,pu,pl,aln,pwant - real(kind_phys) :: xhour,xmin,xlonn,xtime,real_time - real(kind_phys), DIMENSION (1,1) :: sza,cosszax - integer i,ip,j,jp,k,kp,kk,kkp,nv,jmax,jmaxi,l,ll,n,ndystep,ixhour - - ! -- initialize output arrays - rri = 0._kind_phys - t_phy = 0._kind_phys - u_phy = 0._kind_phys - v_phy = 0._kind_phys - p_phy = 0._kind_phys - rho_phy = 0._kind_phys - dz8w = 0._kind_phys - p8w = 0._kind_phys - t8w = 0._kind_phys - vvel = 0._kind_phys - dqdti = 0._kind_phys - moist = 0._kind_phys - chem = 0._kind_phys - z_at_w = 0._kind_phys - - - do j=jts,jte - jp = j - jts + 1 - do i=its,ite - ip = i - its + 1 - z_at_w(i,kts,j)=max(0.,ph3d(ip,1)/g) - enddo - enddo - - do j=jts,jte - jp = j - jts + 1 - do k=kts,kte - kp = k - kts + 1 - do i=its,ite - ip = i - its + 1 - dz8w(i,k,j)=abs(ph3d(ip,kp+1)-ph3d(ip,kp))/g - z_at_w(i,k+1,j)=z_at_w(i,k,j)+dz8w(i,k,j) - enddo - enddo - enddo - - do j=jts,jte - jp = j - jts + 1 - do k=kts,kte+1 - kp = k - kts + 1 - do i=its,ite - ip = i - its + 1 - p8w(i,k,j)=pr3d(ip,kp) - enddo - enddo - enddo - - do j=jts,jte - jp = j - jts + 1 - do k=kts,kte+1 - kk=min(k,kte) - kkp = kk - kts + 1 - do i=its,ite - ip = i - its + 1 - dz8w(i,k,j)=z_at_w(i,kk+1,j)-z_at_w(i,kk,j) - t_phy(i,k,j)=tk3d(ip,kkp) - p_phy(i,k,j)=prl3d(ip,kkp) - u_phy(i,k,j)=us3d(ip,kkp) - dqdti(i,k,j)=dqdt(ip,kkp) - v_phy(i,k,j)=vs3d(ip,kkp) - rho_phy(i,k,j)=p_phy(i,k,j)/(287.04*t_phy(i,k,j)*(1.+.608*spechum(ip,kkp))) - rri(i,k,j)=1./rho_phy(i,k,j) - vvel(i,k,j)=-w(ip,kkp)*rri(i,k,j)/g - moist(i,k,j,:)=0. - moist(i,k,j,1)=gq0(ip,kkp,p_atm_shum) - if (t_phy(i,k,j) > 265.) then - moist(i,k,j,2)=gq0(ip,kkp,p_atm_cldq) - moist(i,k,j,3)=0. - if (moist(i,k,j,2) < 1.e-8) moist(i,k,j,2)=0. - else - moist(i,k,j,2)=0. - moist(i,k,j,3)=gq0(ip,kkp,p_atm_cldq) - if(moist(i,k,j,3) < 1.e-8)moist(i,k,j,3)=0. - endif - !-- - enddo - enddo - enddo - - do j=jts,jte - do k=2,kte - do i=its,ite - t8w(i,k,j)=.5*(t_phy(i,k,j)+t_phy(i,k-1,j)) - enddo - enddo - enddo - - ! -- only used in phtolysis.... - do j=jts,jte - do i=its,ite - t8w(i,1,j)=t_phy(i,1,j) - t8w(i,kte+1,j)=t_phy(i,kte,j) - enddo - enddo - - - do k=kms,kte - do i=ims,ime - chem(i,k,jts,p_oc1 )=max(epsilc,gq0(i,k,ntsmoke)/ppm2ugkg(p_oc1)) - chem(i,k,jts,p_dust_1)=max(epsilc,gq0(i,k,ntdust )/ppm2ugkg(p_dust_1)) - enddo - enddo - - - end subroutine rrfs_smoke_prep_lsdep -!> @} - end module rrfs_smoke_lsdep_wrapper diff --git a/smoke/rrfs_smoke_lsdep_wrapper.meta b/smoke/rrfs_smoke_lsdep_wrapper.meta deleted file mode 100755 index 23c71fce8..000000000 --- a/smoke/rrfs_smoke_lsdep_wrapper.meta +++ /dev/null @@ -1,208 +0,0 @@ -[ccpp-table-properties] - name = rrfs_smoke_lsdep_wrapper - type = scheme - dependencies = dep_dry_gocart_mod.F90,dep_dry_mod.F90,dep_simple_mod.F90,dep_vertmx_mod.F90,dep_wet_ls_mod.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,rrfs_smoke_data.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90 - -######################################################################## -[ccpp-arg-table] - name = rrfs_smoke_lsdep_wrapper_run - type = scheme -[im] - standard_name = horizontal_loop_extent - long_name = horizontal loop extent - units = count - dimensions = () - type = integer - intent = in -[kte] - standard_name = vertical_layer_dimension - long_name = number of vertical levels - units = count - dimensions = () - type = integer - intent = in -[kme] - standard_name = vertical_interface_dimension - long_name = number of vertical levels plus one - units = count - dimensions = () - type = integer - intent = in -[ktau] - standard_name = index_of_timestep - long_name = current forecast iteration - units = index - dimensions = () - type = integer - intent = in -[dt] - standard_name = timestep_for_physics - long_name = physics time step - units = s - dimensions = () - type = real - kind = kind_phys - intent = in -[rain_cpl] - standard_name = lwe_thickness_of_precipitation_amount_on_dynamics_timestep - long_name = total rain at this time step - units = m - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[rainc_cpl] - standard_name = lwe_thickness_of_convective_precipitation_amount_on_dynamics_timestep - long_name = convective rain at this time step - units = m - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = in -[g] - standard_name = gravitational_acceleration - long_name = gravitational acceleration - units = m s-2 - dimensions = () - type = real - kind = kind_phys - intent = in -[pr3d] - standard_name = air_pressure_at_interface - long_name = air pressure at model layer interfaces - units = Pa - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[ph3d] - standard_name = geopotential_at_interface - long_name = geopotential at model layer interfaces - units = m2 s-2 - dimensions = (horizontal_loop_extent,vertical_interface_dimension) - type = real - kind = kind_phys - intent = in -[phl3d] - standard_name = geopotential - long_name = geopotential at model layer centers - units = m2 s-2 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[prl3d] - standard_name = air_pressure - long_name = mean layer pressure - units = Pa - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[tk3d] - standard_name = air_temperature_of_new_state - long_name = updated temperature - units = K - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[us3d] - standard_name = x_wind_of_new_state - long_name = updated x-direction wind - units = m s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[vs3d] - standard_name = y_wind_of_new_state - long_name = updated y-direction wind - units = m s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[spechum] - standard_name = specific_humidity_of_new_state - long_name = water vapor specific humidity updated by physics - units = kg kg-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = inout -[w] - standard_name = lagrangian_tendency_of_air_pressure - long_name = layer mean vertical velocity - units = Pa s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[dqdt] - standard_name = instantaneous_water_vapor_specific_humidity_tendency_due_to_convection - long_name = instantaneous moisture tendency due to convection - units = kg kg-1 s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in -[ntrac] - standard_name = number_of_tracers - long_name = number of tracers - units = count - dimensions = () - type = integer - intent = in -[ntsmoke] - standard_name = index_for_smoke_in_tracer_concentration_array - long_name = tracer index for smoke - units = index - dimensions = () - type = integer - intent = in -[ntdust] - standard_name = index_for_dust_in_tracer_concentration_array - long_name = tracer index for dust - units = index - dimensions = () - type = integer - intent = in -[gq0] - standard_name = tracer_concentration_of_new_state - long_name = tracer concentration updated by physics - units = kg kg-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) - type = real - kind = kind_phys - intent = inout -[qgrs] - standard_name = tracer_concentration - long_name = model layer mean tracer concentration - units = kg kg-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) - type = real - kind = kind_phys - intent = inout -[wetdep_ls_opt_in] - standard_name = control_for_smoke_wet_deposition - long_name = rrfs smoke large scale wet deposition option - units = index - dimensions = () - type = integer - intent = in -[errmsg] - standard_name = ccpp_error_message - long_name = error message for error handling in CCPP - units = none - dimensions = () - type = character - kind = len=* - intent = out -[errflg] - standard_name = ccpp_error_code - long_name = error code for error handling in CCPP - units = 1 - dimensions = () - type = integer - intent = out