@@ -38,7 +38,7 @@ subroutine gws_init(elem)
3838
3939 end subroutine gws_init
4040 !- ------------------------------------------------------------------------------------------------
41- subroutine gws_src_fnct (elem , tl , nphys , use_fgf_pgrad_correction , frontgf , frontga )
41+ subroutine gws_src_fnct (elem , tl , nphys , use_fgf_pgrad_correction , use_fgf_zgrad_correction , frontgf , frontga )
4242 use dimensions_mod, only : npsq, nelemd
4343 use dof_mod, only : UniquePoints
4444 use dyn_comp, only : dom_mt
@@ -52,6 +52,7 @@ subroutine gws_src_fnct(elem, tl, nphys, use_fgf_pgrad_correction, frontgf, fron
5252 integer , intent (in ) :: tl
5353 integer , intent (in ) :: nphys
5454 logical , intent (in ) :: use_fgf_pgrad_correction
55+ logical , intent (in ) :: use_fgf_zgrad_correction
5556 real (kind= real_kind), intent (out ) :: frontgf(nphys* nphys,pver,nelemd)
5657 real (kind= real_kind), intent (out ) :: frontga(nphys* nphys,pver,nelemd)
5758
@@ -68,7 +69,10 @@ subroutine gws_src_fnct(elem, tl, nphys, use_fgf_pgrad_correction, frontgf, fron
6869 hybrid = hybrid_create(par,ithr,hthreads)
6970 allocate (frontgf_thr(nphys,nphys,nlev,nets:nete))
7071 allocate (frontga_thr(nphys,nphys,nlev,nets:nete))
71- call compute_frontogenesis(frontgf_thr,frontga_thr,tl,use_fgf_pgrad_correction,elem,hybrid,nets,nete,nphys)
72+ call compute_frontogenesis( frontgf_thr, frontga_thr, tl, &
73+ use_fgf_pgrad_correction, &
74+ use_fgf_zgrad_correction, &
75+ elem, hybrid, nets, nete, nphys )
7276 if (fv_nphys> 0 ) then
7377 do ie = nets,nete
7478 do k = 1 ,nlev
@@ -89,7 +93,10 @@ subroutine gws_src_fnct(elem, tl, nphys, use_fgf_pgrad_correction, frontgf, fron
8993
9094 end subroutine gws_src_fnct
9195 !- ------------------------------------------------------------------------------------------------
92- subroutine compute_frontogenesis (frontgf ,frontga ,tl ,use_fgf_pgrad_correction ,elem ,hybrid ,nets ,nete ,nphys )
96+ subroutine compute_frontogenesis ( frontgf , frontga , tl , &
97+ use_fgf_pgrad_correction , &
98+ use_fgf_zgrad_correction , &
99+ elem , hybrid , nets , nete , nphys )
93100 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
94101 ! compute frontogenesis function F
95102 ! F = -gradth dot C
@@ -109,14 +116,14 @@ subroutine compute_frontogenesis(frontgf,frontga,tl,use_fgf_pgrad_correction,ele
109116 ! added pressure gradient correction
110117 !
111118 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
112- use physical_constants, only: kappa
119+ use physical_constants, only: kappa, g
113120 use derivative_mod, only: gradient_sphere, ugradv_sphere
114121 use edge_mod, only: edge_g, edgevpack_nlyr, edgevunpack_nlyr
115122 use bndry_mod, only: bndry_exchangev
116123 use dyn_comp, only: hvcoord
117124 use spmd_utils, only: iam
118125 use parallel_mod, only: par
119- use element_ops, only: get_temperature, get_hydro_pressure
126+ use element_ops, only: get_temperature, get_hydro_pressure, get_phi
120127 use dyn_grid, only: fv_nphys
121128 use prim_driver_mod, only: deriv1
122129 use gllfvremap_mod, only: gfr_g2f_scalar, gfr_g2f_vector
@@ -126,24 +133,27 @@ subroutine compute_frontogenesis(frontgf,frontga,tl,use_fgf_pgrad_correction,ele
126133 integer , intent (in ) :: nets,nete,nphys
127134 integer , intent (in ) :: tl ! timelevel to use
128135 logical , intent (in ) :: use_fgf_pgrad_correction
136+ logical , intent (in ) :: use_fgf_zgrad_correction
129137 real (kind= real_kind), intent (out ) :: frontgf(nphys,nphys,nlev,nets:nete)
130138 real (kind= real_kind), intent (out ) :: frontga(nphys,nphys,nlev,nets:nete)
131139
132140 ! local
133141 integer :: k,kptr,i,j,ie,component
134142 real (kind= real_kind) :: frontgf_gll(np,np,nlev,nets:nete)
135143 real (kind= real_kind) :: gradth_gll(np,np,2 ,nlev,nets:nete) ! grad(theta)
136- real (kind= real_kind) :: pmid(np,np,nlev) ! hydrostatic pressure at mid points
144+ real (kind= real_kind) :: pint(np,np,nlev) ! interface hydrostatic pressure
145+ real (kind= real_kind) :: pmid(np,np,nlev) ! mid-point hydrostatic pressure
137146 real (kind= real_kind) :: temperature(np,np,nlev) ! Temperature
138147 real (kind= real_kind) :: C(np,np,2 ), wf1(nphys* nphys,nlev), wf2(nphys* nphys,nlev)
139148
140- ! variables needed for eta to pressure surface correction
141- real (kind= real_kind) :: gradp_gll(np,np,2 ) ! grad(pressure)
142149 real (kind= real_kind) :: theta(np,np,nlev) ! potential temperature at mid points
143- real (kind= real_kind) :: dtheta_dp(np,np,nlev) ! d(theta)/dp for eta to pressure surface correction
144150 real (kind= real_kind) :: dum_grad(np,np,2 ) ! temporary variable for spherical gradient calcualtions
145151 real (kind= real_kind) :: dum_cart(np,np,3 ,nlev) ! temporary variable for cartesian gradient calcualtions
146- real (kind= real_kind) :: ddp_dum_cart(np,np,3 ,nlev) ! vertical pressure derivative of dum_cart
152+
153+ ! variables needed for eta to pressure surface correction
154+ real (kind= real_kind) :: grad_vert_gll(np,np,2 ,nlev) ! grad(vertical coordinate) - either pressure or geopotential
155+ real (kind= real_kind) :: theta_dvert(np,np,nlev) ! d(theta)/dp for eta to pressure surface correction
156+ real (kind= real_kind) :: dum_cart_dvert(np,np,3 ,nlev)! vertical pressure derivative of dum_cart
147157
148158 !- --------------------------------------------------------------------------
149159 !
@@ -178,23 +188,34 @@ subroutine compute_frontogenesis(frontgf,frontga,tl,use_fgf_pgrad_correction,ele
178188
179189 do ie = nets,nete
180190
181- if (use_fgf_pgrad_correction) then
191+ if (use_fgf_pgrad_correction .or. use_fgf_zgrad_correction ) then
182192
183- ! compute pressure at mid points
184- call get_hydro_pressure(pmid ,elem(ie)% state% dp3d(:,:,:,tl),hvcoord)
193+ ! compute pressure at interfaces and mid- points
194+ call get_hydro_pressure_interface(pint ,elem(ie)% state% dp3d(:,:,:,tl),hvcoord)
185195
186196 call get_temperature(elem(ie),temperature,hvcoord,tl)
197+
198+ ! calculate pmid and potential temperature: theta = T (p/p0)^kappa
187199 do k = 1 ,nlev
188- ! potential temperature: theta = T (p/p0)^kappa
200+ pmid(:,:,k) = pint(:,:,k) + elem(ie) % state % dp3d(:,:,k,tl) / 2
189201 theta(:,:,k) = temperature(:,:,k)* (psurf_ref / pmid(:,:,k))** kappa
190202 end do
191- call compute_vertical_derivative(tl,ie,elem,theta,dtheta_dp)
203+
204+ if (use_fgf_pgrad_correction) call compute_vertical_derivative(pint,theta,theta_dvert)
205+
206+ if (use_fgf_zgrad_correction) then
207+ call get_phi(elem(ie),phi_mid,phi_int,hvcoord,tl)
208+ zmid(:,:,:) = phi_mid(:,:,:)/ g
209+ zint(:,:,:) = phi_int(:,:,:)/ g
210+ call compute_vertical_derivative(zint,theta,theta_dvert)
211+ end if
192212
193213 do k = 1 ,nlev
194214 gradth_gll(:,:,:,k,ie) = gradient_sphere(theta(:,:,k),deriv1,elem(ie)% Dinv)
195- gradp_gll(:,:,:) = gradient_sphere(pmid(:,:,k),deriv1,elem(ie)% Dinv)
215+ if (use_fgf_pgrad_correction) grad_vert_gll(:,:,:,k) = gradient_sphere(pmid(:,:,k),deriv1,elem(ie)% Dinv)
216+ if (use_fgf_zgrad_correction) grad_vert_gll(:,:,:,k) = gradient_sphere(zmid(:,:,k),deriv1,elem(ie)% Dinv)
196217 do component= 1 ,2
197- gradth_gll(:,:,component,k,ie) = gradth_gll(:,:,component,k,ie) - dtheta_dp (:,:,k) * gradp_gll (:,:,component)
218+ gradth_gll(:,:,component,k,ie) = gradth_gll(:,:,component,k,ie) - theta_dvert (:,:,k) * grad_vert_gll (:,:,component,k )
198219 end do
199220 end do
200221
@@ -206,16 +227,15 @@ subroutine compute_frontogenesis(frontgf,frontga,tl,use_fgf_pgrad_correction,ele
206227 end do
207228
208229 do component= 1 ,3
209- call compute_vertical_derivative(tl,ie,elem,dum_cart(:,:,component,:),ddp_dum_cart (:,:,component,:))
230+ call compute_vertical_derivative(tl,ie,elem,dum_cart(:,:,component,:),dum_cart_dvert (:,:,component,:))
210231 end do
211232
212233 do k = 1 ,nlev
213- gradp_gll(:,:,:) = gradient_sphere(pmid(:,:,k),deriv1,elem(ie)% Dinv)
214234 ! Do ugradv on the cartesian components - Dot u with the gradient of each component
215235 do component= 1 ,3
216236 dum_grad(:,:,:) = gradient_sphere(dum_cart(:,:,component,k),deriv1,elem(ie)% Dinv)
217237 do i= 1 ,2
218- dum_grad(:,:,i) = dum_grad(:,:,i) - ddp_dum_cart (:,:,component,k) * gradp_gll (:,:,i)
238+ dum_grad(:,:,i) = dum_grad(:,:,i) - dum_cart_dvert (:,:,component,k) * grad_vert_gll (:,:,i,k )
219239 end do
220240 dum_cart(:,:,component,k) = sum ( gradth_gll(:,:,:,k,ie) * dum_grad ,3 )
221241 enddo
@@ -291,39 +311,36 @@ subroutine compute_frontogenesis(frontgf,frontga,tl,use_fgf_pgrad_correction,ele
291311
292312 end subroutine compute_frontogenesis
293313 !- ------------------------------------------------------------------------------------------------
294- subroutine compute_vertical_derivative (tl ,ie ,elem ,data ,ddata_dp )
295- use dyn_comp, only: hvcoord
314+ subroutine compute_vertical_derivative (vert_int , data_mid , ddata_dvert )
296315 !- --------------------------------------------------------------------------
297- integer , intent (in ) :: tl ! timelevel to use
298- integer , intent (in ) :: ie ! current element index
299- type (element_t),target , intent (inout ) :: elem(:)
300- real (kind= real_kind), intent (in ) :: data (np,np,nlev)
301- real (kind= real_kind), intent (out ) :: ddata_dp(np,np,nlev)
316+ real (kind= real_kind), intent (in ) :: vert_int(np,np,nlev) ! vertical coord on interfaces (i.e. pint or zint)
317+ real (kind= real_kind), intent (in ) :: data_mid(np,np,nlev) ! input data in mid-points
318+ real (kind= real_kind), intent (out ) :: ddata_dvert(np,np,nlev) ! vertical derivative of data
302319 !- --------------------------------------------------------------------------
303320 integer :: k
304- real (kind= real_kind) :: pint_above (np,np) ! pressure interpolated to interface above the current k mid-point
305- real (kind= real_kind) :: pint_below (np,np) ! pressure interpolated to interface below the current k mid-point
306- real (kind= real_kind) :: dint_above (np,np) ! data interpolated to interface above the current k mid-point
307- real (kind= real_kind) :: dint_below (np,np) ! data interpolated to interface below the current k mid-point
321+ real (kind= real_kind) :: vert_above (np,np) ! pressure interpolated to interface above the current k mid-point
322+ real (kind= real_kind) :: vert_below (np,np) ! pressure interpolated to interface below the current k mid-point
323+ real (kind= real_kind) :: data_above (np,np) ! data interpolated to interface above the current k mid-point
324+ real (kind= real_kind) :: data_below (np,np) ! data interpolated to interface below the current k mid-point
308325 !- --------------------------------------------------------------------------
309326 do k = 1 ,nlev
310327 if (k== 1 ) then
311- pint_above = hvcoord % hyam(k +0 ) * hvcoord % ps0 + hvcoord % hybm(k +0 ) * elem(ie) % state % ps_v( :,:,tl )
312- pint_below = hvcoord % hyai( k+1 )* hvcoord % ps0 + hvcoord % hybi(k +1 ) * elem(ie) % state % ps_v( :,:,tl)
313- dint_above = data ( :,:,k)
314- dint_below = ( data ( :,:,k+1 ) + data (:,:,k) ) / 2.0
328+ data_above = data_mid( :,:,k )
329+ data_below = ( data_mid(:,:, k+1 ) + data_mid( :,:,k) ) / 2.0 ! interpolate to interface k+1
330+ vert_above = ( vert_int( :,:,k+1 ) + vert_int(:,:,k) ) / 2.0 ! interpolate to mid-point k
331+ vert_below = vert_int( :,:,k+1 )
315332 elseif (k== nlev) then
316- pint_above = hvcoord % hyai(k +0 ) * hvcoord % ps0 + hvcoord % hybi(k +0 ) * elem(ie) % state % ps_v( :,:,tl)
317- pint_below = hvcoord % hyam(k +0 ) * hvcoord % ps0 + hvcoord % hybm(k +0 ) * elem(ie) % state % ps_v( :,:,tl )
318- dint_above = ( data ( :,:,k-1 ) + data (:,:,k) ) / 2.0
319- dint_below = data ( :,:,k)
333+ data_above = ( data_mid(:,:,k -1 ) + data_mid( :,:,k) ) / 2.0 ! interpolate to interface
334+ data_below = data_mid( :,:,k )
335+ vert_above = vert_int( :,:,k)
336+ vert_below = ( vert_int( :,:,k+1 ) + vert_int(:,:,k) ) / 2.0 ! interpolate to mid-point k
320337 else
321- pint_above = hvcoord % hyai(k +0 ) * hvcoord % ps0 + hvcoord % hybi(k +0 ) * elem(ie) % state % ps_v( :,:,tl)
322- pint_below = hvcoord % hyai( k+1 )* hvcoord % ps0 + hvcoord % hybi(k +1 ) * elem(ie) % state % ps_v( :,:,tl)
323- dint_above = ( data ( :,:,k-1 ) + data (:,:,k) ) / 2.0
324- dint_below = ( data ( :,:,k+1 ) + data (:,:,k) ) / 2.0
338+ data_above = ( data_mid(:,:,k -1 ) + data_mid( :,:,k) ) / 2.0 ! interpolate to interface k
339+ data_below = ( data_mid(:,:, k+1 ) + data_mid( :,:,k) ) / 2.0 ! interpolate to interface k+1
340+ vert_above = pint( :,:,k)
341+ vert_below = pint( :,:,k+1 )
325342 end if
326- ddata_dp (:,:,k) = ( dint_above - dint_below ) / ( pint_above - pint_below )
343+ ddata_dvert (:,:,k) = ( data_above - data_below ) / ( vert_above - vert_below )
327344 end do
328345 end subroutine compute_vertical_derivative
329346 !- ------------------------------------------------------------------------------------------------
0 commit comments