FV3 Bundle
pressure_variables_mod.f90
Go to the documentation of this file.
1 ! (C) Copyright 2018 UCAR
2 !
3 ! This software is licensed under the terms of the Apache Licence Version 2.0
4 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5 
6 !> Variable transforms on pressure variables for fv3-jedi
7 !> Daniel Holdaway, NASA/JCSDA
8 
10 
14 
15 implicit none
16 private
17 
21 public delp_to_pe_p_logp
22 public ps_to_delp
23 public ps_to_delp_tl
24 public ps_to_delp_ad
25 
26 contains
27 
28 !----------------------------------------------------------------------------
29 ! Compute all pressures needed as input to fv3 ------------------------------
30 !----------------------------------------------------------------------------
31 
32 subroutine compute_fv3_pressures( is, ie, js, je, isd, ied, jsd, jed, npz, &
33  kappa, ptop, delp, pe, pk, pkz, peln )
34 
35  implicit none
36  integer, intent(in) :: is, ie, js, je, isd, ied, jsd, jed, npz
37  real(kind=kind_real), intent(in) :: kappa, ptop
38  real(kind=kind_real), intent(in) :: delp(isd:ied, jsd:jed, npz)
39  real(kind=kind_real), intent(out) :: pe(is-1:ie+1, npz+1, js-1:je+1)
40  real(kind=kind_real), intent(out) :: pk(is:ie, js:je, npz+1)
41  real(kind=kind_real), intent(out) :: peln(is:ie, npz+1, js:je)
42  real(kind=kind_real), intent(out) :: pkz(is:ie, js:je, npz)
43  integer :: i, j, k
44 
45  pe(:, :, :) = 0.0
46  pe(:, 1, :) = ptop
47  do k=2,npz+1
48  do j=js,je
49  do i=is,ie
50  pe(i, k, j) = pe(i, k-1, j) + delp(i, j, k-1)
51  end do
52  end do
53  end do
54 
55  do k=1,npz+1
56  do j=js,je
57  do i=is,ie
58  peln(i, k, j) = log(pe(i, k, j))
59  end do
60  end do
61  end do
62 
63  do k=1,npz+1
64  do j=js,je
65  do i=is,ie
66  pk(i, j, k) = exp(kappa*peln(i, k, j))
67  end do
68  end do
69  end do
70 
71  do k=1,npz
72  do j=js,je
73  do i=is,ie
74  pkz(i, j, k) = (pk(i, j, k+1)-pk(i, j, k))/(kappa*(peln(i, k+1, j)-peln(i, k, j)))
75  end do
76  end do
77  end do
78 
79 end subroutine compute_fv3_pressures
80 
81 subroutine compute_fv3_pressures_tlm( is, ie, js, je, isd, ied, jsd, jed, npz, &
82  kappa, ptop, delp, delp_tl, &
83  pe, pe_tl, pk, pk_tl, pkz, pkz_tl, peln, peln_tl )
84 
85  implicit none
86  integer, intent(in) :: is, ie, js, je, isd, ied, jsd, jed, npz
87  real(kind=kind_real), intent(in) :: kappa, ptop
88  real(kind=kind_real), intent(in) :: delp(isd:ied, jsd:jed, npz)
89  real(kind=kind_real), intent(in) :: delp_tl(isd:ied, jsd:jed, npz)
90  real(kind=kind_real), intent(out) :: pe(is-1:ie+1, npz+1, js-1:je+1)
91  real(kind=kind_real), intent(out) :: pe_tl(is-1:ie+1, npz+1, js-1:je+1)
92  real(kind=kind_real), intent(out) :: pk(is:ie, js:je, npz+1)
93  real(kind=kind_real), intent(out) :: pk_tl(is:ie, js:je, npz+1)
94  real(kind=kind_real), intent(out) :: peln(is:ie, npz+1, js:je)
95  real(kind=kind_real), intent(out) :: peln_tl(is:ie, npz+1, js:je)
96  real(kind=kind_real), intent(out) :: pkz(is:ie, js:je, npz)
97  real(kind=kind_real), intent(out) :: pkz_tl(is:ie, js:je, npz)
98  integer :: i, j, k
99 
100  pe(:, :, :) = 0.0
101  pe(:, 1, :) = ptop
102  pe_tl = 0.0
103  do k=2,npz+1
104  do j=js,je
105  do i=is,ie
106  pe_tl(i, k, j) = pe_tl(i, k-1, j) + delp_tl(i, j, k-1)
107  pe(i, k, j) = pe(i, k-1, j) + delp(i, j, k-1)
108  end do
109  end do
110  end do
111 
112  peln_tl = 0.0
113  do k=1,npz+1
114  do j=js,je
115  do i=is,ie
116  peln_tl(i, k, j) = pe_tl(i, k, j)/pe(i, k, j)
117  peln(i, k, j) = log(pe(i, k, j))
118  end do
119  end do
120  end do
121 
122  pk_tl = 0.0
123  do k=1,npz+1
124  do j=js,je
125  do i=is,ie
126  pk_tl(i, j, k) = kappa*peln_tl(i, k, j)*exp(kappa*peln(i, k, j))
127  pk(i, j, k) = exp(kappa*peln(i, k, j))
128  end do
129  end do
130  end do
131 
132  pkz_tl = 0.0
133  do k=1,npz
134  do j=js,je
135  do i=is,ie
136  pkz_tl(i, j, k) = ((pk_tl(i, j, k+1)-pk_tl(i, j, k))*kappa*(peln(i, k+1, j)-peln(i, k, j)) &
137  -(pk(i, j, k+1)-pk(i, j, k))*kappa*(peln_tl(i, k+1, j)-peln_tl(i, k, j))) &
138  /(kappa*(peln(i, k+1, j)-peln(i, k, j)))**2
139  pkz(i, j, k) = (pk(i, j, k+1)-pk(i, j, k))/(kappa*(peln(i, k+1, j)-peln(i, k, j)))
140  end do
141  end do
142  end do
143 
144 end subroutine compute_fv3_pressures_tlm
145 
146 subroutine compute_fv3_pressures_bwd( is, ie, js, je, isd, ied, jsd, jed, npz, &
147  kappa, ptop, delp, delp_ad, &
148  pe, pe_ad, pk, pk_ad, pkz, pkz_ad, peln, peln_ad)
150  implicit none
151  integer, intent(in) :: is, ie, js, je, isd, ied, jsd, jed, npz
152  real(kind=kind_real), intent(in) :: kappa, ptop
153  real(kind=kind_real), intent(in) :: delp(isd:ied, jsd:jed, npz)
154  real(kind=kind_real), intent(inout) :: delp_ad(isd:ied, jsd:jed, npz)
155  real(kind=kind_real), intent(in) :: pe(is-1:ie+1, npz+1, js-1:je+1)
156  real(kind=kind_real), intent(inout) :: pe_ad(is-1:ie+1, npz+1, js-1:je+1)
157  real(kind=kind_real), intent(in) :: pk(is:ie, js:je, npz+1)
158  real(kind=kind_real), intent(inout) :: pk_ad(is:ie, js:je, npz+1)
159  real(kind=kind_real), intent(in) :: peln(is:ie, npz+1, js:je)
160  real(kind=kind_real), intent(inout) :: peln_ad(is:ie, npz+1, js:je)
161  real(kind=kind_real), intent(in) :: pkz(is:ie, js:je, npz)
162  real(kind=kind_real), intent(inout) :: pkz_ad(is:ie, js:je, npz)
163  integer :: i, j, k
164  real(kind=kind_real) :: temp_tj1, temp_ad1, temp_ad2
165 
166  do k=npz,1,-1
167  do j=je,js,-1
168  do i=ie,is,-1
169  temp_tj1 = kappa*(peln(i, k+1, j)-peln(i, k, j))
170  temp_ad1 = pkz_ad(i, j, k)/temp_tj1
171  temp_ad2 = -((pk(i, j, k+1)-pk(i, j, k))*kappa*temp_ad1/temp_tj1)
172  pk_ad(i, j, k+1) = pk_ad(i, j, k+1) + temp_ad1
173  pk_ad(i, j, k) = pk_ad(i, j, k) - temp_ad1
174  peln_ad(i, k+1, j) = peln_ad(i, k+1, j) + temp_ad2
175  peln_ad(i, k, j) = peln_ad(i, k, j) - temp_ad2
176  pkz_ad(i, j, k) = 0.0
177  end do
178  end do
179  end do
180 
181  do k=npz+1,1,-1
182  do j=je,js,-1
183  do i=ie,is,-1
184  peln_ad(i, k, j) = peln_ad(i, k, j) + exp(kappa*peln(i, k, j))*kappa*pk_ad(i, j, k)
185  pk_ad(i, j, k) = 0.0
186  end do
187  end do
188  end do
189 
190  do k=npz+1,1,-1
191  do j=je,js,-1
192  do i=ie,is,-1
193  pe_ad(i, k, j) = pe_ad(i, k, j) + peln_ad(i, k, j)/pe(i, k, j)
194  peln_ad(i, k, j) = 0.0
195  end do
196  end do
197  end do
198 
199  do k=npz+1,2,-1
200  do j=je,js,-1
201  do i=ie,is,-1
202  pe_ad(i, k-1, j) = pe_ad(i, k-1, j) + pe_ad(i, k, j)
203  delp_ad(i, j, k-1) = delp_ad(i, j, k-1) + pe_ad(i, k, j)
204  pe_ad(i, k, j) = 0.0
205  end do
206  end do
207  end do
208 
209 end subroutine compute_fv3_pressures_bwd
210 
211 !----------------------------------------------------------------------------
212 ! Pressure thickness to pressure (edge), pressure (mid) and log p (mid) -----
213 !----------------------------------------------------------------------------
214 
215 subroutine delp_to_pe_p_logp(geom,delp,pe,p,logp)
217  implicit none
218  type(fv3jedi_geom) , intent(in ) :: geom !Geometry for the model
219  real(kind=kind_real), intent(in ) :: delp(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz) !Pressure thickness
220  real(kind=kind_real), intent(out) :: pe(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz+1) !Pressure edge/interface
221  real(kind=kind_real), intent(out) :: p(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz) !Pressure mid point
222  real(kind=kind_real), optional, intent(out) :: logp(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz) !Log of pressure mid point
223 
224  !Locals
225  integer :: isc,iec,jsc,jec,k
226 
227  isc = geom%isc
228  iec = geom%iec
229  jsc = geom%jsc
230  jec = geom%jec
231 
232  !Pressure at layer edge
233  pe(isc:iec,jsc:jec,1) = geom%ptop
234  do k = 2,geom%npz+1
235  pe(isc:iec,jsc:jec,k) = pe(isc:iec,jsc:jec,k-1) + delp(isc:iec,jsc:jec,k-1)
236  enddo
237 
238  !Midpoint pressure
239  p(isc:iec,jsc:jec,:) = 0.5*(pe(isc:iec,jsc:jec,2:geom%npz+1) + pe(isc:iec,jsc:jec,1:geom%npz))
240 
241  if (present(logp)) then
242  !Log pressure
243  logp(isc:iec,jsc:jec,:) = log(p(isc:iec,jsc:jec,:))
244  endif
245 
246 end subroutine delp_to_pe_p_logp
247 
248 !----------------------------------------------------------------------------
249 
250 subroutine ps_to_delp(geom,ps,delp)
252  implicit none
253  type(fv3jedi_geom) , intent(in ) :: geom !Geometry for the model
254  real(kind=kind_real), intent(in ) :: ps(geom%isc:geom%iec,geom%jsc:geom%jec ) !Surface pressure
255  real(kind=kind_real), intent(inout) :: delp(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz) !Pressure thickness
256 
257  integer :: isc,iec,jsc,jec,i,j,k
258 
259  isc = geom%isc
260  iec = geom%iec
261  jsc = geom%jsc
262  jec = geom%jec
263 
264  do k = 1,geom%npz
265  do j = jsc,jec
266  do i = isc,iec
267  delp(i,j,k) = geom%ak(k+1) + geom%bk(k+1)*ps(i,j) - (geom%ak(k) + geom%bk(k)*ps(i,j))
268  enddo
269  enddo
270  enddo
271 
272 endsubroutine ps_to_delp
273 
274 subroutine ps_to_delp_tl(geom,ps_tl,delp_tl)
276  implicit none
277  type(fv3jedi_geom) , intent(in ) :: geom !Geometry for the model
278  real(kind=kind_real), intent(in ) :: ps_tl(geom%isc:geom%iec,geom%jsc:geom%jec ) !Surface pressure
279  real(kind=kind_real), intent(inout) :: delp_tl(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz) !Pressure thickness
280 
281  integer :: isc,iec,jsc,jec,i,j,k
282 
283  isc = geom%isc
284  iec = geom%iec
285  jsc = geom%jsc
286  jec = geom%jec
287 
288  delp_tl = 0.0_kind_real
289  do k = 1,geom%npz
290  do j = jsc,jec
291  do i = isc,iec
292  delp_tl(i,j,k) = geom%bk(k+1)*ps_tl(i,j) - geom%bk(k)*ps_tl(i,j)
293  enddo
294  enddo
295  enddo
296 
297 endsubroutine ps_to_delp_tl
298 
299 subroutine ps_to_delp_ad(geom,ps_ad,delp_ad)
301  implicit none
302  type(fv3jedi_geom) , intent(in ) :: geom !Geometry for the model
303  real(kind=kind_real), intent(inout) :: ps_ad(geom%isc:geom%iec,geom%jsc:geom%jec ) !Surface pressure
304  real(kind=kind_real), intent(inout) :: delp_ad(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz) !Pressure thickness
305 
306  integer :: isc,iec,jsc,jec,i,j,k
307 
308  isc = geom%isc
309  iec = geom%iec
310  jsc = geom%jsc
311  jec = geom%jec
312 
313  ps_ad = 0.0_kind_real
314 
315  do k = geom%npz,1,-1
316  do j = jec,jsc,-1
317  do i = iec,isc,-1
318  ps_ad(i,j) = ps_ad(i,j) + (geom%bk(k+1) - geom%bk(k))*delp_ad(i,j,k)
319  enddo
320  enddo
321  enddo
322 
323 endsubroutine ps_to_delp_ad
324 
325 end module pressure_vt_mod
326 
327 
real(kind=kind_real), parameter, public kappa
subroutine, public delp_to_pe_p_logp(geom, delp, pe, p, logp)
subroutine, public ps_to_delp(geom, ps, delp)
subroutine, public compute_fv3_pressures(is, ie, js, je, isd, ied, jsd, jed, npz, kappa, ptop, delp, pe, pk, pkz, peln)
Fortran derived type to hold geometry data for the FV3JEDI model.
subroutine, public compute_fv3_pressures_bwd(is, ie, js, je, isd, ied, jsd, jed, npz, kappa, ptop, delp, delp_ad, pe, pe_ad, pk, pk_ad, pkz, pkz_ad, peln, peln_ad)
subroutine, public ps_to_delp_tl(geom, ps_tl, delp_tl)
subroutine, public ps_to_delp_ad(geom, ps_ad, delp_ad)
Fortran module handling geometry for the FV3 model.
Variable transforms on pressure variables for fv3-jedi Daniel Holdaway, NASA/JCSDA.
integer, parameter, public kind_real
subroutine, public compute_fv3_pressures_tlm(is, ie, js, je, isd, ied, jsd, jed, npz, kappa, ptop, delp, delp_tl, pe, pe_tl, pk, pk_tl, pkz, pkz_tl, peln, peln_tl)