@@ -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
0 commit comments