diff --git a/ccpp/config/ccpp_prebuild_config.py b/ccpp/config/ccpp_prebuild_config.py index af133339d..3f693f8ff 100755 --- a/ccpp/config/ccpp_prebuild_config.py +++ b/ccpp/config/ccpp_prebuild_config.py @@ -203,6 +203,7 @@ 'ccpp/physics/physics/PBL/MYNN_EDMF/mynnedmf_wrapper.F90', 'ccpp/physics/physics/PBL/SATMEDMF/satmedmfvdif.F', 'ccpp/physics/physics/PBL/SATMEDMF/satmedmfvdifq.F', + 'ccpp/physics/physics/PBL/SATMEDMF/canopy_driver.F', 'ccpp/physics/physics/PBL/YSU/ysuvdif.F90', 'ccpp/physics/physics/PBL/saYSU/shinhongvdif.F90', 'ccpp/physics/physics/Radiation/RRTMG/radsw_main.F90', diff --git a/ccpp/physics b/ccpp/physics index bdccfdd9c..135a5dda8 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit bdccfdd9cd474e440ad668b4732d4daacb85e357 +Subproject commit 135a5dda80f383c29c9a1ac937a392c2e74c5683 diff --git a/ccpp/suites/suite_SCM_GFS_v16.xml b/ccpp/suites/suite_SCM_GFS_v16.xml index b98d0f8ce..57c5c01fd 100644 --- a/ccpp/suites/suite_SCM_GFS_v16.xml +++ b/ccpp/suites/suite_SCM_GFS_v16.xml @@ -51,6 +51,7 @@ GFS_surface_generic_post GFS_PBL_generic_pre satmedmfvdifq + canopy_driver GFS_PBL_generic_post GFS_GWD_generic_pre cires_ugwp diff --git a/ccpp/suites/suite_SCM_GFS_v16_ps.xml b/ccpp/suites/suite_SCM_GFS_v16_ps.xml index 90962bb25..6b1a1582c 100644 --- a/ccpp/suites/suite_SCM_GFS_v16_ps.xml +++ b/ccpp/suites/suite_SCM_GFS_v16_ps.xml @@ -32,6 +32,7 @@ GFS_suite_interstitial_2 GFS_PBL_generic_pre satmedmfvdifq + canopy_driver GFS_PBL_generic_post GFS_GWD_generic_pre cires_ugwp diff --git a/ccpp/suites/suite_SCM_GFS_v17_p8.xml b/ccpp/suites/suite_SCM_GFS_v17_p8.xml index 4501026c8..8faddb85b 100644 --- a/ccpp/suites/suite_SCM_GFS_v17_p8.xml +++ b/ccpp/suites/suite_SCM_GFS_v17_p8.xml @@ -52,6 +52,7 @@ GFS_surface_generic_post GFS_PBL_generic_pre satmedmfvdifq + canopy_driver GFS_PBL_generic_post GFS_GWD_generic_pre unified_ugwp diff --git a/ccpp/suites/suite_SCM_GFS_v17_p8_ps.xml b/ccpp/suites/suite_SCM_GFS_v17_p8_ps.xml index 0f214aff6..a789c414b 100644 --- a/ccpp/suites/suite_SCM_GFS_v17_p8_ps.xml +++ b/ccpp/suites/suite_SCM_GFS_v17_p8_ps.xml @@ -33,6 +33,7 @@ GFS_suite_interstitial_2 GFS_PBL_generic_pre satmedmfvdifq + canopy_driver GFS_PBL_generic_post GFS_GWD_generic_pre unified_ugwp diff --git a/scm/src/GFS_typedefs.F90 b/scm/src/GFS_typedefs.F90 index 2dbfe62f2..f00671fdf 100644 --- a/scm/src/GFS_typedefs.F90 +++ b/scm/src/GFS_typedefs.F90 @@ -1567,6 +1567,11 @@ module GFS_typedefs integer :: nchem !< number of prognostic chemical species (vertically mixied) integer :: ndvel !< number of prognostic chemical species (which are deposited, usually =nchem) integer :: ntchm !< number of prognostic chemical tracers (advected) +! "cplaqm" tracers + integer :: nto3 !< tracer index for Ozone chemical species CMAQ + integer :: ntno !< tracer index for NO chemical species CMAQ + integer :: ntno2 !< tracer index for NO2 chemical species CMAQ + integer :: ntchs !< tracer index for first prognostic chemical tracer integer :: ntche !< tracer index for last prognostic chemical tracer integer :: ntdu1 !< tracer index for dust bin1 @@ -2162,6 +2167,11 @@ module GFS_typedefs real (kind=kind_phys), pointer :: dkt(:,:) => null() !< Eddy diffusitivity for heat real (kind=kind_phys), pointer :: dku(:,:) => null() !< Eddy diffusitivity for momentum +!3-LAYER CANOPY + !--- Extra PBL diagnostics in canopy + real (kind=kind_phys), pointer :: dkt_can(:,:) => null() !< Eddy diffusitivity for heat + real (kind=kind_phys), pointer :: dku_can(:,:) => null() !< Eddy diffusitivity for momentum + ! !---vay-2018 UGWP-diagnostics instantaneous ! @@ -2266,7 +2276,6 @@ module GFS_typedefs ! Diagnostics for coupled air quality model real (kind=kind_phys), pointer :: aod (:) => null() !< instantaneous aerosol optical depth ( n/a ) -!IVAI ! Diagnostics for coupled air quality model real (kind=kind_phys), pointer :: coszens(:) => null() ! Cosine SZA for photolysis real (kind=kind_phys), pointer :: jo3o1d(:) => null() ! instantaneous O3O1D photolysis rate @@ -2276,7 +2285,6 @@ module GFS_typedefs real (kind=kind_phys), pointer :: cfrt (:) => null() ! Forest Fraction real (kind=kind_phys), pointer :: cclu (:) => null() ! Clumping Index real (kind=kind_phys), pointer :: cpopu(:) => null() ! Population density -!IVAI ! Auxiliary output arrays for debugging real (kind=kind_phys), pointer :: aux2d(:,:) => null() !< auxiliary 2d arrays in output (for debugging) @@ -5649,6 +5657,10 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, & Model%dtidx = no_tracer if(Model%ntchm>0) then +! GFS_v16 n=9 "no2" n=10 "no" n=11 "o3" (n=8,9, 10 in PBL resp.) + Model%ntno2 = get_tracer_index(Model%tracer_names, 'no2') ! n=11 (index 10 "no2" in PBL scheme) GFS_v17_p8 + Model%ntno = get_tracer_index(Model%tracer_names, 'no') ! n=12 (index 11 "no" in PBL scheme) GFS_v17_p8 + Model%nto3 = get_tracer_index(Model%tracer_names, 'o3') ! n=13 (index 12 "o3" in PBL scheme) GFS_v17_p8 Model%ntdu1 = get_tracer_index(Model%tracer_names, 'dust1') Model%ntdu2 = get_tracer_index(Model%tracer_names, 'dust2') Model%ntdu3 = get_tracer_index(Model%tracer_names, 'dust3') @@ -5723,6 +5735,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, & endif ! More specific chemical tracer names: +! NB. ntchs is 1st chemical tracer (not so2 tracer) call label_dtend_tracer(Model,100+Model%ntchs,'so2','sulfur dioxide concentration','kg kg-1 s-1') if(Model%ntchm>0) then ! Need better descriptions of these. @@ -5772,6 +5785,11 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, & call label_dtend_tracer(Model,100+Model%ntia,'ice_aero','number concentration of ice-friendly aerosols','kg-1 s-1') call label_dtend_tracer(Model,100+Model%nto,'o_ion','oxygen ion concentration','kg kg-1 s-1') call label_dtend_tracer(Model,100+Model%nto2,'o2','oxygen concentration','kg kg-1 s-1') +! cplaqm tracers CMAQ + call label_dtend_tracer(Model,100+Model%ntno2,'no2_cpl','cplaqm NO2 concentration','kg kg-1 s-1') + call label_dtend_tracer(Model,100+Model%ntno, 'no_cpl', 'cplaqm NO concentration','kg kg-1 s-1') + call label_dtend_tracer(Model,100+Model%nto3, 'o3_cpl', 'cplaqm ozone concentration','kg kg-1 s-1') + call label_dtend_cause(Model,Model%index_of_process_pbl,'pbl','tendency due to PBL') call label_dtend_cause(Model,Model%index_of_process_dcnv,'deepcnv','tendency due to deep convection') call label_dtend_cause(Model,Model%index_of_process_scnv,'shalcnv','tendency due to shallow convection') @@ -5854,6 +5872,12 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, & enddo endif +! NB. In PBL scheme chemical tracers indexes are offset by 1 +! (qdiag3d) cplaqm tracers "no2", "no", "o3" + call fill_dtidx(Model,dtend_select,100+Model%ntno2,Model%index_of_process_pbl,have_pbl) ! ntno2= 11 (index 10 is "no2" in PBL scheme) GFS_v17_p8 + call fill_dtidx(Model,dtend_select,100+Model%ntno ,Model%index_of_process_pbl,have_pbl) ! ntno = 12 (index 11 is "no" in PBL scheme) GFS_v17_p8 + call fill_dtidx(Model,dtend_select,100+Model%nto3 ,Model%index_of_process_pbl,have_pbl) ! nto3 = 13 (index 12 is "o3" in PBL scheme) GFS_v17_p8 + call fill_dtidx(Model,dtend_select,100+Model%ntoz,Model%index_of_process_pbl,have_pbl) call fill_dtidx(Model,dtend_select,100+Model%ntoz,Model%index_of_process_prod_loss,have_oz_phys) call fill_dtidx(Model,dtend_select,100+Model%ntoz,Model%index_of_process_ozmix,have_oz_phys) @@ -7437,6 +7461,9 @@ subroutine control_print(Model) print *, ' nqrimef : ', Model%nqrimef print *, ' ntqv : ', Model%ntqv print *, ' ntoz : ', Model%ntoz + print *, ' ntno2 : ', Model%ntno2 ! "no2" tracer cplaqm/CMAQ + print *, ' ntno : ', Model%ntno ! "no" tracer cplaqm/CMAQ + print *, ' nto3 : ', Model%nto3 ! "o3" tracer cplaqm/CMAQ print *, ' ntcw : ', Model%ntcw print *, ' ntiw : ', Model%ntiw print *, ' ntrw : ', Model%ntrw @@ -8373,6 +8400,12 @@ subroutine diag_create (Diag, Model) allocate (Diag%dkt(IM,Model%levs)) allocate (Diag%dku(IM,Model%levs)) + !--- New PBL Diagnostics in 3-layer canopy + if (Model%do_canopy .and. Model%cplaqm) then + allocate (Diag%dkt_can(IM,Model%levs)) + allocate (Diag%dku_can(IM,Model%levs)) + endif + !-- New max hourly diag. allocate (Diag%refdmax(IM)) allocate (Diag%refdmax263k(IM)) @@ -8449,12 +8482,11 @@ subroutine diag_create (Diag, Model) Diag%aod = zero end if -!IVAI: ! Air quality diagnostics ! -- initialize diagnostic variables if (Model%cplaqm) then -!IVAI: photdiag arrays +! photdiag arrays allocate (Diag%coszens(IM)) Diag%coszens= zero @@ -8464,7 +8496,7 @@ subroutine diag_create (Diag, Model) allocate (Diag%jno2(IM)) Diag%jno2 = zero -!IVAI: canopy arrays read via aqm_emis_read +! Canopy arrays read via aqm_emis_read if (Model%do_canopy) then allocate (Diag%claie(IM)) Diag%claie = zero @@ -8483,7 +8515,6 @@ subroutine diag_create (Diag, Model) end if! (Model%do_canopy) end if ! (Model%cplaqm) -!IVAI ! Auxiliary arrays in output for debugging if (Model%naux2d>0) then @@ -8751,6 +8782,12 @@ subroutine diag_phys_zero (Diag, Model, linit, iauwindow_center) Diag%dkt = zero Diag%dku = zero +! Extra PBL diagnostics in 3-layer canopy + if (Model%do_canopy .and. Model%cplaqm ) then + Diag%dkt_can = zero + Diag%dku_can = zero + endif + ! max hourly diagnostics Diag%refl_10cm = -35. Diag%max_hail_diam_sfc = -999. diff --git a/scm/src/GFS_typedefs.meta b/scm/src/GFS_typedefs.meta index b057faa1c..cf7988ed6 100644 --- a/scm/src/GFS_typedefs.meta +++ b/scm/src/GFS_typedefs.meta @@ -6844,6 +6844,29 @@ units = index dimensions = () type = integer +### IVAI +[ntno2] + standard_name = index_for_no2_chemical_tracer_in_tracer_concentration_array + long_name = tracer index for coupled AQM/CMAQ NO2 chemical tracer + units = index + dimensions = () + type = integer +## active = (flag_for_air_quality_coupling .and. flag_for_canopy_option) +[ntno] + standard_name = index_for_no_chemical_tracer_in_tracer_concentration_array + long_name = tracer index for coupled AQM/CMAQ NO chemical tracer + units = index + dimensions = () + type = integer +## active = (flag_for_air_quality_coupling .and. flag_for_canopy_option) +[nto3] + standard_name = index_for_ozone_chemical_tracer_in_tracer_concentration_array + long_name = tracer index for coupled AQM/CMAQ ozone chemical tracer + units = index + dimensions = () + type = integer +## active = (flag_for_air_quality_coupling .and. flag_for_canopy_option) +### IVAI [ntcw] standard_name = index_of_cloud_liquid_water_mixing_ratio_in_tracer_concentration_array long_name = tracer index for cloud condensate (or liquid water) @@ -10016,6 +10039,22 @@ dimensions = (horizontal_dimension,vertical_layer_dimension) type = real kind = kind_phys +[dkt_can] + standard_name = atmosphere_heat_diffusivity_in_canopy + long_name = atmospheric heat diffusivity in canopy + units = m2 s-1 + dimensions = (horizontal_dimension,vertical_layer_dimension) + type = real + kind = kind_phys + active = (flag_for_air_quality_coupling .and. flag_for_canopy_option) +[dku_can] + standard_name = atmosphere_momentum_diffusivity_in_canopy + long_name = atmospheric momentum diffusivity in canopy + units = m2 s-1 + dimensions = (horizontal_dimension,vertical_layer_dimension) + type = real + kind = kind_phys + active = (flag_for_air_quality_coupling .and. flag_for_canopy_option) [cldfra] standard_name = instantaneous_3d_cloud_fraction long_name = instantaneous 3D cloud fraction for all MPs