Skip to content

Commit ec4517a

Browse files
authored
Merge pull request #1467 from PeterHjortLauritzen/frontogenesis-fv-fix
cam6_4_150: fix FV frontogenesis bug and diagnostic PS/PSDRY bug in SE log file
2 parents 38e4e80 + e1c1cc3 commit ec4517a

3 files changed

Lines changed: 187 additions & 5 deletions

File tree

doc/ChangeLog

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,82 @@
1+
2+
===============================================================
3+
4+
Tag name: cam6_4_150
5+
Originator(s): Jack Chen, Peter Lauritzen, cacraigucar
6+
Date: Feb 9, 2026
7+
One-line Summary: fix frontogenesis function bug for FV
8+
Github PR URL: https://github.com/ESCOMP/CAM/pull/1467
9+
10+
Purpose of changes (include the issue number and title text for each relevant GitHub issue):
11+
- Gradient computations for the fronotogenesis function were originally computed over terrain-following coordinate.
12+
Correction terms are added so gradients are on isobaric coordinates.
13+
- diagnostic PS and PSDRY computation in CAM-SE dycore written to log file is missing mass over model top.
14+
15+
16+
Describe any changes made to build system: N/A
17+
18+
Describe any changes made to the namelist: N/A
19+
20+
List any changes to the defaults for the boundary datasets: N/A
21+
22+
Describe any substantial timing or memory changes: N/A
23+
24+
Code reviewed by: cacraigucar
25+
26+
List all files eliminated: N/A
27+
28+
List all files added and what they do: N/A
29+
30+
List all existing files that have been modified, and describe the changes:
31+
M src/dynamics/fv/gravity_waves_sources.F90
32+
M src/dynamics/se/dycore/prim_state_mod.F90
33+
- Changes as described above
34+
35+
If there were any failures reported from running test_driver.sh on any test
36+
platform, and checkin with these failures has been OK'd by the gatekeeper,
37+
then copy the lines from the td.*.status files for the failed tests to the
38+
appropriate machine below. All failed tests must be justified.
39+
40+
derecho/intel/aux_cam:
41+
42+
FAIL ERI_D_Ln18.ne16pg3_ne16pg3_mt232.FHIST_C4.derecho_intel.cam-outfrq3s_eri
43+
- pre-existing failure
44+
- ERI test discovered a bug in CICE: See: https://github.com/ESCOMP/CESM_CICE/issues/34
45+
46+
ERP_Lh12.f19_f19_mg17.FW4madSD.derecho_intel.cam-outfrq3h (Overall: DIFF) details:
47+
ERP_Ln9.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq9s (Overall: DIFF) details:
48+
ERP_Ln9.f19_f19_mg17.FWsc1850.derecho_intel.cam-outfrq9s (Overall: DIFF) details:
49+
ERS_Ln9.f09_f09_mg17.FX2000.derecho_intel.cam-outfrq9s (Overall: DIFF) details:
50+
ERS_Ln9.f19_f19_mg17.FXSD.derecho_intel.cam-outfrq9s (Overall: DIFF) details:
51+
SMS_D_Ln9.f09_f09_mg17.FCts2nudged.derecho_intel.cam-outfrq9s_leapday (Overall: DIFF) details:
52+
SMS_D_Ln9.f09_f09_mg17.FCvbsxHIST.derecho_intel.cam-outfrq9s (Overall: DIFF) details:
53+
SMS_D_Ln9.f19_f19_mg17.FCARMA2000climo.derecho_intel.cam-outfrq9s (Overall: DIFF) details:
54+
SMS_D_Ln9.f19_f19_mg17.FWma2000climo.derecho_intel.cam-outfrq9s (Overall: DIFF) details:
55+
SMS_D_Ln9.f19_f19_mg17.FWma2000climo.derecho_intel.cam-outfrq9s_waccm_ma_mam4 (Overall: DIFF) details:
56+
SMS_D_Ln9.f19_f19_mg17.QPC2000climo.derecho_intel.cam-outfrq3s_usecase (Overall: DIFF) details:
57+
SMS_Ld1.f09_f09_mg17.FCHIST_GC.derecho_intel.cam-outfrq1d (Overall: DIFF) details:
58+
SMS_Ld1.f09_f09_mg17.FW2000climo.derecho_intel.cam-outfrq1d (Overall: DIFF) details:
59+
SMS_Lh12.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq3h (Overall: DIFF) details:
60+
SMS_Ln9.f09_f09_mg17.FW1850.derecho_intel.cam-reduced_hist3s (Overall: DIFF) details:
61+
- Answer changes for FV expected
62+
63+
derecho/nvhpc/aux_cam: all pass
64+
65+
izumi/nag/aux_cam:
66+
ERC_D_Ln9.f10_f10_mg37.QPWmaC6.izumi_nag.cam-outfrq3s (Overall: DIFF) details:
67+
- Answer changes for FV expected
68+
69+
izumi/gnu/aux_cam:
70+
ERC_D_Ln9.f10_f10_mg37.QPC4.izumi_gnu.cam-outfrq3s_diags (Overall: DIFF) details:
71+
SMS_D_Ln9.f10_f10_mg37.FWmaHIST.izumi_gnu.cam-outfrq9s_mee_fluxes (Overall: DIFF) details:
72+
SMS_D_Ln9.f10_f10_mg37.QPWmaC4.izumi_gnu.cam-outfrq9s_apmee (Overall: DIFF) details:
73+
SMS_D_Ln9.f19_f19_mt232.FW4madSD.izumi_gnu.cam-outfrq9s (Overall: DIFF) details:
74+
- Answer changes for FV expected
75+
76+
Summarize any changes to answers:
77+
FV answers differences are climate changing - ACOM will need to retune at a future date
78+
79+
===============================================================
180
===============================================================
281

382
Tag name: cam6_4_149

src/dynamics/fv/gravity_waves_sources.F90

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ subroutine gws_src_fnct(grid, u3,v3,pt, q3, pe, frontgf, frontga)
5858
real(r8) :: ug(grid%ifirstxy-1:grid%ilastxy+1,plev,grid%jfirstxy-1:grid%jlastxy+1) ! U-wind ghosted
5959
real(r8) :: vg(grid%ifirstxy-1:grid%ilastxy+1,plev,grid%jfirstxy-1:grid%jlastxy+1) ! V-wind ghosted
6060

61+
real(r8) :: pmg(grid%ifirstxy-1:grid%ilastxy+1,plev,grid%jfirstxy-1:grid%jlastxy+1) ! mid-point pressure ghosted
62+
real(r8) :: dptdp(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)
63+
real(r8) :: dudp(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)
64+
real(r8) :: dvdp(grid%ifirstxy:grid%ilastxy,plev,grid%jfirstxy:grid%jlastxy)
65+
6166
real(r8) :: tglat ! tangent-latitude
6267
integer :: i,j,k
6368
integer :: im, ip
@@ -100,6 +105,12 @@ subroutine gws_src_fnct(grid, u3,v3,pt, q3, pe, frontgf, frontga)
100105
call ghost_array(grid, u3, ug)
101106
call ghost_array(grid, v3, vg)
102107

108+
call ghost_array(grid, pm, pmg)
109+
110+
call compute_vertical_derivative(grid,pe,pm,ptemp,dptdp)
111+
call compute_vertical_derivative(grid,pe,pm,u3,dudp)
112+
call compute_vertical_derivative(grid,pe,pm,v3,dvdp)
113+
103114
!$omp parallel do private (i,j,k)
104115
do k=1, plev
105116
do i=beglonxy, endlonxy
@@ -108,15 +119,32 @@ subroutine gws_src_fnct(grid, u3,v3,pt, q3, pe, frontgf, frontga)
108119
! Pot. Temperature
109120
pty(i,k,j) = ( ptg(i,k,j+1) - ptg(i,k,j-1) ) / (2._r8 * grid%dp)
110121
pty(i,k,j) = pty(i,k,j) / aearth
122+
!
123+
! Topography/isobaric correction term:
124+
! The horizontal temperature gradient for the frontogenesis function is initially
125+
! computed in terrain-following coordinates. Correction terms are then applied to
126+
! convert it to an isobaric (pressure) surface reference. The same correction is
127+
! performed for the wind component terms.
128+
!
129+
pty(i,k,j) = pty(i,k,j) - dptdp(i,k,j) * &
130+
( pmg(i,k,j+1) - pmg(i,k,j-1) ) / (2._r8 * grid%dp) / aearth
111131

112132
! U-wind
113133
uy(i,k,j) = ( ug(i,k,j+1) - ug(i,k,j-1) ) / (2._r8 * grid%dp)
114134
uy(i,k,j) = uy(i,k,j) / aearth
115135

136+
! Topography correction term
137+
uy(i,k,j) = uy(i,k,j) - dudp(i,k,j) * &
138+
( pmg(i,k,j+1) - pmg(i,k,j-1) ) / (2._r8 * grid%dp) / aearth
139+
116140
! V-wind
117141
vy(i,k,j) = ( vg(i,k,j+1) - vg(i,k,j-1) ) / (2._r8 * grid%dp)
118142
vy(i,k,j) = vy(i,k,j) / aearth
119143

144+
! Topography correction term
145+
vy(i,k,j) = vy(i,k,j) - dvdp(i,k,j) * &
146+
( pmg(i,k,j+1) - pmg(i,k,j-1) ) / (2._r8 * grid%dp) / aearth
147+
120148
end do
121149
end do
122150
end do
@@ -135,14 +163,26 @@ subroutine gws_src_fnct(grid, u3,v3,pt, q3, pe, frontgf, frontga)
135163
ptx(i,k,j) = ( ptg(ip,k,j) - ptg(im,k,j) ) / (2._r8 * grid%dl)
136164
ptx(i,k,j) = ptx(i,k,j) / (aearth * (grid%cosp(j)+1.e-3_r8))
137165

166+
! Topography correction
167+
ptx(i,k,j) = ptx(i,k,j) - dptdp(i,k,j) * &
168+
( pmg(ip,k,j) - pmg(im,k,j) )/(2._r8 * grid%dl)/(aearth * (grid%cosp(j)+1.e-3_r8))
169+
138170
! U-wind
139171
ux(i,k,j) = ( ug(ip,k,j) - ug(im,k,j) ) / (2._r8 *grid%dl)
172+
! Topography correction
140173
ux(i,k,j) = ux(i,k,j) / (aearth * (grid%cosp(j)+1.e-3_r8))
141174

175+
! Topography correction
176+
ux(i,k,j) = ux(i,k,j) - dudp(i,k,j) * &
177+
( pmg(ip,k,j) - pmg(im,k,j) )/(2._r8 * grid%dl)/(aearth * (grid%cosp(j)+1.e-3_r8))
178+
142179
! V-wind
143180
vx(i,k,j) = ( vg(ip,k,j) - vg(im,k,j) ) / (2._r8 *grid%dl)
144181
vx(i,k,j) = vx(i,k,j) / (aearth * (grid%cosp(j)+1.e-3_r8))
145182

183+
! Topography correction
184+
vx(i,k,j) = vx(i,k,j) - dvdp(i,k,j) * &
185+
( pmg(ip,k,j) - pmg(im,k,j) )/(2._r8 * grid%dl)/(aearth * (grid%cosp(j)+1.e-3_r8))
146186
end do
147187
end do
148188
end do
@@ -180,6 +220,66 @@ subroutine gws_src_fnct(grid, u3,v3,pt, q3, pe, frontgf, frontga)
180220

181221
end subroutine gws_src_fnct
182222

223+
subroutine compute_vertical_derivative(grid,pint,pmid,data,ddata_dp)
224+
!---------------------------------------------------------------------------
225+
use dynamics_vars, only: t_fvdycore_grid
226+
227+
type (t_fvdycore_grid), intent(in) :: grid ! grid for XY decomp
228+
real(r8), intent(in ) :: pint(grid%ifirstxy:grid%ilastxy,plevp,grid%jfirstxy:grid%jlastxy) ! interface pressure
229+
real(r8), intent(in ) :: pmid(grid%ifirstxy:grid%ilastxy ,plev,grid%jfirstxy:grid%jlastxy) ! mid-point pressure
230+
real(r8), intent(in ) :: data(grid%ifirstxy:grid%ilastxy ,plev,grid%jfirstxy:grid%jlastxy)
231+
real(r8), intent(out) :: ddata_dp(grid%ifirstxy:grid%ilastxy ,plev,grid%jfirstxy:grid%jlastxy)
232+
!---------------------------------------------------------------------------
233+
integer :: i,j,k
234+
real(r8) :: pint_above ! pressure interpolated to interface above the current k mid-point
235+
real(r8) :: pint_below ! pressure interpolated to interface below the current k mid-point
236+
real(r8) :: dint_above ! data interpolated to interface above the current k mid-point
237+
real(r8) :: dint_below ! data interpolated to interface below the current k mid-point
238+
integer :: beglatxy, endlatxy, beglonxy, endlonxy
239+
!---------------------------------------------------------------------------
240+
beglatxy = grid%jfirstxy
241+
endlatxy = grid%jlastxy
242+
beglonxy = grid%ifirstxy
243+
endlonxy = grid%ilastxy
244+
245+
!$omp parallel do private (i,j,k,pint_above,pint_below,dint_above,dint_below)
246+
do j = beglatxy, endlatxy
247+
do k = 2, plev-1
248+
do i = beglonxy, endlonxy
249+
pint_above = pint(i,k,j)
250+
pint_below = pint(i,k+1,j)
251+
dint_above = ( data(i,k-1,j) + data(i,k,j) ) / 2.0_r8
252+
dint_below = ( data(i,k+1,j) + data(i,k,j) ) / 2.0_r8
253+
ddata_dp(i,k,j) = ( dint_above - dint_below ) / ( pint_above - pint_below )
254+
end do
255+
end do
256+
end do
257+
258+
k = 1
259+
!$omp parallel do private (i,j,pint_above,pint_below,dint_above,dint_below)
260+
do j = beglatxy, endlatxy
261+
do i = beglonxy, endlonxy
262+
pint_above = pmid(i,k,j)
263+
pint_below = pint(i,k+1,j)
264+
dint_above = data(i,k,j)
265+
dint_below = ( data(i,k+1,j) + data(i,k,j) ) / 2.0_r8
266+
ddata_dp(i,k,j) = ( dint_above - dint_below ) / ( pint_above - pint_below )
267+
end do
268+
end do
269+
270+
k = plev
271+
!$omp parallel do private (i,j,pint_above,pint_below,dint_above,dint_below)
272+
do j = beglatxy, endlatxy
273+
do i = beglonxy, endlonxy
274+
pint_above = pint(i,k,j)
275+
pint_below = pmid(i,k,j)
276+
dint_above = ( data(i,k-1,j) + data(i,k,j) ) / 2.0_r8
277+
dint_below = data(i,k,j)
278+
ddata_dp(i,k,j) = ( dint_above - dint_below ) / ( pint_above - pint_below )
279+
end do
280+
end do
281+
end subroutine compute_vertical_derivative
282+
183283
subroutine ghost_array(grid, x, xg)
184284

185285
! subroutine added by Francis Vitt -- 7 July 2008

src/dynamics/se/dycore/prim_state_mod.F90

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ subroutine prim_printstate(elem, tl,hybrid,nets,nete, fvm, omega_cn)
2727
use se_dyn_time_mod, only: tstep
2828
use control_mod, only: rsplit, qsplit
2929
use perf_mod, only: t_startf, t_stopf
30+
use hycoef, only: hyai, ps0
3031
type (element_t), intent(inout) :: elem(:)
3132
type (TimeLevel_t), target, intent(in) :: tl
3233
type (hybrid_t), intent(in) :: hybrid
@@ -62,7 +63,7 @@ subroutine prim_printstate(elem, tl,hybrid,nets,nete, fvm, omega_cn)
6263
! moist surface pressure
6364
if (use_cslam) then
6465
do ie=nets,nete
65-
moist_ps_fvm(:,:,ie)=SUM(fvm(ie)%dp_fvm(1:nc,1:nc,:),DIM=3)
66+
moist_ps_fvm(:,:,ie)=SUM(fvm(ie)%dp_fvm(1:nc,1:nc,:),DIM=3)+hyai(1)*ps0
6667
do q=dry_air_species_num+1,thermodynamic_active_species_num
6768
m_cnst = thermodynamic_active_species_idx(q)
6869
do k=1,nlev
@@ -134,8 +135,8 @@ subroutine prim_printstate(elem, tl,hybrid,nets,nete, fvm, omega_cn)
134135
max_local(ie,5) = 0.0_r8
135136
end if
136137
if (use_cslam) then
137-
min_local(ie,6) = MINVAL(SUM(fvm(ie)%dp_fvm(1:nc,1:nc,:),DIM=3))
138-
max_local(ie,6) = MAXVAL(SUM(fvm(ie)%dp_fvm(1:nc,1:nc,:),DIM=3))
138+
min_local(ie,6) = MINVAL(SUM(fvm(ie)%dp_fvm(1:nc,1:nc,:),DIM=3))+hyai(1)*ps0
139+
max_local(ie,6) = MAXVAL(SUM(fvm(ie)%dp_fvm(1:nc,1:nc,:),DIM=3))+hyai(1)*ps0
139140
min_local(ie,7) = MINVAL(moist_ps_fvm(:,:,ie))
140141
max_local(ie,7) = MINVAL(moist_ps_fvm(:,:,ie))
141142
min_local(ie,8) = MINVAL(elem(ie)%state%psdry(:,:))
@@ -207,7 +208,7 @@ subroutine prim_printstate(elem, tl,hybrid,nets,nete, fvm, omega_cn)
207208
tmp_fvm(:,:,q,ie) = SUM(fvm(ie)%c(1:nc,1:nc,:,q)*fvm(ie)%dp_fvm(1:nc,1:nc,:),DIM=3)
208209
end do
209210
q=statediag_numtrac+1
210-
tmp_fvm(:,:,q,ie) = SUM(fvm(ie)%dp_fvm(1:nc,1:nc,:),DIM=3)
211+
tmp_fvm(:,:,q,ie) = SUM(fvm(ie)%dp_fvm(1:nc,1:nc,:),DIM=3)+hyai(1)*ps0
211212
q=statediag_numtrac+2
212213
tmp_fvm(:,:,q,ie) = moist_ps_fvm(:,:,ie)
213214
end do
@@ -291,7 +292,9 @@ subroutine prim_printstate(elem, tl,hybrid,nets,nete, fvm, omega_cn)
291292
101 format (A12,A23,A23,A23,A23)
292293

293294
#ifdef waccm_debug
294-
call prim_printstate_cslam_gamma(elem, tl,hybrid,nets,nete, fvm)
295+
if (use_cslam) then
296+
call prim_printstate_cslam_gamma(elem, tl,hybrid,nets,nete, fvm)
297+
end if
295298
#endif
296299
call prim_printstate_U(elem, tl,hybrid,nets,nete, fvm)
297300
end subroutine prim_printstate

0 commit comments

Comments
 (0)