diff --git a/ccpp/config/ccpp_prebuild_config.py b/ccpp/config/ccpp_prebuild_config.py index fdc47fc9..f2d29d2d 100755 --- a/ccpp/config/ccpp_prebuild_config.py +++ b/ccpp/config/ccpp_prebuild_config.py @@ -230,6 +230,7 @@ 'ccpp/physics/physics/GFS_surface_composites.F90' , 'ccpp/physics/physics/GFS_surface_loop_control.F90' , 'ccpp/physics/physics/GFS_time_vary_pre.scm.F90' , +# 'ccpp/physics/physics/bl_acm.F90' , 'ccpp/physics/physics/cires_ugwp.F90' , 'ccpp/physics/physics/cires_ugwp_post.F90' , 'ccpp/physics/physics/cnvc90.f' , diff --git a/ccpp/physics_namelists/input_GFS_v15p2_ACM.nml b/ccpp/physics_namelists/input_GFS_v15p2_ACM.nml new file mode 100644 index 00000000..20f90f7d --- /dev/null +++ b/ccpp/physics_namelists/input_GFS_v15p2_ACM.nml @@ -0,0 +1,116 @@ +&gfs_physics_nml + fhzero = 6. + h2o_phys = .true. + ldiag3d = .true. + fhcyc = 24. + use_ufo = .true. + pre_rad = .false. + ncld = 5 + imp_physics = 11 + pdfcld = .false. + fhswr = 3600. + fhlwr = 3600. + ialb = 1 + iems = 1 + iaer = 111 + ico2 = 2 + isubc_sw = 2 + isubc_lw = 2 + isol = 2 + lwhtr = .true. + swhtr = .true. + cnvgwd = .true. + shal_cnv = .true. + cal_pre = .false. + redrag = .true. + dspheat = .true. + hybedmf = .false. + do_ysu = .false. + acm = .true. + random_clds = .false. + trans_trac = .true. + cnvcld = .true. + imfshalcnv = 2 + imfdeepcnv = 2 + cdmbgwd = 3.5,0.25 + prslrd0 = 0. + ivegsrc = 1 + isot = 1 + debug = .false. + oz_phys = .false. + oz_phys_2015 = .true. + nstf_name = 2,1,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .true. + effr_in = .true. + do_sppt = .false. + do_shum = .false. + do_skeb = .false. + do_sfcperts = .false. +/ + +&gfdl_cloud_microphysics_nml + sedi_transport = .true. + do_sedi_heat = .false. + rad_snow = .true. + rad_graupel = .true. + rad_rain = .true. + const_vi = .F. + const_vs = .F. + const_vg = .F. + const_vr = .F. + vi_max = 1. + vs_max = 2. + vg_max = 12. + vr_max = 12. + qi_lim = 1. + prog_ccn = .false. + do_qa = .false. + fast_sat_adj = .false. + tau_l2v = 225. + tau_v2l = 150. + tau_g2v = 900. + rthresh = 10.e-6 ! This is a key parameter for cloud water + dw_land = 0.16 + dw_ocean = 0.10 + ql_gen = 1.0e-3 + ql_mlt = 1.0e-3 + qi0_crt = 8.0E-5 + qs0_crt = 1.0e-3 + tau_i2s = 1000. + c_psaci = 0.05 + c_pgacs = 0.01 + rh_inc = 0.30 + rh_inr = 0.30 + rh_ins = 0.30 + ccn_l = 300. + ccn_o = 100. + c_paut = 0.5 + c_cracw = 0.8 + use_ppm = .false. + use_ccn = .true. + mono_prof = .true. + z_slope_liq = .true. + z_slope_ice = .true. + de_ice = .false. + fix_negative = .true. + icloud_f = 1 + mp_time = 150. +/ + +&cires_ugwp_nml + knob_ugwp_solver = 2 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 1 + knob_ugwp_ndx4lh = 1 + knob_ugwp_version = 0 + launch_level = 25 +/ diff --git a/ccpp/physics_namelists/input_GFS_v15p2_YSU.nml b/ccpp/physics_namelists/input_GFS_v15p2_YSU.nml new file mode 100644 index 00000000..a80558c0 --- /dev/null +++ b/ccpp/physics_namelists/input_GFS_v15p2_YSU.nml @@ -0,0 +1,115 @@ +&gfs_physics_nml + fhzero = 6. + h2o_phys = .true. + ldiag3d = .true. + fhcyc = 24. + use_ufo = .true. + pre_rad = .false. + ncld = 5 + imp_physics = 11 + pdfcld = .false. + fhswr = 3600. + fhlwr = 3600. + ialb = 1 + iems = 1 + iaer = 111 + ico2 = 2 + isubc_sw = 2 + isubc_lw = 2 + isol = 2 + lwhtr = .true. + swhtr = .true. + cnvgwd = .true. + shal_cnv = .true. + cal_pre = .false. + redrag = .true. + dspheat = .true. + hybedmf = .false. + do_ysu = .true. + random_clds = .false. + trans_trac = .true. + cnvcld = .true. + imfshalcnv = 2 + imfdeepcnv = 2 + cdmbgwd = 3.5,0.25 + prslrd0 = 0. + ivegsrc = 1 + isot = 1 + debug = .false. + oz_phys = .false. + oz_phys_2015 = .true. + nstf_name = 2,1,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .true. + effr_in = .true. + do_sppt = .false. + do_shum = .false. + do_skeb = .false. + do_sfcperts = .false. +/ + +&gfdl_cloud_microphysics_nml + sedi_transport = .true. + do_sedi_heat = .false. + rad_snow = .true. + rad_graupel = .true. + rad_rain = .true. + const_vi = .F. + const_vs = .F. + const_vg = .F. + const_vr = .F. + vi_max = 1. + vs_max = 2. + vg_max = 12. + vr_max = 12. + qi_lim = 1. + prog_ccn = .false. + do_qa = .false. + fast_sat_adj = .false. + tau_l2v = 225. + tau_v2l = 150. + tau_g2v = 900. + rthresh = 10.e-6 ! This is a key parameter for cloud water + dw_land = 0.16 + dw_ocean = 0.10 + ql_gen = 1.0e-3 + ql_mlt = 1.0e-3 + qi0_crt = 8.0E-5 + qs0_crt = 1.0e-3 + tau_i2s = 1000. + c_psaci = 0.05 + c_pgacs = 0.01 + rh_inc = 0.30 + rh_inr = 0.30 + rh_ins = 0.30 + ccn_l = 300. + ccn_o = 100. + c_paut = 0.5 + c_cracw = 0.8 + use_ppm = .false. + use_ccn = .true. + mono_prof = .true. + z_slope_liq = .true. + z_slope_ice = .true. + de_ice = .false. + fix_negative = .true. + icloud_f = 1 + mp_time = 150. +/ + +&cires_ugwp_nml + knob_ugwp_solver = 2 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 1 + knob_ugwp_ndx4lh = 1 + knob_ugwp_version = 0 + launch_level = 25 +/ diff --git a/ccpp/physics_namelists/input_GFS_v15p2_saYSU.nml b/ccpp/physics_namelists/input_GFS_v15p2_saYSU.nml new file mode 100644 index 00000000..eb428317 --- /dev/null +++ b/ccpp/physics_namelists/input_GFS_v15p2_saYSU.nml @@ -0,0 +1,115 @@ +&gfs_physics_nml + fhzero = 6. + h2o_phys = .true. + ldiag3d = .true. + fhcyc = 24. + use_ufo = .true. + pre_rad = .false. + ncld = 5 + imp_physics = 11 + pdfcld = .false. + fhswr = 3600. + fhlwr = 3600. + ialb = 1 + iems = 1 + iaer = 111 + ico2 = 2 + isubc_sw = 2 + isubc_lw = 2 + isol = 2 + lwhtr = .true. + swhtr = .true. + cnvgwd = .true. + shal_cnv = .true. + cal_pre = .false. + redrag = .true. + dspheat = .true. + hybedmf = .false. + shinhong = .true. + random_clds = .false. + trans_trac = .true. + cnvcld = .true. + imfshalcnv = 2 + imfdeepcnv = 2 + cdmbgwd = 3.5,0.25 + prslrd0 = 0. + ivegsrc = 1 + isot = 1 + debug = .false. + oz_phys = .false. + oz_phys_2015 = .true. + nstf_name = 2,1,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .true. + effr_in = .true. + do_sppt = .false. + do_shum = .false. + do_skeb = .false. + do_sfcperts = .false. +/ + +&gfdl_cloud_microphysics_nml + sedi_transport = .true. + do_sedi_heat = .false. + rad_snow = .true. + rad_graupel = .true. + rad_rain = .true. + const_vi = .F. + const_vs = .F. + const_vg = .F. + const_vr = .F. + vi_max = 1. + vs_max = 2. + vg_max = 12. + vr_max = 12. + qi_lim = 1. + prog_ccn = .false. + do_qa = .false. + fast_sat_adj = .false. + tau_l2v = 225. + tau_v2l = 150. + tau_g2v = 900. + rthresh = 10.e-6 ! This is a key parameter for cloud water + dw_land = 0.16 + dw_ocean = 0.10 + ql_gen = 1.0e-3 + ql_mlt = 1.0e-3 + qi0_crt = 8.0E-5 + qs0_crt = 1.0e-3 + tau_i2s = 1000. + c_psaci = 0.05 + c_pgacs = 0.01 + rh_inc = 0.30 + rh_inr = 0.30 + rh_ins = 0.30 + ccn_l = 300. + ccn_o = 100. + c_paut = 0.5 + c_cracw = 0.8 + use_ppm = .false. + use_ccn = .true. + mono_prof = .true. + z_slope_liq = .true. + z_slope_ice = .true. + de_ice = .false. + fix_negative = .true. + icloud_f = 1 + mp_time = 150. +/ + +&cires_ugwp_nml + knob_ugwp_solver = 2 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 1 + knob_ugwp_ndx4lh = 1 + knob_ugwp_version = 0 + launch_level = 25 +/ diff --git a/ccpp/suites/suite_SCM_GFS_v15p2_ACM_ps.xml b/ccpp/suites/suite_SCM_GFS_v15p2_ACM_ps.xml new file mode 100644 index 00000000..37ec81cf --- /dev/null +++ b/ccpp/suites/suite_SCM_GFS_v15p2_ACM_ps.xml @@ -0,0 +1,63 @@ + + + + + + GFS_time_vary_pre + GFS_rrtmg_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + GFS_rrtmg_pre + rrtmg_sw_pre + rrtmg_sw + rrtmg_sw_post + rrtmg_lw_pre + rrtmg_lw + rrtmg_lw_post + GFS_rrtmg_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + dcyc2t3 + GFS_suite_interstitial_2 + gmtb_scm_sfc_flux_spec + GFS_PBL_generic_pre + bl_acm + GFS_PBL_generic_post + GFS_GWD_generic_pre + cires_ugwp + cires_ugwp_post + GFS_GWD_generic_post + rayleigh_damp + GFS_suite_stateout_update + ozphys_2015 + h2ophys + get_phi_fv3 + GFS_suite_interstitial_3 + GFS_DCNV_generic_pre + samfdeepcnv + GFS_DCNV_generic_post + GFS_SCNV_generic_pre + samfshalcnv + GFS_SCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + gfdl_cloud_microphys + GFS_MP_generic_post + maximum_hourly_diagnostics + phys_tend + + + diff --git a/ccpp/suites/suite_SCM_GFS_v15p2_YSU_ps.xml b/ccpp/suites/suite_SCM_GFS_v15p2_YSU_ps.xml new file mode 100644 index 00000000..725502b4 --- /dev/null +++ b/ccpp/suites/suite_SCM_GFS_v15p2_YSU_ps.xml @@ -0,0 +1,63 @@ + + + + + + GFS_time_vary_pre + GFS_rrtmg_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + GFS_rrtmg_pre + rrtmg_sw_pre + rrtmg_sw + rrtmg_sw_post + rrtmg_lw_pre + rrtmg_lw + rrtmg_lw_post + GFS_rrtmg_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + dcyc2t3 + GFS_suite_interstitial_2 + gmtb_scm_sfc_flux_spec + GFS_PBL_generic_pre + ysuvdif + GFS_PBL_generic_post + GFS_GWD_generic_pre + cires_ugwp + cires_ugwp_post + GFS_GWD_generic_post + rayleigh_damp + GFS_suite_stateout_update + ozphys_2015 + h2ophys + get_phi_fv3 + GFS_suite_interstitial_3 + GFS_DCNV_generic_pre + samfdeepcnv + GFS_DCNV_generic_post + GFS_SCNV_generic_pre + samfshalcnv + GFS_SCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + gfdl_cloud_microphys + GFS_MP_generic_post + maximum_hourly_diagnostics + phys_tend + + + diff --git a/ccpp/suites/suite_SCM_GFS_v15p2_saYSU_ps.xml b/ccpp/suites/suite_SCM_GFS_v15p2_saYSU_ps.xml new file mode 100644 index 00000000..d9739dae --- /dev/null +++ b/ccpp/suites/suite_SCM_GFS_v15p2_saYSU_ps.xml @@ -0,0 +1,63 @@ + + + + + + GFS_time_vary_pre + GFS_rrtmg_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + GFS_rrtmg_pre + rrtmg_sw_pre + rrtmg_sw + rrtmg_sw_post + rrtmg_lw_pre + rrtmg_lw + rrtmg_lw_post + GFS_rrtmg_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + dcyc2t3 + GFS_suite_interstitial_2 + gmtb_scm_sfc_flux_spec + GFS_PBL_generic_pre + shinhongvdif + GFS_PBL_generic_post + GFS_GWD_generic_pre + cires_ugwp + cires_ugwp_post + GFS_GWD_generic_post + rayleigh_damp + GFS_suite_stateout_update + ozphys_2015 + h2ophys + get_phi_fv3 + GFS_suite_interstitial_3 + GFS_DCNV_generic_pre + samfdeepcnv + GFS_DCNV_generic_post + GFS_SCNV_generic_pre + samfshalcnv + GFS_SCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + gfdl_cloud_microphys + GFS_MP_generic_post + maximum_hourly_diagnostics + phys_tend + + + diff --git a/scm/etc/tracer_config/tracers_csawmg.txt b/scm/etc/tracer_config/tracers_csawmg.txt new file mode 100644 index 00000000..262e6b5e --- /dev/null +++ b/scm/etc/tracer_config/tracers_csawmg.txt @@ -0,0 +1,12 @@ +"sphum","water_vapor_specific_humidity","kg kg-1" +"liq_wat","cloud_condensed_water_mixing_ratio","kg kg-1" +"ice_wat","ice_water_mixing_ratio","kg kg-1" +"rainwat","rain_water_mixing_ratio","kg kg-1" +"snowwat","snow_water_mixing_ratio","kg kg-1" +"graupel","graupel_mixing_ratio","kg kg-1" +"water_nc","cloud_droplet_number_concentration","kg-1" +"ice_nc","ice_number_concentration","kg-1" +"rain_nc","rain_number_concentration","kg-1" +"snow_nc","snow_number_concentration","kg-1" +"graupel_nc","graupel_number_concentration","kg-1" +"o3mr","ozone_mixing_ratio","kg kg-1" \ No newline at end of file diff --git a/scm/etc/tracer_config/tracers_gfdlmp.txt b/scm/etc/tracer_config/tracers_gfdlmp.txt new file mode 100644 index 00000000..6689c538 --- /dev/null +++ b/scm/etc/tracer_config/tracers_gfdlmp.txt @@ -0,0 +1,8 @@ +"sphum","water_vapor_specific_humidity","kg kg-1" +"liq_wat","cloud_condensed_water_mixing_ratio","kg kg-1" +"ice_wat","ice_water_mixing_ratio","kg kg-1" +"o3mr","ozone_mixing_ratio","kg kg-1" +"rainwat","rain_water_mixing_ratio","kg kg-1" +"snowwat","snow_water_mixing_ratio","kg kg-1" +"graupel","graupel_mixing_ratio","kg kg-1" +"cld_amt","cloud_fraction","frac" \ No newline at end of file diff --git a/scm/etc/tracer_config/tracers_gsd.txt b/scm/etc/tracer_config/tracers_gsd.txt new file mode 100644 index 00000000..873b5532 --- /dev/null +++ b/scm/etc/tracer_config/tracers_gsd.txt @@ -0,0 +1,13 @@ +"sphum","water_vapor_specific_humidity","kg kg-1" +"liq_wat","cloud_condensed_water_mixing_ratio","kg kg-1" +"ice_wat","ice_water_mixing_ratio","kg kg-1" +"rainwat","rain_water_mixing_ratio","kg kg-1" +"snowwat","snow_water_mixing_ratio","kg kg-1" +"graupel","graupel_mixing_ratio","kg kg-1" +"water_nc","cloud_droplet_number_concentration","kg-1" +"ice_nc","ice_number_concentration","kg-1" +"rain_nc","rain_number_concentration","kg-1" +"o3mr","ozone_mixing_ratio","kg kg-1" +"liq_aero","water_friendly_aerosol_number_concentration","kg-1" +"ice_aero","ice_friendly_aerosol_number_concentration","kg-1" +"sgs_tke","turbulent_kinetic_energy","m2 s-2" \ No newline at end of file diff --git a/scm/src/GFS_typedefs.F90 b/scm/src/GFS_typedefs.F90 index 980f2710..04e00ac0 100644 --- a/scm/src/GFS_typedefs.F90 +++ b/scm/src/GFS_typedefs.F90 @@ -820,6 +820,7 @@ module GFS_typedefs !< vertical turbulent mixing scheme logical :: shinhong !< flag for scale-aware Shinhong vertical turbulent mixing scheme logical :: do_ysu !< flag for YSU turbulent mixing scheme + logical :: acm !< flag for ACM turbulent mixing scheme logical :: dspheat !< flag for tke dissipative heating logical :: hurr_pbl !< flag for hurricane-specific options in PBL scheme logical :: lheatstrg !< flag for canopy heat storage parameterization @@ -1792,7 +1793,10 @@ module GFS_typedefs integer :: nsamftrac !< integer :: nscav !< integer :: nspc1 !< + integer :: ntqvx !< + integer :: ntcwx !< integer :: ntiwx !< + integer :: ntozx !< integer :: ntk !< integer :: ntkev !< integer :: nvdiff !< @@ -3040,6 +3044,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & !< vertical turbulent mixing scheme logical :: shinhong = .false. !< flag for scale-aware Shinhong vertical turbulent mixing scheme logical :: do_ysu = .false. !< flag for YSU vertical turbulent mixing scheme + logical :: acm = .false. !< flag for ACM vertical turbulent mixing scheme logical :: dspheat = .false. !< flag for tke dissipative heating logical :: hurr_pbl = .false. !< flag for hurricane-specific options in PBL scheme logical :: lheatstrg = .false. !< flag for canopy heat storage parameterization @@ -3303,7 +3308,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & do_myjsfc, do_myjpbl, & hwrf_samfdeep, hwrf_samfshal, & h2o_phys, pdfcld, shcnvcw, redrag, hybedmf, satmedmf, & - shinhong, do_ysu, dspheat, hurr_pbl, lheatstrg, cnvcld, & + shinhong, do_ysu, acm, dspheat, hurr_pbl, lheatstrg, cnvcld, & random_clds, shal_cnv, imfshalcnv, imfdeepcnv, isatmedmf, & do_deep, jcap, & cs_parm, flgmin, cgwf, ccwf, cdmbgwd, sup, ctei_rm, crtrh, & @@ -3430,6 +3435,18 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & if(me==master) & write(0,*) 'FLAG: do_mynnedmf so pbl not generic' Model%flag_for_pbl_generic_tend=.false. + else if(do_ysu) then + if(me==master) & + write(0,*) 'FLAG: do_ysu so pbl not generic' + Model%flag_for_pbl_generic_tend=.false. + else if(shinhong) then + if(me==master) & + write(0,*) 'FLAG: shinhong so pbl not generic' + Model%flag_for_pbl_generic_tend=.false. + else if(acm) then + if(me==master) & + write(0,*) 'FLAG: acm so pbl not generic' + Model%flag_for_pbl_generic_tend=.false. elseif(me==master) then write(0,*) 'NO FLAG: pbl is generic' endif @@ -3793,6 +3810,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%satmedmf = satmedmf Model%shinhong = shinhong Model%do_ysu = do_ysu + Model%acm = acm Model%dspheat = dspheat Model%hurr_pbl = hurr_pbl Model%lheatstrg = lheatstrg @@ -3957,7 +3975,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%ntracp1 = Model%ntrac + 1 allocate (Model%tracer_names(Model%ntrac)) Model%tracer_names(:) = tracer_names(:) - Model%ntqv = get_tracer_index(Model%tracer_names, 'vap_wat', Model%me, Model%master, Model%debug) + Model%ntqv = get_tracer_index(Model%tracer_names, 'sphum', Model%me, Model%master, Model%debug) #ifdef MULTI_GASES Model%nto = get_tracer_index(Model%tracer_names, 'spfo', Model%me, Model%master, Model%debug) Model%nto2 = get_tracer_index(Model%tracer_names, 'spfo2', Model%me, Model%master, Model%debug) @@ -4800,6 +4818,7 @@ subroutine control_print(Model) print *, ' isatmedmf : ', Model%isatmedmf print *, ' shinhong : ', Model%shinhong print *, ' do_ysu : ', Model%do_ysu + print *, ' acm : ', Model%acm print *, ' dspheat : ', Model%dspheat print *, ' lheatstrg : ', Model%lheatstrg print *, ' cnvcld : ', Model%cnvcld @@ -5933,7 +5952,7 @@ subroutine interstitial_create (Interstitial, IM, Model) ! allocate (Interstitial%otspt (Model%ntracp1,2)) ! Set up numbers of tracers for PBL, convection, etc: sets - ! Interstitial%{nncl,nvdiff,mg3_as_mg2,nn,tracers_total,ntiwx,ntk,ntkev,otspt,nsamftrac,ncstrac,nscav} + ! Interstitial%{nncl,nvdiff,mg3_as_mg2,nn,tracers_total,ntqvx,ntcwx,ntiwx,ntk,ntkev,ntozx,otspt,nsamftrac,ncstrac,nscav} call interstitial_setup_tracers(Interstitial, Model) ! Allocate arrays allocate (Interstitial%adjsfculw_land (IM)) @@ -6390,7 +6409,7 @@ subroutine interstitial_setup_tracers(Interstitial, Model) elseif (Model%ntclamt > 0) then ! for GFDL MP don't diffuse cloud amount Interstitial%nvdiff = Model%ntrac - 1 endif - + if (Model%imp_physics == Model%imp_physics_gfdl) then Interstitial%nncl = 5 endif @@ -6412,25 +6431,53 @@ subroutine interstitial_setup_tracers(Interstitial, Model) ! DH* STILL VALID GIVEN THE CHANGES BELOW FOR CPLCHM? if (Interstitial%nvdiff == Model%ntrac) then + Interstitial%ntqvx = Model%ntqv + Interstitial%ntcwx = Model%ntcw Interstitial%ntiwx = Model%ntiw + Interstitial%ntozx = Model%ntoz else if (Model%imp_physics == Model%imp_physics_wsm6) then + Interstitial%ntqvx = 1 + Interstitial%ntcwx = 2 Interstitial%ntiwx = 3 + Interstitial%ntozx = 4 elseif (Model%imp_physics == Model%imp_physics_thompson) then if(Model%ltaerosol) then + Interstitial%ntqvx = 1 + Interstitial%ntcwx = 2 Interstitial%ntiwx = 3 + Interstitial%ntozx = 10 else + Interstitial%ntqvx = 1 + Interstitial%ntcwx = 2 Interstitial%ntiwx = 3 + Interstitial%ntozx = 9 endif elseif (Model%imp_physics == Model%imp_physics_gfdl) then + Interstitial%ntqvx = 1 + Interstitial%ntcwx = 2 Interstitial%ntiwx = 3 + Interstitial%ntozx = 7 ! F-A MP scheme elseif (Model%imp_physics == Model%imp_physics_fer_hires) then + Interstitial%ntqvx = 1 + Interstitial%ntcwx = 2 Interstitial%ntiwx = 3 ! total ice or total condensate + Interstitial%ntozx = 6 elseif (Model%imp_physics == Model%imp_physics_mg) then + Interstitial%ntqvx = 1 + Interstitial%ntcwx = 2 Interstitial%ntiwx = 3 + if (Model%ntgl > 0) then + Interstitial%ntozx = 12 + else + Interstitial%ntozx = 10 + end if else + Interstitial%ntqvx = 1 + Interstitial%ntcwx = 2 Interstitial%ntiwx = 0 + Interstitial%ntozx = 3 endif endif ! *DH diff --git a/scm/src/GFS_typedefs.meta b/scm/src/GFS_typedefs.meta index b83b31d7..b84caba5 100644 --- a/scm/src/GFS_typedefs.meta +++ b/scm/src/GFS_typedefs.meta @@ -8011,6 +8011,18 @@ units = count dimensions = () type = integer +[ntqvx] + standard_name = index_for_water_vapor_vertical_diffusion_tracer + long_name = tracer index for water vapor (specific humidity) in the vertically diffused tracer array + units = index + dimensions = () + type = integer +[ntcwx] + standard_name = index_for_liquid_cloud_condensate_vertical_diffusion_tracer + long_name = tracer index for cloud condensate (or liquid water) in the vertically diffused tracer array + units = index + dimensions = () + type = integer [ntiwx] standard_name = index_for_ice_cloud_condensate_vertical_diffusion_tracer long_name = index for ice cloud condensate in the vertically diffused tracer array @@ -8029,6 +8041,12 @@ units = index dimensions = () type = integer +[ntozx] + standard_name = index_for_ozone_vertical_diffusion_tracer + long_name = tracer index for ozone mixing ratio in the vertically diffused tracer array + units = index + dimensions = () + type = integer [nvdiff] standard_name = number_of_vertical_diffusion_tracers long_name = number of tracers to diffuse vertically diff --git a/scm/src/default_namelists.py b/scm/src/default_namelists.py index 41a0299a..7097c4ac 100644 --- a/scm/src/default_namelists.py +++ b/scm/src/default_namelists.py @@ -6,5 +6,8 @@ "SCM_GFS_v16beta_no_nsst":"input_GFS_v16beta.nml", "SCM_GFS_v15p2_noahmp":"input_GFS_v15p2_noahmp.nml", "SCM_GFS_v15p2_MYJ":"input_GFS_v15p2_MYJ.nml", - "SCM_GFS_v15p2_FA":"input_GFS_v15p2_FA.nml" + "SCM_GFS_v15p2_FA":"input_GFS_v15p2_FA.nml", + "SCM_GFS_v15p2_YSU":"input_GFS_v15p2_YSU.nml", + "SCM_GFS_v15p2_saYSU":"input_GFS_v15p2_saYSU.nml", + "SCM_GFS_v15p2_ACM":"input_GFS_v15p2_ACM.nml" } \ No newline at end of file diff --git a/scm/src/default_tracers.py b/scm/src/default_tracers.py new file mode 100644 index 00000000..8bbff40a --- /dev/null +++ b/scm/src/default_tracers.py @@ -0,0 +1,12 @@ +default_tracers = {"SCM_GFS_v15p2":"tracers_gfdlmp.txt", + "SCM_GFS_v16beta":"tracers_gfdlmp.txt", + "SCM_csawmg":"tracers_csawmg.txt", + "SCM_GFS_v15p2_no_nsst":"tracers_gfdlmp.txt", + "SCM_GFS_v16beta_no_nsst":"tracers_gfdlmp.txt", + "SCM_GFS_v15p2_noahmp":"tracers_gfdlmp.txt", + "SCM_GFS_v15p2_MYJ":"tracers_gfdlmp.txt", + "SCM_GSD_v1":"tracers_gsd.txt", + "SCM_GFS_v15p2_YSU":"tracers_gfdlmp.txt", + "SCM_GFS_v15p2_saYSU":"tracers_gfdlmp.txt", + "SCM_GFS_v15p2_ACM":"tracers_gfdlmp.txt" + } \ No newline at end of file diff --git a/scm/src/gmtb_scm_input.F90 b/scm/src/gmtb_scm_input.F90 index c55bcbfd..75a227ca 100644 --- a/scm/src/gmtb_scm_input.F90 +++ b/scm/src/gmtb_scm_input.F90 @@ -59,6 +59,8 @@ subroutine get_config_nml(scm_state) character(len=character_length) :: physics_suite !< name of the physics suite name (currently only GFS_operational supported) character(len=character_length) :: physics_nml + + character(len=character_length), allocatable, dimension(:) :: tracer_names integer :: ioerror @@ -138,9 +140,11 @@ subroutine get_config_nml(scm_state) case default n_time_levels = 2 end select - - call scm_state%create(n_columns, n_levels, n_soil, n_snow, n_time_levels) + call get_tracers(tracer_names) + + call scm_state%create(n_columns, n_levels, n_soil, n_snow, n_time_levels, tracer_names) + scm_state%experiment_name = experiment_name scm_state%model_name = model_name scm_state%output_dir = output_dir @@ -174,6 +178,7 @@ subroutine get_config_nml(scm_state) scm_state%reference_profile_choice = reference_profile_choice scm_state%relax_time = relax_time + deallocate(tracer_names) !> @} end subroutine get_config_nml @@ -867,6 +872,38 @@ subroutine get_reference_profile_old(nlev, pres, T, qv, ozone) end subroutine get_reference_profile_old +subroutine get_tracers(tracer_names) + character(len=character_length), allocatable, intent(inout), dimension(:) :: tracer_names + + character(len=*), parameter :: file_name = 'tracers.txt' + + character(len=100) :: name!, std_name, units + integer :: i, fu, rc, n_lines + + open (action='read', file=FILE_NAME, iostat=rc, newunit=fu) + if (rc == 0) then + n_lines = 0 + do + read (fu, *, iostat=rc) name!, std_name, units + if (rc /= 0) exit + n_lines = n_lines + 1 + end do + allocate(tracer_names(n_lines)) + rewind(fu) + do i=1,n_lines + read (fu, *, iostat=rc) name!, std_name, units + if (rc /= 0) exit + tracer_names(i) = trim(name) + end do + else + write(*,'(a,i0)') 'There was an error opening the file ' // FILE_NAME // & + '; error code = ', rc + stop + end if + + close (fu) +end subroutine get_tracers + !> Generic subroutine to check for netCDF I/O errors subroutine check(status) integer, intent ( in) :: status diff --git a/scm/src/gmtb_scm_type_defs.F90 b/scm/src/gmtb_scm_type_defs.F90 index 4aa87fc9..f794de33 100644 --- a/scm/src/gmtb_scm_type_defs.F90 +++ b/scm/src/gmtb_scm_type_defs.F90 @@ -352,9 +352,12 @@ module gmtb_scm_type_defs contains - subroutine scm_state_create(scm_state, n_columns, n_levels, n_soil, n_snow, n_time_levels) + subroutine scm_state_create(scm_state, n_columns, n_levels, n_soil, n_snow, n_time_levels, tracers) class(scm_state_type) :: scm_state integer, intent(in) :: n_columns, n_levels, n_soil, n_snow, n_time_levels + character(len=character_length), intent(in), dimension(:) :: tracers + + integer :: i scm_state%experiment_name = clear_char scm_state%model_name = clear_char @@ -374,42 +377,28 @@ subroutine scm_state_create(scm_state, n_columns, n_levels, n_soil, n_snow, n_ti scm_state%n_cols = n_columns scm_state%n_timesteps = int_zero scm_state%n_time_levels = n_time_levels - scm_state%n_tracers = 17 + + scm_state%n_tracers = size(tracers) allocate(scm_state%tracer_names(scm_state%n_tracers)) - scm_state%water_vapor_index = 1 - scm_state%ozone_index = 2 - scm_state%cloud_water_index = 3 - scm_state%cloud_ice_index = 4 - scm_state%rain_index = 5 - scm_state%snow_index = 6 - scm_state%graupel_index = 7 - scm_state%cloud_amount_index = 8 - scm_state%cloud_droplet_nc_index = 9 - scm_state%cloud_ice_nc_index = 10 - scm_state%rain_nc_index = 11 - scm_state%snow_nc_index = 12 - scm_state%graupel_nc_index = 13 - scm_state%tke_index = 14 - scm_state%water_friendly_aerosol_index = 15 - scm_state%ice_friendly_aerosol_index = 16 - scm_state%mass_weighted_rime_factor_index = 17 - scm_state%tracer_names(1) = 'vap_wat' - scm_state%tracer_names(2) = 'o3mr' - scm_state%tracer_names(3) = 'liq_wat' - scm_state%tracer_names(4) = 'ice_wat' - scm_state%tracer_names(5) = 'rainwat' - scm_state%tracer_names(6) = 'snowwat' - scm_state%tracer_names(7) = 'graupel' - scm_state%tracer_names(8) = 'cld_amt' - scm_state%tracer_names(9) = 'water_nc' - scm_state%tracer_names(10)= 'ice_nc' - scm_state%tracer_names(11)= 'rain_nc' - scm_state%tracer_names(12)= 'snow_nc' - scm_state%tracer_names(13)= 'graupel_nc' - scm_state%tracer_names(14)= 'sgs_tke' - scm_state%tracer_names(15)= 'liq_aero' - scm_state%tracer_names(16)= 'ice_aero' - scm_state%tracer_names(17)= 'q_rimef' + scm_state%tracer_names = tracers + scm_state%water_vapor_index = get_tracer_index(scm_state%tracer_names,"sphum") + scm_state%ozone_index = get_tracer_index(scm_state%tracer_names,"o3mr") + scm_state%cloud_water_index = get_tracer_index(scm_state%tracer_names,"liq_wat") + scm_state%cloud_ice_index = get_tracer_index(scm_state%tracer_names,"ice_wat") + scm_state%rain_index = get_tracer_index(scm_state%tracer_names,"rainwat") + scm_state%snow_index = get_tracer_index(scm_state%tracer_names,"snowwat") + scm_state%graupel_index = get_tracer_index(scm_state%tracer_names,"graupel") + scm_state%cloud_amount_index = get_tracer_index(scm_state%tracer_names,"cld_amt") + scm_state%cloud_droplet_nc_index = get_tracer_index(scm_state%tracer_names,"water_nc") + scm_state%cloud_ice_nc_index = get_tracer_index(scm_state%tracer_names,"ice_nc") + scm_state%rain_nc_index = get_tracer_index(scm_state%tracer_names,"rain_nc") + scm_state%snow_nc_index = get_tracer_index(scm_state%tracer_names,"snow_nc") + scm_state%graupel_nc_index = get_tracer_index(scm_state%tracer_names,"graupel_nc") + scm_state%tke_index = get_tracer_index(scm_state%tracer_names,"sgs_tke") + scm_state%water_friendly_aerosol_index = get_tracer_index(scm_state%tracer_names,"liq_aero") + scm_state%ice_friendly_aerosol_index = get_tracer_index(scm_state%tracer_names,"ice_aero") + scm_state%mass_weighted_rime_factor_index = get_tracer_index(scm_state%tracer_names,"q_rimef") + scm_state%n_itt_swrad = int_zero scm_state%n_itt_lwrad = int_zero scm_state%n_itt_out = int_zero @@ -946,5 +935,33 @@ subroutine physics_associate(physics, scm_state) end subroutine physics_associate + + function get_tracer_index (tracer_names, name) + + character(len=32), intent(in) :: tracer_names(:) + character(len=*), intent(in) :: name + + !--- local variables + integer :: get_tracer_index + integer :: i + integer, parameter :: no_tracer = -99 + + get_tracer_index = no_tracer + + do i=1, size(tracer_names) + if (trim(name) == trim(tracer_names(i))) then + get_tracer_index = i + exit + endif + enddo + + if (get_tracer_index == no_tracer) then + print *,'tracer with name '//trim(name)//' not found' + else + print *,'tracer FOUND:',trim(name) + endif + + return + end function get_tracer_index end module gmtb_scm_type_defs diff --git a/scm/src/run_gmtb_scm.py b/scm/src/run_gmtb_scm.py index 5bd5ea0f..af453741 100755 --- a/scm/src/run_gmtb_scm.py +++ b/scm/src/run_gmtb_scm.py @@ -10,6 +10,7 @@ import sys import time from default_namelists import default_physics_namelists +from default_tracers import default_tracers ############################################################################### # Global settings # @@ -21,6 +22,10 @@ # Path to the directory containing experiment namelists (relative to run dir) CASE_NAMELIST_DIR = '../etc/case_config' +# Path to the directory containing tracer configurations (relative to run dir) +TRACERS_DIR = '../etc/tracer_config' +TRACERS_LINK = 'tracers.txt' + # Standard name of experiment namelist in run directory, must match value in gmtb_scm_input.f90 STANDARD_EXPERIMENT_NAMELIST = 'input_experiment.nml' @@ -63,6 +68,7 @@ parser.add_argument('-g', '--gdb', help='invoke gmtb_scm through gdb', action='store_true', default=False) parser.add_argument('-s', '--suite', help='name of suite to use', default=DEFAULT_SUITE) parser.add_argument('-n', '--namelist', help='physics namelist to use') +parser.add_argument('-t', '--tracers', help='tracer configuration to use') parser.add_argument('-d', '--docker', help='include if scm is being run in a docker container to mount volumes', action='store_true', default=False) ############################################################################### @@ -101,7 +107,8 @@ def parse_arguments(): suite = args.suite namelist = args.namelist docker = args.docker - return (case, gdb, suite, namelist, docker) + tracers = args.tracers + return (case, gdb, suite, namelist, docker, tracers) def find_gdb(): """Detect gdb, abort if not found""" @@ -118,7 +125,7 @@ def find_gdb(): class Experiment(object): - def __init__(self, case, suite, physics_namelist): + def __init__(self, case, suite, physics_namelist, tracers): """Initialize experiment. This routine does most of the work, including setting and checking the experiment configuration (namelist).""" @@ -144,6 +151,24 @@ def __init__(self, case, suite, physics_namelist): message = 'The physics namelist {0} was not found'.format(os.path.join(PHYSICS_NAMELIST_DIR, self._physics_namelist)) logging.critical(message) raise Exception(message) + + #if a tracer configuration is specified (entire filename), it will be used; + #otherwise, a default tracer configuration for the given suite is used from default_tracers.py + if tracers: + self._tracers = tracers + else: + if self._suite in default_tracers: + self._tracers = default_tracers.get(self._suite) + else: + message = 'A default tracer configuration for suite {0} is not found in default_tracers.py'.format(self._suite) + logging.critical(message) + raise Exception(message) + + #check to see that the physics namelists exists in the right dir + if not os.path.isfile(os.path.join(TRACERS_DIR, self._tracers)): + message = 'The tracer configuration {0} was not found'.format(os.path.join(TRACERS_DIR, self._tracers)) + logging.critical(message) + raise Exception(message) #check to see if the case namelists exists in the right dir self._namelist = os.path.join(CASE_NAMELIST_DIR, self._case + '.nml') @@ -267,6 +292,17 @@ def setup_rundir(self): cmd = "ln -sf {0} {1}".format(os.path.join(PHYSICS_NAMELIST_DIR, self._physics_namelist), self._physics_namelist) execute(cmd) + # Link tracer configuration to run directory with its original name + logging.info('Linking tracer configuration {0} to run directory'.format(self._tracers)) + if os.path.isfile(self._tracers): + os.remove(self._tracers) + if not os.path.isfile(os.path.join(TRACERS_DIR, self._tracers)): + message = 'Tracer configuration {0} not found in directory {1}'.format(self._tracers, TRACERS_DIR) + logging.critical(message) + raise Exception(message) + cmd = "ln -sf {0} {1}".format(os.path.join(TRACERS_DIR, self._tracers), TRACERS_LINK) + execute(cmd) + # Link physics SDF to run directory physics_suite = 'suite_' + self._suite + '.xml' logging.info('Linking physics suite {0} to run directory'.format(physics_suite)) @@ -371,16 +407,22 @@ def copy_outdir(exp_dir): shutil.copytree(exp_dir, home_output_dir) def main(): - (case, use_gdb, suite, namelist, docker) = parse_arguments() + (case, use_gdb, suite, namelist, docker, tracers) = parse_arguments() setup_logging() #Experiment if namelist: - logging.info('Setting up experiment {0} with suite {1} using namelist {2}'.format(case,suite,namelist)) + if tracers: + logging.info('Setting up experiment {0} with suite {1} using namelist {2} and tracers {3}'.format(case,suite,namelist,tracers)) + else: + logging.info('Setting up experiment {0} with suite {1} using namelist {2} using default tracers for the suite'.format(case,suite,namelist)) else: - logging.info('Setting up experiment {0} with suite {1} using the default namelist for the suite'.format(case,suite)) - exp = Experiment(case, suite, namelist) + if tracers: + logging.info('Setting up experiment {0} with suite {1} using the default namelist for the suite and tracers {2}'.format(case,suite,tracers)) + else: + logging.info('Setting up experiment {0} with suite {1} using the default namelist and tracers for the suite'.format(case,suite)) + exp = Experiment(case, suite, namelist, tracers) exp_dir = exp.setup_rundir() # Debugger if use_gdb: