From 5c4dfa73ab828b91d9adbbde14886f1ae63a696b Mon Sep 17 00:00:00 2001 From: Matus Martini Date: Thu, 14 May 2026 04:18:11 -0700 Subject: [PATCH 1/5] GW multiplication factors scaled by inverse square root of dx (#82) * Scale cdmb with the inverse square root of dxres in ugwp_v0 * Scale cleff with the inverse square root of dxres in ugwp_v0 * Replace the non-ascii 1/2 with its ascii representation to satisfy ci test requirement. --- physics/GWD/cires_ugwp.F90 | 5 +++-- physics/GWD/cires_ugwp.meta | 8 ++++++++ physics/GWD/ugwp_driver_v0.F90 | 7 ++++++- physics/PBL/SATMEDMF/canopy_levs.F90 | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/physics/GWD/cires_ugwp.F90 b/physics/GWD/cires_ugwp.F90 index f9ee82c50..9ac0c1a5c 100644 --- a/physics/GWD/cires_ugwp.F90 +++ b/physics/GWD/cires_ugwp.F90 @@ -188,7 +188,7 @@ 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, & + do_tofd, ldiag_ugwp, cdmbgwd, cdmbgwd0, 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, & @@ -216,6 +216,7 @@ subroutine cires_ugwp_run(do_ugwp, me, master, im, levs, ntrac, dtp, kdt, lonr real(kind=kind_phys), intent(in), dimension(:, :) :: prsi, phii real(kind=kind_phys), intent(in), dimension(:,:,:):: qgrs real(kind=kind_phys), intent(in) :: dtp, cdmbgwd(:) + real(kind=kind_phys), intent(in) :: cdmbgwd0(:) logical, intent(in) :: do_ugwp, do_tofd, ldiag_ugwp real(kind=kind_phys), intent(out), dimension(:) :: dusfcg, dvsfcg @@ -293,7 +294,7 @@ subroutine cires_ugwp_run(do_ugwp, me, master, im, levs, ntrac, dtp, kdt, lonr call GWDPS_V0(im, levs, lonr, do_tofd, Pdvdt, Pdudt, Pdtdt, Pkdis, & ugrs, vgrs, tgrs, qgrs(:,:,1), kpbl, prsi,del,prsl, prslk, phii, phil, & dtp, kdt, sgh30, hprime, oc, oa4, clx, theta, sigma, gamma, elvmax, & - dusfcg, dvsfcg, xlat_d, sinlat, coslat, area, cdmbgwd(1:2), & + dusfcg, dvsfcg, xlat_d, sinlat, coslat, area, cdmbgwd(1:2), cdmbgwd0, & me, master, rdxzb, zmtb, zogw, tau_mtb, tau_ogw, & tau_tofd, dudt_mtb, dudt_ogw, dudt_tms, & errmsg, errflg) diff --git a/physics/GWD/cires_ugwp.meta b/physics/GWD/cires_ugwp.meta index f16ec7ce7..510ae2f56 100644 --- a/physics/GWD/cires_ugwp.meta +++ b/physics/GWD/cires_ugwp.meta @@ -358,6 +358,14 @@ type = real kind = kind_phys intent = in +[cdmbgwd0] + standard_name = multiplicative_tunable_parameters_for_mountain_blocking_and_orographic_gravity_wave_drag_for_ugwp_version_0 + long_name = multiplication factors for cdmb and gwd for UGWP v0 + units = none + dimensions = (2) + type = real + kind = kind_phys + intent = in [xlat] standard_name = latitude long_name = grid latitude diff --git a/physics/GWD/ugwp_driver_v0.F90 b/physics/GWD/ugwp_driver_v0.F90 index fdbe35d5f..d3ffb5d34 100644 --- a/physics/GWD/ugwp_driver_v0.F90 +++ b/physics/GWD/ugwp_driver_v0.F90 @@ -30,7 +30,7 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & PRSI,DEL,PRSL,PRSLK,PHII, PHIL,DTP,KDT, & sgh30, HPRIME,OC,OA4,CLX4,THETA,vSIGMA,vGAMMA,ELVMAXD, & DUSFC, DVSFC, xlatd, sinlat, coslat, sparea, & - cdmbgwd, me, master, rdxzb, & + cdmbgwd, cdmbgwd0, me, master, rdxzb, & zmtb, zogw, tau_mtb, tau_ogw, tau_tofd, & dudt_mtb, dudt_ogw, dudt_tms, errmsg,errflg ) !---------------------------------------- @@ -89,6 +89,7 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & integer, intent(in) :: KPBL(IM) ! Index for the PBL top layer! real(kind=kind_phys), intent(in) :: dtp ! time step real(kind=kind_phys), intent(in) :: cdmbgwd(2) + real(kind=kind_phys), intent(in) :: cdmbgwd0(2) ! Namelist parameters used to scale MB and GWD real(kind=kind_phys), intent(in), dimension(im,km) :: & u1, v1, t1, q1, del, prsl, prslk, phil @@ -485,6 +486,8 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & sigres = max(sigmin, sigma(J)) if (hprime(J)/sigres > dxres) sigres = hprime(J)/dxres mtbridge = ZR * sigres*ZLEN / hprime(J) + ! Scale the drag coefficient by the inverse square root of dxres + cdmb4 = cdmbgwd0(1) / sqrt(sqrt(sparea(j))) ! dbtmp = cdmb4*mtbridge*max(cos(ang(i,k)), gamma(j)*sin(ang(i,k))) ! (4.15)-ifs dbtmp = cdmb4*mtbridge*(bgam * cosang2 + cgam * sinang2) ! (4.16)-ifs DB(I,K)= DBTMP * UDS(I,K) @@ -624,6 +627,8 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & ! COEFM = (1. + CLX(I)) ** (OA(I)+1.) ! + ! Scale the cleff coefficient by the inverse square root of dxres + cleff = cdmbgwd0(2) / sqrt(sqrt(sparea(j))) XLINV(I) = COEFM * CLEFF ! effective kxw for Lin-wave XLINGFS = COEFM * CLEFF ! diff --git a/physics/PBL/SATMEDMF/canopy_levs.F90 b/physics/PBL/SATMEDMF/canopy_levs.F90 index 87a139d48..18cfa27d8 100644 --- a/physics/PBL/SATMEDMF/canopy_levs.F90 +++ b/physics/PBL/SATMEDMF/canopy_levs.F90 @@ -780,7 +780,7 @@ subroutine canopy_levs_run(im, km, nkc, nkt, & ! Note that these changes only exist inside the chemistry part of GEM-MACH and do not affect the model physics !!! !!! Create the momentum height (layer interface) array. The original momentum layers are used above the canopy height. -!!! Below the canopy height, the "momentum" layers are assumed to be ½ way between the thermodynamic layers. +!!! Below the canopy height, the "momentum" layers are assumed to be 1/2 way between the thermodynamic layers. ! Default case: all added canopy thermodynamic layers are below the lowest resolved model thermodynamic layer ! kcan_top is either 2nd or 3rd (63 or 62) resolved model layer From 17182da326af21a1ec15244c0ca30d4a81da94e3 Mon Sep 17 00:00:00 2001 From: Matus Martini Date: Fri, 15 May 2026 13:59:55 -0700 Subject: [PATCH 2/5] Unify cdmbgwd0 and cdmbgwd (#83) * Make cdmbgwd0 to be rank 4 * Unify cdmbgwd0 and cdmbgwd --- physics/GWD/cires_ugwp.F90 | 5 ++--- physics/GWD/cires_ugwp.meta | 8 -------- physics/GWD/ugwp_driver_v0.F90 | 11 +++++------ 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/physics/GWD/cires_ugwp.F90 b/physics/GWD/cires_ugwp.F90 index 9ac0c1a5c..f9ee82c50 100644 --- a/physics/GWD/cires_ugwp.F90 +++ b/physics/GWD/cires_ugwp.F90 @@ -188,7 +188,7 @@ 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, cdmbgwd0, xlat, xlat_d, sinlat, coslat, & + 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, & @@ -216,7 +216,6 @@ subroutine cires_ugwp_run(do_ugwp, me, master, im, levs, ntrac, dtp, kdt, lonr real(kind=kind_phys), intent(in), dimension(:, :) :: prsi, phii real(kind=kind_phys), intent(in), dimension(:,:,:):: qgrs real(kind=kind_phys), intent(in) :: dtp, cdmbgwd(:) - real(kind=kind_phys), intent(in) :: cdmbgwd0(:) logical, intent(in) :: do_ugwp, do_tofd, ldiag_ugwp real(kind=kind_phys), intent(out), dimension(:) :: dusfcg, dvsfcg @@ -294,7 +293,7 @@ subroutine cires_ugwp_run(do_ugwp, me, master, im, levs, ntrac, dtp, kdt, lonr call GWDPS_V0(im, levs, lonr, do_tofd, Pdvdt, Pdudt, Pdtdt, Pkdis, & ugrs, vgrs, tgrs, qgrs(:,:,1), kpbl, prsi,del,prsl, prslk, phii, phil, & dtp, kdt, sgh30, hprime, oc, oa4, clx, theta, sigma, gamma, elvmax, & - dusfcg, dvsfcg, xlat_d, sinlat, coslat, area, cdmbgwd(1:2), cdmbgwd0, & + dusfcg, dvsfcg, xlat_d, sinlat, coslat, area, cdmbgwd(1:2), & me, master, rdxzb, zmtb, zogw, tau_mtb, tau_ogw, & tau_tofd, dudt_mtb, dudt_ogw, dudt_tms, & errmsg, errflg) diff --git a/physics/GWD/cires_ugwp.meta b/physics/GWD/cires_ugwp.meta index 510ae2f56..f16ec7ce7 100644 --- a/physics/GWD/cires_ugwp.meta +++ b/physics/GWD/cires_ugwp.meta @@ -358,14 +358,6 @@ type = real kind = kind_phys intent = in -[cdmbgwd0] - standard_name = multiplicative_tunable_parameters_for_mountain_blocking_and_orographic_gravity_wave_drag_for_ugwp_version_0 - long_name = multiplication factors for cdmb and gwd for UGWP v0 - units = none - dimensions = (2) - type = real - kind = kind_phys - intent = in [xlat] standard_name = latitude long_name = grid latitude diff --git a/physics/GWD/ugwp_driver_v0.F90 b/physics/GWD/ugwp_driver_v0.F90 index d3ffb5d34..d1ec02118 100644 --- a/physics/GWD/ugwp_driver_v0.F90 +++ b/physics/GWD/ugwp_driver_v0.F90 @@ -30,7 +30,7 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & PRSI,DEL,PRSL,PRSLK,PHII, PHIL,DTP,KDT, & sgh30, HPRIME,OC,OA4,CLX4,THETA,vSIGMA,vGAMMA,ELVMAXD, & DUSFC, DVSFC, xlatd, sinlat, coslat, sparea, & - cdmbgwd, cdmbgwd0, me, master, rdxzb, & + cdmbgwd, me, master, rdxzb, & zmtb, zogw, tau_mtb, tau_ogw, tau_tofd, & dudt_mtb, dudt_ogw, dudt_tms, errmsg,errflg ) !---------------------------------------- @@ -89,7 +89,6 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & integer, intent(in) :: KPBL(IM) ! Index for the PBL top layer! real(kind=kind_phys), intent(in) :: dtp ! time step real(kind=kind_phys), intent(in) :: cdmbgwd(2) - real(kind=kind_phys), intent(in) :: cdmbgwd0(2) ! Namelist parameters used to scale MB and GWD real(kind=kind_phys), intent(in), dimension(im,km) :: & u1, v1, t1, q1, del, prsl, prslk, phil @@ -486,8 +485,8 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & sigres = max(sigmin, sigma(J)) if (hprime(J)/sigres > dxres) sigres = hprime(J)/dxres mtbridge = ZR * sigres*ZLEN / hprime(J) - ! Scale the drag coefficient by the inverse square root of dxres - cdmb4 = cdmbgwd0(1) / sqrt(sqrt(sparea(j))) + ! Scale the blocking coefficient by the inverse square root of dxres + cdmb4 = cdmbgwd(1) / sqrt(sqrt(sparea(j))) ! dbtmp = cdmb4*mtbridge*max(cos(ang(i,k)), gamma(j)*sin(ang(i,k))) ! (4.15)-ifs dbtmp = cdmb4*mtbridge*(bgam * cosang2 + cgam * sinang2) ! (4.16)-ifs DB(I,K)= DBTMP * UDS(I,K) @@ -626,9 +625,9 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & EFACT = MIN( MAX(EFACT,EFMIN), EFMAX ) ! COEFM = (1. + CLX(I)) ** (OA(I)+1.) -! + ! Scale the cleff coefficient by the inverse square root of dxres - cleff = cdmbgwd0(2) / sqrt(sqrt(sparea(j))) + cleff = cdmbgwd(2) / sqrt(sqrt(sparea(j))) XLINV(I) = COEFM * CLEFF ! effective kxw for Lin-wave XLINGFS = COEFM * CLEFF ! From 7ff8e063df72669466835788811cf89e2f782d8b Mon Sep 17 00:00:00 2001 From: Matus Martini Date: Thu, 21 May 2026 13:54:24 +0000 Subject: [PATCH 3/5] Remove unnecessary line --- physics/GWD/ugwp_driver_v0.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/physics/GWD/ugwp_driver_v0.F90 b/physics/GWD/ugwp_driver_v0.F90 index d1ec02118..39d3aea30 100644 --- a/physics/GWD/ugwp_driver_v0.F90 +++ b/physics/GWD/ugwp_driver_v0.F90 @@ -483,7 +483,6 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & R = sqrt(rnom/rdem) ZR = MAX( 2. - R, 0. ) sigres = max(sigmin, sigma(J)) - if (hprime(J)/sigres > dxres) sigres = hprime(J)/dxres mtbridge = ZR * sigres*ZLEN / hprime(J) ! Scale the blocking coefficient by the inverse square root of dxres cdmb4 = cdmbgwd(1) / sqrt(sqrt(sparea(j))) From 3a5fb9cd8a0e34b2445e3c555d748d15e5afee74 Mon Sep 17 00:00:00 2001 From: Matus Martini Date: Tue, 26 May 2026 17:13:23 +0000 Subject: [PATCH 4/5] Multiply coefficients by a power of 10 --- physics/GWD/ugwp_driver_v0.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/physics/GWD/ugwp_driver_v0.F90 b/physics/GWD/ugwp_driver_v0.F90 index 39d3aea30..8b37f9a35 100644 --- a/physics/GWD/ugwp_driver_v0.F90 +++ b/physics/GWD/ugwp_driver_v0.F90 @@ -485,7 +485,7 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & sigres = max(sigmin, sigma(J)) mtbridge = ZR * sigres*ZLEN / hprime(J) ! Scale the blocking coefficient by the inverse square root of dxres - cdmb4 = cdmbgwd(1) / sqrt(sqrt(sparea(j))) + cdmb4 = cdmbgwd(1) * 100.0 / sqrt(sqrt(sparea(j))) ! dbtmp = cdmb4*mtbridge*max(cos(ang(i,k)), gamma(j)*sin(ang(i,k))) ! (4.15)-ifs dbtmp = cdmb4*mtbridge*(bgam * cosang2 + cgam * sinang2) ! (4.16)-ifs DB(I,K)= DBTMP * UDS(I,K) @@ -626,7 +626,7 @@ SUBROUTINE GWDPS_V0(IM, km, imx, do_tofd, & COEFM = (1. + CLX(I)) ** (OA(I)+1.) ! Scale the cleff coefficient by the inverse square root of dxres - cleff = cdmbgwd(2) / sqrt(sqrt(sparea(j))) + cleff = cdmbgwd(2) * 0.001 / sqrt(sqrt(sparea(j))) XLINV(I) = COEFM * CLEFF ! effective kxw for Lin-wave XLINGFS = COEFM * CLEFF ! From 06fd5c29b56d43e163f22eac7366c6946f6096e1 Mon Sep 17 00:00:00 2001 From: Grant Firl Date: Wed, 17 Jun 2026 16:26:55 -0400 Subject: [PATCH 5/5] add Alex and Matus as codeowners for ugwp_v0 --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 61ee44df8..30e2f3aea 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -30,7 +30,7 @@ physics/GWD/drag_suite.* @md physics/GWD/gwdc.* @Songyou184 @grantfirl @rhaesung @Qingfu-Liu @dustinswales physics/GWD/gwdps.* @Songyou184 @grantfirl @rhaesung @Qingfu-Liu @dustinswales physics/GWD/rayleigh_damp.* @yangfanglin @grantfirl @rhaesung @Qingfu-Liu @dustinswales -physics/GWD/ugwp_driver_v0.F90 @mdtoyNOAA @grantfirl @rhaesung @Qingfu-Liu @dustinswales +physics/GWD/ugwp_driver_v0.F90 @mdtoyNOAA @matusmartini @areinecke @grantfirl @rhaesung @Qingfu-Liu @dustinswales physics/GWD/ugwpv1_gsldrag.* @mdtoyNOAA @BoYang-NOAA @grantfirl @rhaesung @Qingfu-Liu @dustinswales physics/GWD/ugwpv1_gsldrag_post.* @mdtoyNOAA @BoYang-NOAA @grantfirl @rhaesung @Qingfu-Liu @dustinswales physics/GWD/unified_ugwp* @mdtoyNOAA @grantfirl @rhaesung @Qingfu-Liu @dustinswales