FV3 Bundle
nh_utils_tlm.F90
Go to the documentation of this file.
1 !***********************************************************************
2 !* GNU General Public License *
3 !* This file is a part of fvGFS. *
4 !* *
5 !* fvGFS is free software; you can redistribute it and/or modify it *
6 !* and are expected to follow the terms of the GNU General Public *
7 !* License as published by the Free Software Foundation; either *
8 !* version 2 of the License, or (at your option) any later version. *
9 !* *
10 !* fvGFS is distributed in the hope that it will be useful, but *
11 !* WITHOUT ANY WARRANTY; without even the implied warranty of *
12 !* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
13 !* General Public License for more details. *
14 !* *
15 !* For the full text of the GNU General Public License, *
16 !* write to: Free Software Foundation, Inc., *
17 !* 675 Mass Ave, Cambridge, MA 02139, USA. *
18 !* or see: http://www.gnu.org/licenses/gpl.html *
19 !***********************************************************************
21 ! Developer: S.-J. Lin, NOAA/GFDL
22 ! To do list:
23 ! include moisture effect in pt
24 !------------------------------
25  use constants_mod, only: rdgas, cp_air, grav
26  use tp_core_tlm_mod, only: fv_tp_2d
27  use tp_core_tlm_mod, only: fv_tp_2d_tlm
31 
32  implicit none
33  private
34 
37  public sim3p0_solver, rim_2d
38  public riem_solver_c
42  public riem_solver_c_tlm
43 
44  real, parameter:: dz_min = 2.
45  real, parameter:: r3 = 1./3.
46 
47 CONTAINS
48 ! Differentiation of update_dz_c in forward (tangent) mode:
49 ! variations of useful results: ws gz
50 ! with respect to varying inputs: ws gz ut vt
51  SUBROUTINE update_dz_c_tlm(is, ie, js, je, km, ng, dt, dp0, zs, area, &
52 & ut, ut_tl, vt, vt_tl, gz, gz_tl, ws, ws_tl, npx, npy, sw_corner, &
53 & se_corner, ne_corner, nw_corner, bd, grid_type)
54  IMPLICIT NONE
55 ! !INPUT PARAMETERS:
56  TYPE(fv_grid_bounds_type), INTENT(IN) :: bd
57  INTEGER, INTENT(IN) :: is, ie, js, je, ng, km, npx, npy, grid_type
58  LOGICAL, INTENT(IN) :: sw_corner, se_corner, ne_corner, nw_corner
59  REAL, INTENT(IN) :: dt
60  REAL, INTENT(IN) :: dp0(km)
61  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: ut, vt
62  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: ut_tl, &
63 & vt_tl
64  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng), INTENT(IN) :: area
65  REAL, INTENT(INOUT) :: gz(is-ng:ie+ng, js-ng:je+ng, km+1)
66  REAL, INTENT(INOUT) :: gz_tl(is-ng:ie+ng, js-ng:je+ng, km+1)
67  REAL, INTENT(IN) :: zs(is-ng:ie+ng, js-ng:je+ng)
68  REAL, INTENT(OUT) :: ws(is-ng:ie+ng, js-ng:je+ng)
69  REAL, INTENT(OUT) :: ws_tl(is-ng:ie+ng, js-ng:je+ng)
70 ! Local Work array:
71  REAL :: gz2(is-ng:ie+ng, js-ng:je+ng)
72  REAL :: gz2_tl(is-ng:ie+ng, js-ng:je+ng)
73  REAL, DIMENSION(is-1:ie+2, js-1:je+1) :: xfx, fx
74  REAL, DIMENSION(is-1:ie+2, js-1:je+1) :: xfx_tl, fx_tl
75  REAL, DIMENSION(is-1:ie+1, js-1:je+2) :: yfx, fy
76  REAL, DIMENSION(is-1:ie+1, js-1:je+2) :: yfx_tl, fy_tl
77  REAL, PARAMETER :: r14=1./14.
78  INTEGER :: i, j, k
79  INTEGER :: is1, ie1, js1, je1
80  INTEGER :: ie2, je2
81  REAL :: rdt, top_ratio, bot_ratio, int_ratio
82  INTRINSIC max
83 !--------------------------------------------------------------------
84  rdt = 1./dt
85  top_ratio = dp0(1)/(dp0(1)+dp0(2))
86  bot_ratio = dp0(km)/(dp0(km-1)+dp0(km))
87  is1 = is - 1
88  js1 = js - 1
89  ie1 = ie + 1
90  je1 = je + 1
91  ie2 = ie + 2
92  je2 = je + 2
93  xfx_tl = 0.0
94  gz2_tl = 0.0
95  yfx_tl = 0.0
96  fx_tl = 0.0
97  fy_tl = 0.0
98 !$OMP parallel do default(none) shared(js1,je1,is1,ie2,km,je2,ie1,ut,top_ratio,vt, &
99 !$OMP bot_ratio,dp0,js,je,ng,is,ie,gz,grid_type, &
100 !$OMP bd,npx,npy,sw_corner,se_corner,ne_corner, &
101 !$OMP nw_corner,area) &
102 !$OMP private(gz2, xfx, yfx, fx, fy, int_ratio)
103  DO k=1,km+1
104  IF (k .EQ. 1) THEN
105  DO j=js1,je1
106  DO i=is1,ie2
107  xfx_tl(i, j) = ut_tl(i, j, 1) + top_ratio*(ut_tl(i, j, 1)-&
108 & ut_tl(i, j, 2))
109  xfx(i, j) = ut(i, j, 1) + (ut(i, j, 1)-ut(i, j, 2))*&
110 & top_ratio
111  END DO
112  END DO
113  DO j=js1,je2
114  DO i=is1,ie1
115  yfx_tl(i, j) = vt_tl(i, j, 1) + top_ratio*(vt_tl(i, j, 1)-&
116 & vt_tl(i, j, 2))
117  yfx(i, j) = vt(i, j, 1) + (vt(i, j, 1)-vt(i, j, 2))*&
118 & top_ratio
119  END DO
120  END DO
121  ELSE IF (k .EQ. km + 1) THEN
122 ! Bottom extrapolation
123  DO j=js1,je1
124  DO i=is1,ie2
125  xfx_tl(i, j) = ut_tl(i, j, km) + bot_ratio*(ut_tl(i, j, km)-&
126 & ut_tl(i, j, km-1))
127  xfx(i, j) = ut(i, j, km) + (ut(i, j, km)-ut(i, j, km-1))*&
128 & bot_ratio
129  END DO
130  END DO
131 ! xfx(i,j) = r14*(3.*ut(i,j,km-2)-13.*ut(i,j,km-1)+24.*ut(i,j,km))
132 ! if ( xfx(i,j)*ut(i,j,km)<0. ) xfx(i,j) = 0.
133  DO j=js1,je2
134  DO i=is1,ie1
135  yfx_tl(i, j) = vt_tl(i, j, km) + bot_ratio*(vt_tl(i, j, km)-&
136 & vt_tl(i, j, km-1))
137  yfx(i, j) = vt(i, j, km) + (vt(i, j, km)-vt(i, j, km-1))*&
138 & bot_ratio
139  END DO
140  END DO
141  ELSE
142 ! yfx(i,j) = r14*(3.*vt(i,j,km-2)-13.*vt(i,j,km-1)+24.*vt(i,j,km))
143 ! if ( yfx(i,j)*vt(i,j,km)<0. ) yfx(i,j) = 0.
144  int_ratio = 1./(dp0(k-1)+dp0(k))
145  DO j=js1,je1
146  DO i=is1,ie2
147  xfx_tl(i, j) = int_ratio*(dp0(k)*ut_tl(i, j, k-1)+dp0(k-1)*&
148 & ut_tl(i, j, k))
149  xfx(i, j) = (dp0(k)*ut(i, j, k-1)+dp0(k-1)*ut(i, j, k))*&
150 & int_ratio
151  END DO
152  END DO
153  DO j=js1,je2
154  DO i=is1,ie1
155  yfx_tl(i, j) = int_ratio*(dp0(k)*vt_tl(i, j, k-1)+dp0(k-1)*&
156 & vt_tl(i, j, k))
157  yfx(i, j) = (dp0(k)*vt(i, j, k-1)+dp0(k-1)*vt(i, j, k))*&
158 & int_ratio
159  END DO
160  END DO
161  END IF
162  DO j=js-ng,je+ng
163  DO i=is-ng,ie+ng
164  gz2_tl(i, j) = gz_tl(i, j, k)
165  gz2(i, j) = gz(i, j, k)
166  END DO
167  END DO
168  IF (grid_type .LT. 3) CALL fill_4corners_tlm(gz2, gz2_tl, 1, bd, &
169 & npx, npy, sw_corner, &
170 & se_corner, ne_corner, &
171 & nw_corner)
172  DO j=js1,je1
173  DO i=is1,ie2
174  IF (xfx(i, j) .GT. 0.) THEN
175  fx_tl(i, j) = gz2_tl(i-1, j)
176  fx(i, j) = gz2(i-1, j)
177  ELSE
178  fx_tl(i, j) = gz2_tl(i, j)
179  fx(i, j) = gz2(i, j)
180  END IF
181  fx_tl(i, j) = xfx_tl(i, j)*fx(i, j) + xfx(i, j)*fx_tl(i, j)
182  fx(i, j) = xfx(i, j)*fx(i, j)
183  END DO
184  END DO
185  IF (grid_type .LT. 3) CALL fill_4corners_tlm(gz2, gz2_tl, 2, bd, &
186 & npx, npy, sw_corner, &
187 & se_corner, ne_corner, &
188 & nw_corner)
189  DO j=js1,je2
190  DO i=is1,ie1
191  IF (yfx(i, j) .GT. 0.) THEN
192  fy_tl(i, j) = gz2_tl(i, j-1)
193  fy(i, j) = gz2(i, j-1)
194  ELSE
195  fy_tl(i, j) = gz2_tl(i, j)
196  fy(i, j) = gz2(i, j)
197  END IF
198  fy_tl(i, j) = yfx_tl(i, j)*fy(i, j) + yfx(i, j)*fy_tl(i, j)
199  fy(i, j) = yfx(i, j)*fy(i, j)
200  END DO
201  END DO
202  DO j=js1,je1
203  DO i=is1,ie1
204  gz_tl(i, j, k) = ((area(i, j)*gz2_tl(i, j)+fx_tl(i, j)-fx_tl(i&
205 & +1, j)+fy_tl(i, j)-fy_tl(i, j+1))*(area(i, j)+(xfx(i, j)-xfx&
206 & (i+1, j))+(yfx(i, j)-yfx(i, j+1)))-(gz2(i, j)*area(i, j)+(fx&
207 & (i, j)-fx(i+1, j))+(fy(i, j)-fy(i, j+1)))*(xfx_tl(i, j)-&
208 & xfx_tl(i+1, j)+yfx_tl(i, j)-yfx_tl(i, j+1)))/(area(i, j)+(&
209 & xfx(i, j)-xfx(i+1, j))+(yfx(i, j)-yfx(i, j+1)))**2
210  gz(i, j, k) = (gz2(i, j)*area(i, j)+(fx(i, j)-fx(i+1, j))+(fy(&
211 & i, j)-fy(i, j+1)))/(area(i, j)+(xfx(i, j)-xfx(i+1, j))+(yfx(&
212 & i, j)-yfx(i, j+1)))
213  END DO
214  END DO
215  END DO
216 ! Enforce monotonicity of height to prevent blowup
217 !$OMP parallel do default(none) shared(is1,ie1,js1,je1,ws,zs,gz,rdt,km)
218  DO j=js1,je1
219  DO i=is1,ie1
220  ws_tl(i, j) = -(rdt*gz_tl(i, j, km+1))
221  ws(i, j) = (zs(i, j)-gz(i, j, km+1))*rdt
222  END DO
223  DO k=km,1,-1
224  DO i=is1,ie1
225  IF (gz(i, j, k) .LT. gz(i, j, k+1) + dz_min) THEN
226  gz_tl(i, j, k) = gz_tl(i, j, k+1)
227  gz(i, j, k) = gz(i, j, k+1) + dz_min
228  ELSE
229  gz(i, j, k) = gz(i, j, k)
230  END IF
231  END DO
232  END DO
233  END DO
234  END SUBROUTINE update_dz_c_tlm
235  SUBROUTINE update_dz_c(is, ie, js, je, km, ng, dt, dp0, zs, area, ut, &
236 & vt, gz, ws, npx, npy, sw_corner, se_corner, ne_corner, nw_corner, bd&
237 & , grid_type)
238  IMPLICIT NONE
239 ! !INPUT PARAMETERS:
240  TYPE(fv_grid_bounds_type), INTENT(IN) :: bd
241  INTEGER, INTENT(IN) :: is, ie, js, je, ng, km, npx, npy, grid_type
242  LOGICAL, INTENT(IN) :: sw_corner, se_corner, ne_corner, nw_corner
243  REAL, INTENT(IN) :: dt
244  REAL, INTENT(IN) :: dp0(km)
245  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: ut, vt
246  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng), INTENT(IN) :: area
247  REAL, INTENT(INOUT) :: gz(is-ng:ie+ng, js-ng:je+ng, km+1)
248  REAL, INTENT(IN) :: zs(is-ng:ie+ng, js-ng:je+ng)
249  REAL, INTENT(OUT) :: ws(is-ng:ie+ng, js-ng:je+ng)
250 ! Local Work array:
251  REAL :: gz2(is-ng:ie+ng, js-ng:je+ng)
252  REAL, DIMENSION(is-1:ie+2, js-1:je+1) :: xfx, fx
253  REAL, DIMENSION(is-1:ie+1, js-1:je+2) :: yfx, fy
254  REAL, PARAMETER :: r14=1./14.
255  INTEGER :: i, j, k
256  INTEGER :: is1, ie1, js1, je1
257  INTEGER :: ie2, je2
258  REAL :: rdt, top_ratio, bot_ratio, int_ratio
259  INTRINSIC max
260 !--------------------------------------------------------------------
261  rdt = 1./dt
262  top_ratio = dp0(1)/(dp0(1)+dp0(2))
263  bot_ratio = dp0(km)/(dp0(km-1)+dp0(km))
264  is1 = is - 1
265  js1 = js - 1
266  ie1 = ie + 1
267  je1 = je + 1
268  ie2 = ie + 2
269  je2 = je + 2
270 !$OMP parallel do default(none) shared(js1,je1,is1,ie2,km,je2,ie1,ut,top_ratio,vt, &
271 !$OMP bot_ratio,dp0,js,je,ng,is,ie,gz,grid_type, &
272 !$OMP bd,npx,npy,sw_corner,se_corner,ne_corner, &
273 !$OMP nw_corner,area) &
274 !$OMP private(gz2, xfx, yfx, fx, fy, int_ratio)
275  DO k=1,km+1
276  IF (k .EQ. 1) THEN
277  DO j=js1,je1
278  DO i=is1,ie2
279  xfx(i, j) = ut(i, j, 1) + (ut(i, j, 1)-ut(i, j, 2))*&
280 & top_ratio
281  END DO
282  END DO
283  DO j=js1,je2
284  DO i=is1,ie1
285  yfx(i, j) = vt(i, j, 1) + (vt(i, j, 1)-vt(i, j, 2))*&
286 & top_ratio
287  END DO
288  END DO
289  ELSE IF (k .EQ. km + 1) THEN
290 ! Bottom extrapolation
291  DO j=js1,je1
292  DO i=is1,ie2
293  xfx(i, j) = ut(i, j, km) + (ut(i, j, km)-ut(i, j, km-1))*&
294 & bot_ratio
295  END DO
296  END DO
297 ! xfx(i,j) = r14*(3.*ut(i,j,km-2)-13.*ut(i,j,km-1)+24.*ut(i,j,km))
298 ! if ( xfx(i,j)*ut(i,j,km)<0. ) xfx(i,j) = 0.
299  DO j=js1,je2
300  DO i=is1,ie1
301  yfx(i, j) = vt(i, j, km) + (vt(i, j, km)-vt(i, j, km-1))*&
302 & bot_ratio
303  END DO
304  END DO
305  ELSE
306 ! yfx(i,j) = r14*(3.*vt(i,j,km-2)-13.*vt(i,j,km-1)+24.*vt(i,j,km))
307 ! if ( yfx(i,j)*vt(i,j,km)<0. ) yfx(i,j) = 0.
308  int_ratio = 1./(dp0(k-1)+dp0(k))
309  DO j=js1,je1
310  DO i=is1,ie2
311  xfx(i, j) = (dp0(k)*ut(i, j, k-1)+dp0(k-1)*ut(i, j, k))*&
312 & int_ratio
313  END DO
314  END DO
315  DO j=js1,je2
316  DO i=is1,ie1
317  yfx(i, j) = (dp0(k)*vt(i, j, k-1)+dp0(k-1)*vt(i, j, k))*&
318 & int_ratio
319  END DO
320  END DO
321  END IF
322  DO j=js-ng,je+ng
323  DO i=is-ng,ie+ng
324  gz2(i, j) = gz(i, j, k)
325  END DO
326  END DO
327  IF (grid_type .LT. 3) CALL fill_4corners(gz2, 1, bd, npx, npy, &
328 & sw_corner, se_corner, ne_corner&
329 & , nw_corner)
330  DO j=js1,je1
331  DO i=is1,ie2
332  IF (xfx(i, j) .GT. 0.) THEN
333  fx(i, j) = gz2(i-1, j)
334  ELSE
335  fx(i, j) = gz2(i, j)
336  END IF
337  fx(i, j) = xfx(i, j)*fx(i, j)
338  END DO
339  END DO
340  IF (grid_type .LT. 3) CALL fill_4corners(gz2, 2, bd, npx, npy, &
341 & sw_corner, se_corner, ne_corner&
342 & , nw_corner)
343  DO j=js1,je2
344  DO i=is1,ie1
345  IF (yfx(i, j) .GT. 0.) THEN
346  fy(i, j) = gz2(i, j-1)
347  ELSE
348  fy(i, j) = gz2(i, j)
349  END IF
350  fy(i, j) = yfx(i, j)*fy(i, j)
351  END DO
352  END DO
353  DO j=js1,je1
354  DO i=is1,ie1
355  gz(i, j, k) = (gz2(i, j)*area(i, j)+(fx(i, j)-fx(i+1, j))+(fy(&
356 & i, j)-fy(i, j+1)))/(area(i, j)+(xfx(i, j)-xfx(i+1, j))+(yfx(&
357 & i, j)-yfx(i, j+1)))
358  END DO
359  END DO
360  END DO
361 ! Enforce monotonicity of height to prevent blowup
362 !$OMP parallel do default(none) shared(is1,ie1,js1,je1,ws,zs,gz,rdt,km)
363  DO j=js1,je1
364  DO i=is1,ie1
365  ws(i, j) = (zs(i, j)-gz(i, j, km+1))*rdt
366  END DO
367  DO k=km,1,-1
368  DO i=is1,ie1
369  IF (gz(i, j, k) .LT. gz(i, j, k+1) + dz_min) THEN
370  gz(i, j, k) = gz(i, j, k+1) + dz_min
371  ELSE
372  gz(i, j, k) = gz(i, j, k)
373  END IF
374  END DO
375  END DO
376  END DO
377  END SUBROUTINE update_dz_c
378 ! Differentiation of update_dz_d in forward (tangent) mode:
379 ! variations of useful results: ws zh
380 ! with respect to varying inputs: xfx ws yfx zh crx cry
381  SUBROUTINE update_dz_d_tlm(ndif, damp, hord, is, ie, js, je, km, ng, &
382 & npx, npy, area, rarea, dp0, zs, zh, zh_tl, crx, crx_tl, cry, cry_tl&
383 & , xfx, xfx_tl, yfx, yfx_tl, delz, ws, ws_tl, rdt, gridstruct, bd, &
384 & hord_pert)
385  IMPLICIT NONE
386  TYPE(fv_grid_bounds_type), INTENT(IN) :: bd
387  INTEGER, INTENT(IN) :: is, ie, js, je, ng, km, npx, npy
388  INTEGER, INTENT(IN) :: hord, hord_pert
389  REAL, INTENT(IN) :: rdt
390  REAL, INTENT(IN) :: dp0(km)
391  REAL, INTENT(IN) :: area(is-ng:ie+ng, js-ng:je+ng)
392  REAL, INTENT(IN) :: rarea(is-ng:ie+ng, js-ng:je+ng)
393  REAL, INTENT(INOUT) :: damp(km+1)
394  INTEGER, INTENT(INOUT) :: ndif(km+1)
395  REAL, INTENT(IN) :: zs(is-ng:ie+ng, js-ng:je+ng)
396  REAL, INTENT(INOUT) :: zh(is-ng:ie+ng, js-ng:je+ng, km+1)
397  REAL, INTENT(INOUT) :: zh_tl(is-ng:ie+ng, js-ng:je+ng, km+1)
398  REAL, INTENT(OUT) :: delz(is-ng:ie+ng, js-ng:je+ng, km)
399  REAL, DIMENSION(is:ie+1, js-ng:je+ng, km), INTENT(INOUT) :: crx, xfx
400  REAL, DIMENSION(is:ie+1, js-ng:je+ng, km), INTENT(INOUT) :: crx_tl, &
401 & xfx_tl
402  REAL, DIMENSION(is-ng:ie+ng, js:je+1, km), INTENT(INOUT) :: cry, yfx
403  REAL, DIMENSION(is-ng:ie+ng, js:je+1, km), INTENT(INOUT) :: cry_tl, &
404 & yfx_tl
405  REAL, INTENT(OUT) :: ws(is:ie, js:je)
406  REAL, INTENT(OUT) :: ws_tl(is:ie, js:je)
407  TYPE(fv_grid_type), INTENT(IN), TARGET :: gridstruct
408 !-----------------------------------------------------
409 ! Local array:
410  REAL, DIMENSION(is:ie+1, js-ng:je+ng, km+1) :: crx_adv, xfx_adv
411  REAL, DIMENSION(is:ie+1, js-ng:je+ng, km+1) :: crx_adv_tl, &
412 & xfx_adv_tl
413  REAL, DIMENSION(is-ng:ie+ng, js:je+1, km+1) :: cry_adv, yfx_adv
414  REAL, DIMENSION(is-ng:ie+ng, js:je+1, km+1) :: cry_adv_tl, &
415 & yfx_adv_tl
416  REAL, DIMENSION(is:ie+1, js:je) :: fx
417  REAL, DIMENSION(is:ie+1, js:je) :: fx_tl
418  REAL, DIMENSION(is:ie, js:je+1) :: fy
419  REAL, DIMENSION(is:ie, js:je+1) :: fy_tl
420  REAL, DIMENSION(is-ng:ie+ng+1, js-ng:je+ng) :: fx2
421  REAL, DIMENSION(is-ng:ie+ng+1, js-ng:je+ng) :: fx2_tl
422  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng+1) :: fy2
423  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng+1) :: fy2_tl
424  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng) :: wk2, z2
425  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng) :: wk2_tl, z2_tl
426  REAL :: ra_x(is:ie, js-ng:je+ng)
427  REAL :: ra_x_tl(is:ie, js-ng:je+ng)
428  REAL :: ra_y(is-ng:ie+ng, js:je)
429  REAL :: ra_y_tl(is-ng:ie+ng, js:je)
430 !--------------------------------------------------------------------
431  INTEGER :: i, j, k, isd, ied, jsd, jed
432  LOGICAL :: uniform_grid
433  INTRINSIC max
434  uniform_grid = .false.
435  damp(km+1) = damp(km)
436  ndif(km+1) = ndif(km)
437  isd = is - ng
438  ied = ie + ng
439  jsd = js - ng
440  jed = je + ng
441  yfx_adv_tl = 0.0
442  crx_adv_tl = 0.0
443  xfx_adv_tl = 0.0
444  cry_adv_tl = 0.0
445 !$OMP parallel do default(none) shared(jsd,jed,crx,xfx,crx_adv,xfx_adv,is,ie,isd,ied, &
446 !$OMP km,dp0,uniform_grid,js,je,cry,yfx,cry_adv,yfx_adv)
447  DO j=jsd,jed
448  CALL edge_profile_tlm(crx, crx_tl, xfx, xfx_tl, crx_adv, &
449 & crx_adv_tl, xfx_adv, xfx_adv_tl, is, ie + 1, jsd, &
450 & jed, j, km, dp0, uniform_grid, 0)
451  IF (j .LE. je + 1 .AND. j .GE. js) CALL edge_profile_tlm(cry, &
452 & cry_tl, yfx, &
453 & yfx_tl, cry_adv&
454 & , cry_adv_tl, &
455 & yfx_adv, &
456 & yfx_adv_tl, isd&
457 & , ied, js, je +&
458 & 1, j, km, dp0, &
459 & uniform_grid, 0&
460 & )
461  END DO
462  fy2_tl = 0.0
463  wk2_tl = 0.0
464  z2_tl = 0.0
465  ra_x_tl = 0.0
466  ra_y_tl = 0.0
467  fx_tl = 0.0
468  fy_tl = 0.0
469  fx2_tl = 0.0
470 !$OMP parallel do default(none) shared(is,ie,js,je,isd,ied,jsd,jed,km,area,xfx_adv,yfx_adv, &
471 !$OMP damp,zh,crx_adv,cry_adv,npx,npy,hord,gridstruct,bd, &
472 !$OMP ndif,rarea) &
473 !$OMP private(z2, fx2, fy2, ra_x, ra_y, fx, fy,wk2)
474  DO k=1,km+1
475  DO j=jsd,jed
476  DO i=is,ie
477  ra_x_tl(i, j) = xfx_adv_tl(i, j, k) - xfx_adv_tl(i+1, j, k)
478  ra_x(i, j) = area(i, j) + (xfx_adv(i, j, k)-xfx_adv(i+1, j, k)&
479 & )
480  END DO
481  END DO
482  DO j=js,je
483  DO i=isd,ied
484  ra_y_tl(i, j) = yfx_adv_tl(i, j, k) - yfx_adv_tl(i, j+1, k)
485  ra_y(i, j) = area(i, j) + (yfx_adv(i, j, k)-yfx_adv(i, j+1, k)&
486 & )
487  END DO
488  END DO
489  IF (damp(k) .GT. 1.e-5) THEN
490  DO j=jsd,jed
491  DO i=isd,ied
492  z2_tl(i, j) = zh_tl(i, j, k)
493  z2(i, j) = zh(i, j, k)
494  END DO
495  END DO
496  IF (hord .EQ. hord_pert) THEN
497  CALL fv_tp_2d_tlm(z2, z2_tl, crx_adv(is:ie+1, jsd:jed, k), &
498 & crx_adv_tl(is:ie+1, jsd:jed, k), cry_adv(isd:&
499 & ied, js:je+1, k), cry_adv_tl(isd:ied, js:je+1, &
500 & k), npx, npy, hord, fx, fx_tl, fy, fy_tl, &
501 & xfx_adv(is:ie+1, jsd:jed, k), xfx_adv_tl(is:ie+&
502 & 1, jsd:jed, k), yfx_adv(isd:ied, js:je+1, k), &
503 & yfx_adv_tl(isd:ied, js:je+1, k), gridstruct, bd&
504 & , ra_x, ra_x_tl, ra_y, ra_y_tl)
505  ELSE
506  CALL fv_tp_2d_tlm(z2, z2_tl, crx_adv(is:ie+1, jsd:jed, k), &
507 & crx_adv_tl(is:ie+1, jsd:jed, k), cry_adv(isd:ied, &
508 & js:je+1, k), cry_adv_tl(isd:ied, js:je+1, k), npx&
509 & , npy, hord_pert, fx, fx_tl, fy, fy_tl, xfx_adv(is&
510 & :ie+1, jsd:jed, k), xfx_adv_tl(is:ie+1, jsd:jed, k&
511 & ), yfx_adv(isd:ied, js:je+1, k), yfx_adv_tl(isd:&
512 & ied, js:je+1, k), gridstruct, bd, ra_x, ra_x_tl, &
513 & ra_y, ra_y_tl)
514  call fv_tp_2d(z2, crx_adv(is:ie+1,jsd:jed,k), cry_adv(isd:ied,js:je+1,k), npx, npy, hord, &
515  fx, fy, xfx_adv(is:ie+1,jsd:jed,k), yfx_adv(isd:ied,js:je+1,k), gridstruct, bd, ra_x, ra_y)
516  END IF
517  CALL del6_vt_flux_tlm(ndif(k), npx, npy, damp(k), z2, z2_tl, wk2&
518 & , wk2_tl, fx2, fx2_tl, fy2, fy2_tl, gridstruct, &
519 & bd)
520  DO j=js,je
521  DO i=is,ie
522  zh_tl(i, j, k) = ((area(i, j)*z2_tl(i, j)+fx_tl(i, j)-fx_tl(&
523 & i+1, j)+fy_tl(i, j)-fy_tl(i, j+1))*(ra_x(i, j)+ra_y(i, j)-&
524 & area(i, j))-(z2(i, j)*area(i, j)+(fx(i, j)-fx(i+1, j))+(fy&
525 & (i, j)-fy(i, j+1)))*(ra_x_tl(i, j)+ra_y_tl(i, j)))/(ra_x(i&
526 & , j)+ra_y(i, j)-area(i, j))**2 + rarea(i, j)*(fx2_tl(i, j)&
527 & -fx2_tl(i+1, j)+fy2_tl(i, j)-fy2_tl(i, j+1))
528  zh(i, j, k) = (z2(i, j)*area(i, j)+(fx(i, j)-fx(i+1, j))+(fy&
529 & (i, j)-fy(i, j+1)))/(ra_x(i, j)+ra_y(i, j)-area(i, j)) + (&
530 & fx2(i, j)-fx2(i+1, j)+(fy2(i, j)-fy2(i, j+1)))*rarea(i, j)
531  END DO
532  END DO
533  ELSE
534  IF (hord .EQ. hord_pert) THEN
535  CALL fv_tp_2d_tlm(zh(isd:ied, jsd:jed, k), zh_tl(isd:ied, &
536 & jsd:jed, k), crx_adv(is:ie+1, jsd:jed, k), &
537 & crx_adv_tl(is:ie+1, jsd:jed, k), cry_adv(isd:&
538 & ied, js:je+1, k), cry_adv_tl(isd:ied, js:je+1, &
539 & k), npx, npy, hord, fx, fx_tl, fy, fy_tl, &
540 & xfx_adv(is:ie+1, jsd:jed, k), xfx_adv_tl(is:ie+&
541 & 1, jsd:jed, k), yfx_adv(isd:ied, js:je+1, k), &
542 & yfx_adv_tl(isd:ied, js:je+1, k), gridstruct, bd&
543 & , ra_x, ra_x_tl, ra_y, ra_y_tl)
544  ELSE
545  CALL fv_tp_2d_tlm(zh(isd:ied, jsd:jed, k), zh_tl(isd:ied, jsd:&
546 & jed, k), crx_adv(is:ie+1, jsd:jed, k), crx_adv_tl(&
547 & is:ie+1, jsd:jed, k), cry_adv(isd:ied, js:je+1, k)&
548 & , cry_adv_tl(isd:ied, js:je+1, k), npx, npy, &
549 & hord_pert, fx, fx_tl, fy, fy_tl, xfx_adv(is:ie+1, &
550 & jsd:jed, k), xfx_adv_tl(is:ie+1, jsd:jed, k), &
551 & yfx_adv(isd:ied, js:je+1, k), yfx_adv_tl(isd:ied, &
552 & js:je+1, k), gridstruct, bd, ra_x, ra_x_tl, ra_y, &
553 & ra_y_tl)
554  call fv_tp_2d(zh(isd:ied,jsd:jed,k), crx_adv(is:ie+1,jsd:jed,k), cry_adv(isd:ied,js:je+1,k), npx, npy, hord, &
555  fx, fy, xfx_adv(is:ie+1,jsd:jed,k), yfx_adv(isd:ied,js:je+1,k), gridstruct, bd, ra_x, ra_y)
556  END IF
557  DO j=js,je
558  DO i=is,ie
559  zh_tl(i, j, k) = ((area(i, j)*zh_tl(i, j, k)+fx_tl(i, j)-&
560 & fx_tl(i+1, j)+fy_tl(i, j)-fy_tl(i, j+1))*(ra_x(i, j)+ra_y(&
561 & i, j)-area(i, j))-(zh(i, j, k)*area(i, j)+(fx(i, j)-fx(i+1&
562 & , j))+(fy(i, j)-fy(i, j+1)))*(ra_x_tl(i, j)+ra_y_tl(i, j))&
563 & )/(ra_x(i, j)+ra_y(i, j)-area(i, j))**2
564  zh(i, j, k) = (zh(i, j, k)*area(i, j)+(fx(i, j)-fx(i+1, j))+&
565 & (fy(i, j)-fy(i, j+1)))/(ra_x(i, j)+ra_y(i, j)-area(i, j))
566  END DO
567  END DO
568  END IF
569  END DO
570 ! zh(i,j,k) = rarea(i,j)*(fx(i,j)-fx(i+1,j)+fy(i,j)-fy(i,j+1)) &
571 ! + zh(i,j,k)*(3.-rarea(i,j)*(ra_x(i,j) + ra_y(i,j)))
572 !$OMP parallel do default(none) shared(is,ie,js,je,km,ws,zs,zh,rdt)
573  DO j=js,je
574  DO i=is,ie
575  ws_tl(i, j) = -(rdt*zh_tl(i, j, km+1))
576  ws(i, j) = (zs(i, j)-zh(i, j, km+1))*rdt
577  END DO
578  DO k=km,1,-1
579  DO i=is,ie
580  IF (zh(i, j, k) .LT. zh(i, j, k+1) + dz_min) THEN
581  zh_tl(i, j, k) = zh_tl(i, j, k+1)
582  zh(i, j, k) = zh(i, j, k+1) + dz_min
583  ELSE
584  zh(i, j, k) = zh(i, j, k)
585  END IF
586  END DO
587  END DO
588  END DO
589  END SUBROUTINE update_dz_d_tlm
590  SUBROUTINE update_dz_d(ndif, damp, hord, is, ie, js, je, km, ng, npx, &
591 & npy, area, rarea, dp0, zs, zh, crx, cry, xfx, yfx, delz, ws, rdt, &
592 & gridstruct, bd, hord_pert)
593  IMPLICIT NONE
594  TYPE(fv_grid_bounds_type), INTENT(IN) :: bd
595  INTEGER, INTENT(IN) :: is, ie, js, je, ng, km, npx, npy
596  INTEGER, INTENT(IN) :: hord, hord_pert
597  REAL, INTENT(IN) :: rdt
598  REAL, INTENT(IN) :: dp0(km)
599  REAL, INTENT(IN) :: area(is-ng:ie+ng, js-ng:je+ng)
600  REAL, INTENT(IN) :: rarea(is-ng:ie+ng, js-ng:je+ng)
601  REAL, INTENT(INOUT) :: damp(km+1)
602  INTEGER, INTENT(INOUT) :: ndif(km+1)
603  REAL, INTENT(IN) :: zs(is-ng:ie+ng, js-ng:je+ng)
604  REAL, INTENT(INOUT) :: zh(is-ng:ie+ng, js-ng:je+ng, km+1)
605  REAL, INTENT(OUT) :: delz(is-ng:ie+ng, js-ng:je+ng, km)
606  REAL, DIMENSION(is:ie+1, js-ng:je+ng, km), INTENT(INOUT) :: crx, xfx
607  REAL, DIMENSION(is-ng:ie+ng, js:je+1, km), INTENT(INOUT) :: cry, yfx
608  REAL, INTENT(OUT) :: ws(is:ie, js:je)
609  TYPE(fv_grid_type), INTENT(IN), TARGET :: gridstruct
610 !-----------------------------------------------------
611 ! Local array:
612  REAL, DIMENSION(is:ie+1, js-ng:je+ng, km+1) :: crx_adv, xfx_adv
613  REAL, DIMENSION(is-ng:ie+ng, js:je+1, km+1) :: cry_adv, yfx_adv
614  REAL, DIMENSION(is:ie+1, js:je) :: fx
615  REAL, DIMENSION(is:ie, js:je+1) :: fy
616  REAL, DIMENSION(is-ng:ie+ng+1, js-ng:je+ng) :: fx2
617  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng+1) :: fy2
618  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng) :: wk2, z2
619  REAL :: ra_x(is:ie, js-ng:je+ng)
620  REAL :: ra_y(is-ng:ie+ng, js:je)
621 !--------------------------------------------------------------------
622  INTEGER :: i, j, k, isd, ied, jsd, jed
623  LOGICAL :: uniform_grid
624  INTRINSIC max
625  uniform_grid = .false.
626  damp(km+1) = damp(km)
627  ndif(km+1) = ndif(km)
628  isd = is - ng
629  ied = ie + ng
630  jsd = js - ng
631  jed = je + ng
632 !$OMP parallel do default(none) shared(jsd,jed,crx,xfx,crx_adv,xfx_adv,is,ie,isd,ied, &
633 !$OMP km,dp0,uniform_grid,js,je,cry,yfx,cry_adv,yfx_adv)
634  DO j=jsd,jed
635  CALL edge_profile(crx, xfx, crx_adv, xfx_adv, is, ie + 1, jsd, jed&
636 & , j, km, dp0, uniform_grid, 0)
637  IF (j .LE. je + 1 .AND. j .GE. js) CALL edge_profile(cry, yfx, &
638 & cry_adv, yfx_adv, &
639 & isd, ied, js, je + &
640 & 1, j, km, dp0, &
641 & uniform_grid, 0)
642  END DO
643 !$OMP parallel do default(none) shared(is,ie,js,je,isd,ied,jsd,jed,km,area,xfx_adv,yfx_adv, &
644 !$OMP damp,zh,crx_adv,cry_adv,npx,npy,hord,gridstruct,bd, &
645 !$OMP ndif,rarea) &
646 !$OMP private(z2, fx2, fy2, ra_x, ra_y, fx, fy,wk2)
647  DO k=1,km+1
648  DO j=jsd,jed
649  DO i=is,ie
650  ra_x(i, j) = area(i, j) + (xfx_adv(i, j, k)-xfx_adv(i+1, j, k)&
651 & )
652  END DO
653  END DO
654  DO j=js,je
655  DO i=isd,ied
656  ra_y(i, j) = area(i, j) + (yfx_adv(i, j, k)-yfx_adv(i, j+1, k)&
657 & )
658  END DO
659  END DO
660  IF (damp(k) .GT. 1.e-5) THEN
661  DO j=jsd,jed
662  DO i=isd,ied
663  z2(i, j) = zh(i, j, k)
664  END DO
665  END DO
666  IF (hord .EQ. hord_pert) THEN
667  CALL fv_tp_2d(z2, crx_adv(is:ie+1, jsd:jed, k), cry_adv(isd&
668 & :ied, js:je+1, k), npx, npy, hord, fx, fy, xfx_adv(&
669 & is:ie+1, jsd:jed, k), yfx_adv(isd:ied, js:je+1, k)&
670 & , gridstruct, bd, ra_x, ra_y)
671  ELSE
672  call fv_tp_2d(z2, crx_adv(is:ie+1,jsd:jed,k), cry_adv(isd:ied,js:je+1,k), npx, npy, hord, &
673  fx, fy, xfx_adv(is:ie+1,jsd:jed,k), yfx_adv(isd:ied,js:je+1,k), gridstruct, bd, ra_x, ra_y)
674  END IF
675  CALL del6_vt_flux(ndif(k), npx, npy, damp(k), z2, wk2, fx2, fy2&
676 & , gridstruct, bd)
677  DO j=js,je
678  DO i=is,ie
679  zh(i, j, k) = (z2(i, j)*area(i, j)+(fx(i, j)-fx(i+1, j))+(fy&
680 & (i, j)-fy(i, j+1)))/(ra_x(i, j)+ra_y(i, j)-area(i, j)) + (&
681 & fx2(i, j)-fx2(i+1, j)+(fy2(i, j)-fy2(i, j+1)))*rarea(i, j)
682  END DO
683  END DO
684  ELSE
685  IF (hord .EQ. hord_pert) THEN
686  CALL fv_tp_2d(zh(isd:ied, jsd:jed, k), crx_adv(is:ie+1, jsd&
687 & :jed, k), cry_adv(isd:ied, js:je+1, k), npx, npy, &
688 & hord, fx, fy, xfx_adv(is:ie+1, jsd:jed, k), yfx_adv&
689 & (isd:ied, js:je+1, k), gridstruct, bd, ra_x, ra_y)
690  ELSE
691  call fv_tp_2d(zh(isd:ied,jsd:jed,k), crx_adv(is:ie+1,jsd:jed,k), cry_adv(isd:ied,js:je+1,k), npx, npy, hord, &
692  fx, fy, xfx_adv(is:ie+1,jsd:jed,k), yfx_adv(isd:ied,js:je+1,k), gridstruct, bd, ra_x, ra_y)
693  END IF
694  DO j=js,je
695  DO i=is,ie
696  zh(i, j, k) = (zh(i, j, k)*area(i, j)+(fx(i, j)-fx(i+1, j))+&
697 & (fy(i, j)-fy(i, j+1)))/(ra_x(i, j)+ra_y(i, j)-area(i, j))
698  END DO
699  END DO
700  END IF
701  END DO
702 ! zh(i,j,k) = rarea(i,j)*(fx(i,j)-fx(i+1,j)+fy(i,j)-fy(i,j+1)) &
703 ! + zh(i,j,k)*(3.-rarea(i,j)*(ra_x(i,j) + ra_y(i,j)))
704 !$OMP parallel do default(none) shared(is,ie,js,je,km,ws,zs,zh,rdt)
705  DO j=js,je
706  DO i=is,ie
707  ws(i, j) = (zs(i, j)-zh(i, j, km+1))*rdt
708  END DO
709  DO k=km,1,-1
710  DO i=is,ie
711  IF (zh(i, j, k) .LT. zh(i, j, k+1) + dz_min) THEN
712  zh(i, j, k) = zh(i, j, k+1) + dz_min
713  ELSE
714  zh(i, j, k) = zh(i, j, k)
715  END IF
716  END DO
717  END DO
718  END DO
719  END SUBROUTINE update_dz_d
720 ! Differentiation of riem_solver_c in forward (tangent) mode:
721 ! variations of useful results: gz pef
722 ! with respect to varying inputs: ws gz delp w3 pef pt
723  SUBROUTINE riem_solver_c_tlm(ms, dt, is, ie, js, je, km, ng, akap, &
724 & cappa, cp, ptop, hs, w3, w3_tl, pt, pt_tl, q_con, delp, delp_tl, gz&
725 & , gz_tl, pef, pef_tl, ws, ws_tl, p_fac, a_imp, scale_m)
726  IMPLICIT NONE
727  INTEGER, INTENT(IN) :: is, ie, js, je, ng, km
728  INTEGER, INTENT(IN) :: ms
729  REAL, INTENT(IN) :: dt, akap, cp, ptop, p_fac, a_imp, scale_m
730  REAL, INTENT(IN) :: ws(is-ng:ie+ng, js-ng:je+ng)
731  REAL, INTENT(IN) :: ws_tl(is-ng:ie+ng, js-ng:je+ng)
732  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: pt, &
733 & delp
734  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: pt_tl, &
735 & delp_tl
736  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: q_con, &
737 & cappa
738  REAL, INTENT(IN) :: hs(is-ng:ie+ng, js-ng:je+ng)
739  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: w3
740  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: w3_tl
741 ! OUTPUT PARAMETERS
742  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km+1), INTENT(INOUT) :: gz
743  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km+1), INTENT(INOUT) :: &
744 & gz_tl
745  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km+1), INTENT(OUT) :: pef
746  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km+1), INTENT(OUT) :: &
747 & pef_tl
748 ! Local:
749  REAL, DIMENSION(is-1:ie+1, km) :: dm, dz2, w2, pm2, gm2, cp2
750  REAL, DIMENSION(is-1:ie+1, km) :: dm_tl, dz2_tl, w2_tl, pm2_tl
751  REAL, DIMENSION(is-1:ie+1, km+1) :: pem, pe2, peg
752  REAL, DIMENSION(is-1:ie+1, km+1) :: pem_tl, pe2_tl
753  REAL :: gama, rgrav
754  INTEGER :: i, j, k
755  INTEGER :: is1, ie1
756  INTRINSIC log
757  REAL :: arg1
758  REAL :: arg1_tl
759  gama = 1./(1.-akap)
760  rgrav = 1./grav
761  is1 = is - 1
762  ie1 = ie + 1
763  dm_tl = 0.0
764  pe2_tl = 0.0
765  dz2_tl = 0.0
766  w2_tl = 0.0
767  pm2_tl = 0.0
768  pem_tl = 0.0
769 !$OMP parallel do default(none) shared(js,je,is1,ie1,km,delp,pef,ptop,gz,rgrav,w3,pt, &
770 !$OMP a_imp,dt,gama,akap,ws,p_fac,scale_m,ms,hs,q_con,cappa) &
771 !$OMP private(cp2,gm2, dm, dz2, w2, pm2, pe2, pem, peg)
772  DO j=js-1,je+1
773  DO k=1,km
774  DO i=is1,ie1
775  dm_tl(i, k) = delp_tl(i, j, k)
776  dm(i, k) = delp(i, j, k)
777  END DO
778  END DO
779  DO i=is1,ie1
780 ! full pressure at top
781  pef_tl(i, j, 1) = 0.0
782  pef(i, j, 1) = ptop
783  pem_tl(i, 1) = 0.0
784  pem(i, 1) = ptop
785  END DO
786  DO k=2,km+1
787  DO i=is1,ie1
788  pem_tl(i, k) = pem_tl(i, k-1) + dm_tl(i, k-1)
789  pem(i, k) = pem(i, k-1) + dm(i, k-1)
790  END DO
791  END DO
792  DO k=1,km
793  DO i=is1,ie1
794  dz2_tl(i, k) = gz_tl(i, j, k+1) - gz_tl(i, j, k)
795  dz2(i, k) = gz(i, j, k+1) - gz(i, j, k)
796  arg1_tl = (pem_tl(i, k+1)*pem(i, k)-pem(i, k+1)*pem_tl(i, k))/&
797 & pem(i, k)**2
798  arg1 = pem(i, k+1)/pem(i, k)
799  pm2_tl(i, k) = (dm_tl(i, k)*log(arg1)-dm(i, k)*arg1_tl/arg1)/&
800 & log(arg1)**2
801  pm2(i, k) = dm(i, k)/log(arg1)
802  dm_tl(i, k) = rgrav*dm_tl(i, k)
803  dm(i, k) = dm(i, k)*rgrav
804  w2_tl(i, k) = w3_tl(i, j, k)
805  w2(i, k) = w3(i, j, k)
806  END DO
807  END DO
808  IF (a_imp .LT. -0.01) THEN
809  CALL sim3p0_solver_tlm(dt, is1, ie1, km, rdgas, gama, akap, pe2&
810 & , pe2_tl, dm, dm_tl, pem, pem_tl, w2, w2_tl, &
811 & dz2, dz2_tl, pt(is1:ie1, j, 1:km), pt_tl(is1:&
812 & ie1, j, 1:km), ws(is1:ie1, j), ws_tl(is1:ie1, j&
813 & ), p_fac, scale_m)
814  ELSE IF (a_imp .LE. 0.5) THEN
815  CALL rim_2d_tlm(ms, dt, is1, ie1, km, rdgas, gama, gm2, pe2, &
816 & pe2_tl, dm, dm_tl, pm2, pm2_tl, w2, w2_tl, dz2, dz2_tl&
817 & , pt(is1:ie1, j, 1:km), pt_tl(is1:ie1, j, 1:km), ws(&
818 & is1:ie1, j), ws_tl(is1:ie1, j), .true.)
819  ELSE
820  CALL sim1_solver_tlm(dt, is1, ie1, km, rdgas, gama, gm2, cp2, &
821 & akap, pe2, pe2_tl, dm, dm_tl, pm2, pm2_tl, pem, &
822 & pem_tl, w2, w2_tl, dz2, dz2_tl, pt(is1:ie1, j, 1:&
823 & km), pt_tl(is1:ie1, j, 1:km), ws(is1:ie1, j), &
824 & ws_tl(is1:ie1, j), p_fac)
825  END IF
826  DO k=2,km+1
827  DO i=is1,ie1
828 ! add hydrostatic full-component
829  pef_tl(i, j, k) = pe2_tl(i, k) + pem_tl(i, k)
830  pef(i, j, k) = pe2(i, k) + pem(i, k)
831  END DO
832  END DO
833 ! Compute Height * grav (for p-gradient computation)
834  DO i=is1,ie1
835  gz_tl(i, j, km+1) = 0.0
836  gz(i, j, km+1) = hs(i, j)
837  END DO
838  DO k=km,1,-1
839  DO i=is1,ie1
840  gz_tl(i, j, k) = gz_tl(i, j, k+1) - grav*dz2_tl(i, k)
841  gz(i, j, k) = gz(i, j, k+1) - dz2(i, k)*grav
842  END DO
843  END DO
844  END DO
845  END SUBROUTINE riem_solver_c_tlm
846  SUBROUTINE riem_solver_c(ms, dt, is, ie, js, je, km, ng, akap, cappa, &
847 & cp, ptop, hs, w3, pt, q_con, delp, gz, pef, ws, p_fac, a_imp, &
848 & scale_m)
849  IMPLICIT NONE
850  INTEGER, INTENT(IN) :: is, ie, js, je, ng, km
851  INTEGER, INTENT(IN) :: ms
852  REAL, INTENT(IN) :: dt, akap, cp, ptop, p_fac, a_imp, scale_m
853  REAL, INTENT(IN) :: ws(is-ng:ie+ng, js-ng:je+ng)
854  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: pt, &
855 & delp
856  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: q_con, &
857 & cappa
858  REAL, INTENT(IN) :: hs(is-ng:ie+ng, js-ng:je+ng)
859  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km), INTENT(IN) :: w3
860 ! OUTPUT PARAMETERS
861  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km+1), INTENT(INOUT) :: gz
862  REAL, DIMENSION(is-ng:ie+ng, js-ng:je+ng, km+1), INTENT(OUT) :: pef
863 ! Local:
864  REAL, DIMENSION(is-1:ie+1, km) :: dm, dz2, w2, pm2, gm2, cp2
865  REAL, DIMENSION(is-1:ie+1, km+1) :: pem, pe2, peg
866  REAL :: gama, rgrav
867  INTEGER :: i, j, k
868  INTEGER :: is1, ie1
869  INTRINSIC log
870  REAL :: arg1
871  gama = 1./(1.-akap)
872  rgrav = 1./grav
873  is1 = is - 1
874  ie1 = ie + 1
875 !$OMP parallel do default(none) shared(js,je,is1,ie1,km,delp,pef,ptop,gz,rgrav,w3,pt, &
876 !$OMP a_imp,dt,gama,akap,ws,p_fac,scale_m,ms,hs,q_con,cappa) &
877 !$OMP private(cp2,gm2, dm, dz2, w2, pm2, pe2, pem, peg)
878  DO j=js-1,je+1
879  DO k=1,km
880  DO i=is1,ie1
881  dm(i, k) = delp(i, j, k)
882  END DO
883  END DO
884  DO i=is1,ie1
885 ! full pressure at top
886  pef(i, j, 1) = ptop
887  pem(i, 1) = ptop
888  END DO
889  DO k=2,km+1
890  DO i=is1,ie1
891  pem(i, k) = pem(i, k-1) + dm(i, k-1)
892  END DO
893  END DO
894  DO k=1,km
895  DO i=is1,ie1
896  dz2(i, k) = gz(i, j, k+1) - gz(i, j, k)
897  arg1 = pem(i, k+1)/pem(i, k)
898  pm2(i, k) = dm(i, k)/log(arg1)
899  dm(i, k) = dm(i, k)*rgrav
900  w2(i, k) = w3(i, j, k)
901  END DO
902  END DO
903  IF (a_imp .LT. -0.01) THEN
904  CALL sim3p0_solver(dt, is1, ie1, km, rdgas, gama, akap, pe2, dm&
905 & , pem, w2, dz2, pt(is1:ie1, j, 1:km), ws(is1:ie1, j&
906 & ), p_fac, scale_m)
907  ELSE IF (a_imp .LE. 0.5) THEN
908  CALL rim_2d(ms, dt, is1, ie1, km, rdgas, gama, gm2, pe2, dm, pm2&
909 & , w2, dz2, pt(is1:ie1, j, 1:km), ws(is1:ie1, j), .true.)
910  ELSE
911  CALL sim1_solver(dt, is1, ie1, km, rdgas, gama, gm2, cp2, akap, &
912 & pe2, dm, pm2, pem, w2, dz2, pt(is1:ie1, j, 1:km), ws(&
913 & is1:ie1, j), p_fac)
914  END IF
915  DO k=2,km+1
916  DO i=is1,ie1
917 ! add hydrostatic full-component
918  pef(i, j, k) = pe2(i, k) + pem(i, k)
919  END DO
920  END DO
921 ! Compute Height * grav (for p-gradient computation)
922  DO i=is1,ie1
923  gz(i, j, km+1) = hs(i, j)
924  END DO
925  DO k=km,1,-1
926  DO i=is1,ie1
927  gz(i, j, k) = gz(i, j, k+1) - dz2(i, k)*grav
928  END DO
929  END DO
930  END DO
931  END SUBROUTINE riem_solver_c
932 !GFDL - This routine will not give absoulte reproducibility when compiled with -fast-transcendentals.
933 !GFDL - It is now inside of nh_core.F90 and being compiled without -fast-transcendentals.
934  SUBROUTINE riem_solver3test(ms, dt, is, ie, js, je, km, ng, isd, ied, &
935 & jsd, jed, akap, cappa, cp, ptop, zs, q_con, w, delz, pt, delp, zh, &
936 & pe, ppe, pk3, pk, peln, ws, scale_m, p_fac, a_imp, use_logp, &
937 & last_call, fp_out)
938  IMPLICIT NONE
939 !--------------------------------------------
940 ! !OUTPUT PARAMETERS
941 ! Ouput: gz: grav*height at edges
942 ! pe: full hydrostatic pressure
943 ! ppe: non-hydrostatic pressure perturbation
944 !--------------------------------------------
945  INTEGER, INTENT(IN) :: ms, is, ie, js, je, km, ng
946  INTEGER, INTENT(IN) :: isd, ied, jsd, jed
947 ! the BIG horizontal Lagrangian time step
948  REAL, INTENT(IN) :: dt
949  REAL, INTENT(IN) :: akap, cp, ptop, p_fac, a_imp, scale_m
950  REAL, INTENT(IN) :: zs(isd:ied, jsd:jed)
951  LOGICAL, INTENT(IN) :: last_call, use_logp, fp_out
952  REAL, INTENT(IN) :: ws(is:ie, js:je)
953  REAL, DIMENSION(isd:ied, jsd:jed, km), INTENT(IN) :: q_con, cappa
954  REAL, DIMENSION(isd:ied, jsd:jed, km), INTENT(IN) :: delp, pt
955  REAL, DIMENSION(isd:ied, jsd:jed, km+1), INTENT(INOUT) :: zh
956  REAL, DIMENSION(isd:ied, jsd:jed, km), INTENT(INOUT) :: w
957  REAL, INTENT(INOUT) :: pe(is-1:ie+1, km+1, js-1:je+1)
958 ! ln(pe)
959  REAL, INTENT(OUT) :: peln(is:ie, km+1, js:je)
960  REAL, DIMENSION(isd:ied, jsd:jed, km+1), INTENT(OUT) :: ppe
961  REAL, INTENT(OUT) :: delz(is-ng:ie+ng, js-ng:je+ng, km)
962  REAL, INTENT(OUT) :: pk(is:ie, js:je, km+1)
963  REAL, INTENT(OUT) :: pk3(isd:ied, jsd:jed, km+1)
964 ! Local:
965  REAL, DIMENSION(is:ie, km) :: dm, dz2, pm2, w2, gm2, cp2
966  REAL, DIMENSION(is:ie, km+1) :: pem, pe2, peln2, peg, pelng
967  REAL :: gama, rgrav, ptk, peln1
968  INTEGER :: i, j, k
969  INTRINSIC log
970  INTRINSIC exp
971  INTRINSIC abs
972  REAL :: abs0
973  gama = 1./(1.-akap)
974  rgrav = 1./grav
975  peln1 = log(ptop)
976  ptk = exp(akap*peln1)
977 !$OMP parallel do default(none) shared(is,ie,js,je,km,delp,ptop,peln1,pk3,ptk,akap,rgrav,zh,pt, &
978 !$OMP w,a_imp,dt,gama,ws,p_fac,scale_m,ms,delz,last_call, &
979 !$OMP peln,pk,fp_out,ppe,use_logp,zs,pe,cappa,q_con ) &
980 !$OMP private(cp2, gm2, dm, dz2, pm2, pem, peg, pelng, pe2, peln2, w2)
981  DO j=js,je
982  DO k=1,km
983  DO i=is,ie
984  dm(i, k) = delp(i, j, k)
985  END DO
986  END DO
987  DO i=is,ie
988  pem(i, 1) = ptop
989  peln2(i, 1) = peln1
990  pk3(i, j, 1) = ptk
991  END DO
992  DO k=2,km+1
993  DO i=is,ie
994  pem(i, k) = pem(i, k-1) + dm(i, k-1)
995  peln2(i, k) = log(pem(i, k))
996  pk3(i, j, k) = exp(akap*peln2(i, k))
997  END DO
998  END DO
999  DO k=1,km
1000  DO i=is,ie
1001  pm2(i, k) = dm(i, k)/(peln2(i, k+1)-peln2(i, k))
1002  dm(i, k) = dm(i, k)*rgrav
1003  dz2(i, k) = zh(i, j, k+1) - zh(i, j, k)
1004  w2(i, k) = w(i, j, k)
1005  END DO
1006  END DO
1007  IF (a_imp .LT. -0.999) THEN
1008  CALL sim3p0_solver(dt, is, ie, km, rdgas, gama, akap, pe2, dm, &
1009 & pem, w2, dz2, pt(is:ie, j, 1:km), ws(is:ie, j), &
1010 & p_fac, scale_m)
1011  ELSE IF (a_imp .LT. -0.5) THEN
1012  IF (a_imp .GE. 0.) THEN
1013  abs0 = a_imp
1014  ELSE
1015  abs0 = -a_imp
1016  END IF
1017  CALL sim3_solver(dt, is, ie, km, rdgas, gama, akap, pe2, dm, pem&
1018 & , w2, dz2, pt(is:ie, j, 1:km), ws(is:ie, j), abs0, &
1019 & p_fac, scale_m)
1020  ELSE IF (a_imp .LE. 0.5) THEN
1021  CALL rim_2d(ms, dt, is, ie, km, rdgas, gama, gm2, pe2, dm, pm2, &
1022 & w2, dz2, pt(is:ie, j, 1:km), ws(is:ie, j), .false.)
1023  ELSE IF (a_imp .GT. 0.999) THEN
1024  CALL sim1_solver(dt, is, ie, km, rdgas, gama, gm2, cp2, akap, &
1025 & pe2, dm, pm2, pem, w2, dz2, pt(is:ie, j, 1:km), ws(is&
1026 & :ie, j), p_fac)
1027  ELSE
1028  CALL sim_solver(dt, is, ie, km, rdgas, gama, gm2, cp2, akap, pe2&
1029 & , dm, pm2, pem, w2, dz2, pt(is:ie, j, 1:km), ws(is:ie&
1030 & , j), a_imp, p_fac, scale_m)
1031  END IF
1032  DO k=1,km
1033  DO i=is,ie
1034  w(i, j, k) = w2(i, k)
1035  delz(i, j, k) = dz2(i, k)
1036  END DO
1037  END DO
1038  IF (last_call) THEN
1039  DO k=1,km+1
1040  DO i=is,ie
1041  peln(i, k, j) = peln2(i, k)
1042  pk(i, j, k) = pk3(i, j, k)
1043  pe(i, k, j) = pem(i, k)
1044  END DO
1045  END DO
1046  END IF
1047  IF (fp_out) THEN
1048  DO k=1,km+1
1049  DO i=is,ie
1050  ppe(i, j, k) = pe2(i, k) + pem(i, k)
1051  END DO
1052  END DO
1053  ELSE
1054  DO k=1,km+1
1055  DO i=is,ie
1056  ppe(i, j, k) = pe2(i, k)
1057  END DO
1058  END DO
1059  END IF
1060  IF (use_logp) THEN
1061  DO k=2,km+1
1062  DO i=is,ie
1063  pk3(i, j, k) = peln2(i, k)
1064  END DO
1065  END DO
1066  END IF
1067  DO i=is,ie
1068  zh(i, j, km+1) = zs(i, j)
1069  END DO
1070  DO k=km,1,-1
1071  DO i=is,ie
1072  zh(i, j, k) = zh(i, j, k+1) - dz2(i, k)
1073  END DO
1074  END DO
1075  END DO
1076  END SUBROUTINE riem_solver3test
1077  SUBROUTINE imp_diff_w(j, is, ie, js, je, ng, km, cd, delz, ws, w, w3)
1078  IMPLICIT NONE
1079  INTEGER, INTENT(IN) :: j, is, ie, js, je, km, ng
1080  REAL, INTENT(IN) :: cd
1081 ! delta-height (m)
1082  REAL, INTENT(IN) :: delz(is-ng:ie+ng, km)
1083 ! vertical vel. (m/s)
1084  REAL, INTENT(IN) :: w(is:ie, km)
1085  REAL, INTENT(IN) :: ws(is:ie)
1086  REAL, INTENT(OUT) :: w3(is-ng:ie+ng, js-ng:je+ng, km)
1087 ! Local:
1088  REAL, DIMENSION(is:ie, km) :: c, gam, dz, wt
1089  REAL :: bet(is:ie)
1090  REAL :: a
1091  INTEGER :: i, k
1092  DO k=2,km
1093  DO i=is,ie
1094  dz(i, k) = 0.5*(delz(i, k-1)+delz(i, k))
1095  END DO
1096  END DO
1097  DO k=1,km-1
1098  DO i=is,ie
1099  c(i, k) = -(cd/(dz(i, k+1)*delz(i, k)))
1100  END DO
1101  END DO
1102 ! model top:
1103  DO i=is,ie
1104 ! bet(i) = b
1105  bet(i) = 1. - c(i, 1)
1106  wt(i, 1) = w(i, 1)/bet(i)
1107  END DO
1108 ! Interior:
1109  DO k=2,km-1
1110  DO i=is,ie
1111  gam(i, k) = c(i, k-1)/bet(i)
1112  a = cd/(dz(i, k)*delz(i, k))
1113  bet(i) = 1. + a - c(i, k) + a*gam(i, k)
1114  wt(i, k) = (w(i, k)+a*wt(i, k-1))/bet(i)
1115  END DO
1116  END DO
1117 ! Bottom:
1118  DO i=is,ie
1119  gam(i, km) = c(i, km-1)/bet(i)
1120  a = cd/(dz(i, km)*delz(i, km))
1121  wt(i, km) = (w(i, km)+2.*ws(i)*cd/delz(i, km)**2+a*wt(i, km-1))/(&
1122 & 1.+a+(cd+cd)/delz(i, km)**2+a*gam(i, km))
1123  END DO
1124  DO k=km-1,1,-1
1125  DO i=is,ie
1126  wt(i, k) = wt(i, k) - gam(i, k+1)*wt(i, k+1)
1127  END DO
1128  END DO
1129  DO k=1,km
1130  DO i=is,ie
1131  w3(i, j, k) = wt(i, k)
1132  END DO
1133  END DO
1134  END SUBROUTINE imp_diff_w
1135 ! Differentiation of rim_2d in forward (tangent) mode:
1136 ! variations of useful results: pe2 dz2 w2
1137 ! with respect to varying inputs: ws pe2 dm2 dz2 w2 pm2 pt2
1138  SUBROUTINE rim_2d_tlm(ms, bdt, is, ie, km, rgas, gama, gm2, pe2, &
1139 & pe2_tl, dm2, dm2_tl, pm2, pm2_tl, w2, w2_tl, dz2, dz2_tl, pt2, &
1140 & pt2_tl, ws, ws_tl, c_core)
1141  IMPLICIT NONE
1142  INTEGER, INTENT(IN) :: ms, is, ie, km
1143  REAL, INTENT(IN) :: bdt, gama, rgas
1144  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm2, pm2, gm2
1145  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm2_tl, pm2_tl
1146  LOGICAL, INTENT(IN) :: c_core
1147  REAL, INTENT(IN) :: pt2(is:ie, km)
1148  REAL, INTENT(IN) :: pt2_tl(is:ie, km)
1149  REAL, INTENT(IN) :: ws(is:ie)
1150  REAL, INTENT(IN) :: ws_tl(is:ie)
1151 ! IN/OUT:
1152  REAL, INTENT(INOUT) :: dz2(is:ie, km)
1153  REAL, INTENT(INOUT) :: dz2_tl(is:ie, km)
1154  REAL, INTENT(INOUT) :: w2(is:ie, km)
1155  REAL, INTENT(INOUT) :: w2_tl(is:ie, km)
1156  REAL, INTENT(OUT) :: pe2(is:ie, km+1)
1157  REAL, INTENT(OUT) :: pe2_tl(is:ie, km+1)
1158 ! Local:
1159  REAL :: ws2(is:ie)
1160  REAL :: ws2_tl(is:ie)
1161  REAL, DIMENSION(km+1) :: m_bot, m_top, r_bot, r_top, pe1, pbar, wbar
1162  REAL, DIMENSION(km+1) :: m_bot_tl, m_top_tl, r_bot_tl, r_top_tl, &
1163 & pe1_tl, pbar_tl, wbar_tl
1164  REAL, DIMENSION(km) :: r_hi, r_lo, dz, wm, dm, dts
1165  REAL, DIMENSION(km) :: r_hi_tl, r_lo_tl, dz_tl, wm_tl, dm_tl, dts_tl
1166  REAL, DIMENSION(km) :: pf1, wc, cm, pp, pt1
1167  REAL, DIMENSION(km) :: pf1_tl, wc_tl, cm_tl, pp_tl, pt1_tl
1168  REAL :: dt, rdt, grg, z_frac, ptmp1, rden, pf, time_left
1169  REAL :: z_frac_tl, ptmp1_tl, rden_tl, pf_tl, time_left_tl
1170  REAL :: m_surf
1171  REAL :: m_surf_tl
1172  INTEGER :: i, k, n, ke, kt1, ktop
1173  INTEGER :: ks0, ks1
1174  INTRINSIC real
1175  INTRINSIC log
1176  INTRINSIC exp
1177  INTRINSIC sqrt
1178  INTRINSIC max
1179  REAL :: arg1
1180  REAL :: arg1_tl
1181  REAL :: result1
1182  REAL :: result1_tl
1183  grg = gama*rgas
1184  rdt = 1./bdt
1185  dt = bdt/REAL(ms)
1186  pbar(:) = 0.
1187  wbar(:) = 0.
1188  ws2_tl = 0.0
1189  DO i=is,ie
1190  ws2_tl(i) = 2.*ws_tl(i)
1191  ws2(i) = 2.*ws(i)
1192  END DO
1193  dm_tl = 0.0
1194  dts_tl = 0.0
1195  dz_tl = 0.0
1196  r_lo_tl = 0.0
1197  wbar_tl = 0.0
1198  pf1_tl = 0.0
1199  m_top_tl = 0.0
1200  r_top_tl = 0.0
1201  m_bot_tl = 0.0
1202  r_bot_tl = 0.0
1203  pt1_tl = 0.0
1204  cm_tl = 0.0
1205  pp_tl = 0.0
1206  wc_tl = 0.0
1207  pbar_tl = 0.0
1208  wm_tl = 0.0
1209  r_hi_tl = 0.0
1210 ! end i-loop
1211  DO 6000 i=is,ie
1212  DO k=1,km
1213  dz_tl(k) = dz2_tl(i, k)
1214  dz(k) = dz2(i, k)
1215  dm_tl(k) = dm2_tl(i, k)
1216  dm(k) = dm2(i, k)
1217  wm_tl(k) = w2_tl(i, k)*dm(k) + w2(i, k)*dm_tl(k)
1218  wm(k) = w2(i, k)*dm(k)
1219  pt1_tl(k) = pt2_tl(i, k)
1220  pt1(k) = pt2(i, k)
1221  END DO
1222  pe1(:) = 0.
1223  wbar_tl(km+1) = ws_tl(i)
1224  wbar(km+1) = ws(i)
1225  ks0 = 1
1226  IF (ms .GT. 1 .AND. ms .LT. 8) THEN
1227 ! Continuity of (pbar, wbar) is maintained
1228  DO k=1,km
1229  rden_tl = -((rgas*dm_tl(k)*dz(k)-rgas*dm(k)*dz_tl(k))/dz(k)**2&
1230 & )
1231  rden = -(rgas*dm(k)/dz(k))
1232  arg1_tl = gama*(rden_tl*pt1(k)+rden*pt1_tl(k))/(rden*pt1(k))
1233  arg1 = gama*log(rden*pt1(k))
1234  pf1_tl(k) = arg1_tl*exp(arg1)
1235  pf1(k) = exp(arg1)
1236  arg1_tl = (grg*pf1_tl(k)*rden-grg*pf1(k)*rden_tl)/rden**2
1237  arg1 = grg*pf1(k)/rden
1238  IF (arg1 .EQ. 0.0) THEN
1239  result1_tl = 0.0
1240  ELSE
1241  result1_tl = arg1_tl/(2.0*sqrt(arg1))
1242  END IF
1243  result1 = sqrt(arg1)
1244  dts_tl(k) = -((dz_tl(k)*result1-dz(k)*result1_tl)/result1**2)
1245  dts(k) = -(dz(k)/result1)
1246  IF (bdt .GT. dts(k)) GOTO 100
1247  END DO
1248  ks0 = km
1249  GOTO 222
1250  100 ks0 = k - 1
1251  222 IF (ks0 .EQ. 1) THEN
1252  pe1_tl = 0.0
1253  ELSE
1254  DO k=1,ks0
1255  cm_tl(k) = (dm_tl(k)*dts(k)-dm(k)*dts_tl(k))/dts(k)**2
1256  cm(k) = dm(k)/dts(k)
1257  wc_tl(k) = (wm_tl(k)*dts(k)-wm(k)*dts_tl(k))/dts(k)**2
1258  wc(k) = wm(k)/dts(k)
1259  pp_tl(k) = pf1_tl(k) - pm2_tl(i, k)
1260  pp(k) = pf1(k) - pm2(i, k)
1261  END DO
1262  wbar_tl(1) = ((wc_tl(1)+pp_tl(1))*cm(1)-(wc(1)+pp(1))*cm_tl(1)&
1263 & )/cm(1)**2
1264  wbar(1) = (wc(1)+pp(1))/cm(1)
1265  pe1_tl = 0.0
1266  DO k=2,ks0
1267  wbar_tl(k) = ((wc_tl(k-1)+wc_tl(k)+pp_tl(k)-pp_tl(k-1))*(cm(&
1268 & k-1)+cm(k))-(wc(k-1)+wc(k)+pp(k)-pp(k-1))*(cm_tl(k-1)+&
1269 & cm_tl(k)))/(cm(k-1)+cm(k))**2
1270  wbar(k) = (wc(k-1)+wc(k)+pp(k)-pp(k-1))/(cm(k-1)+cm(k))
1271  pbar_tl(k) = bdt*(cm_tl(k-1)*wbar(k)+cm(k-1)*wbar_tl(k)-&
1272 & wc_tl(k-1)+pp_tl(k-1))
1273  pbar(k) = bdt*(cm(k-1)*wbar(k)-wc(k-1)+pp(k-1))
1274  pe1_tl(k) = pbar_tl(k)
1275  pe1(k) = pbar(k)
1276  END DO
1277  IF (ks0 .EQ. km) THEN
1278  pbar_tl(km+1) = bdt*(cm_tl(km)*wbar(km+1)+cm(km)*wbar_tl(km+&
1279 & 1)-wc_tl(km)+pp_tl(km))
1280  pbar(km+1) = bdt*(cm(km)*wbar(km+1)-wc(km)+pp(km))
1281  IF (c_core) THEN
1282  DO k=1,km
1283  dz2_tl(i, k) = dz_tl(k) + bdt*(wbar_tl(k+1)-wbar_tl(k))
1284  dz2(i, k) = dz(k) + bdt*(wbar(k+1)-wbar(k))
1285  END DO
1286  ELSE
1287  DO k=1,km
1288  dz2_tl(i, k) = dz_tl(k) + bdt*(wbar_tl(k+1)-wbar_tl(k))
1289  dz2(i, k) = dz(k) + bdt*(wbar(k+1)-wbar(k))
1290  w2_tl(i, k) = ((wm_tl(k)+pbar_tl(k+1)-pbar_tl(k))*dm(k)-&
1291 & (wm(k)+pbar(k+1)-pbar(k))*dm_tl(k))/dm(k)**2
1292  w2(i, k) = (wm(k)+pbar(k+1)-pbar(k))/dm(k)
1293  END DO
1294  END IF
1295  pe2_tl(i, 1) = 0.0
1296  pe2(i, 1) = 0.
1297  DO k=2,km+1
1298  pe2_tl(i, k) = rdt*pbar_tl(k)
1299  pe2(i, k) = pbar(k)*rdt
1300  END DO
1301  GOTO 6000
1302  ELSE
1303 ! next i
1304  IF (c_core) THEN
1305  DO k=1,ks0-1
1306  dz2_tl(i, k) = dz_tl(k) + bdt*(wbar_tl(k+1)-wbar_tl(k))
1307  dz2(i, k) = dz(k) + bdt*(wbar(k+1)-wbar(k))
1308  END DO
1309  ELSE
1310  DO k=1,ks0-1
1311  dz2_tl(i, k) = dz_tl(k) + bdt*(wbar_tl(k+1)-wbar_tl(k))
1312  dz2(i, k) = dz(k) + bdt*(wbar(k+1)-wbar(k))
1313  w2_tl(i, k) = ((wm_tl(k)+pbar_tl(k+1)-pbar_tl(k))*dm(k)-&
1314 & (wm(k)+pbar(k+1)-pbar(k))*dm_tl(k))/dm(k)**2
1315  w2(i, k) = (wm(k)+pbar(k+1)-pbar(k))/dm(k)
1316  END DO
1317  END IF
1318  pbar_tl(ks0) = pbar_tl(ks0)/REAL(ms)
1319  pbar(ks0) = pbar(ks0)/REAL(ms)
1320  END IF
1321  END IF
1322  ELSE
1323  pe1_tl = 0.0
1324  END IF
1325  ks1 = ks0
1326  DO n=1,ms
1327  DO k=ks1,km
1328  rden_tl = -((rgas*dm_tl(k)*dz(k)-rgas*dm(k)*dz_tl(k))/dz(k)**2&
1329 & )
1330  rden = -(rgas*dm(k)/dz(k))
1331  arg1_tl = gama*(rden_tl*pt1(k)+rden*pt1_tl(k))/(rden*pt1(k))
1332  arg1 = gama*log(rden*pt1(k))
1333  pf_tl = arg1_tl*exp(arg1)
1334  pf = exp(arg1)
1335  arg1_tl = (grg*pf_tl*rden-grg*pf*rden_tl)/rden**2
1336  arg1 = grg*pf/rden
1337  IF (arg1 .EQ. 0.0) THEN
1338  result1_tl = 0.0
1339  ELSE
1340  result1_tl = arg1_tl/(2.0*sqrt(arg1))
1341  END IF
1342  result1 = sqrt(arg1)
1343  dts_tl(k) = -((dz_tl(k)*result1-dz(k)*result1_tl)/result1**2)
1344  dts(k) = -(dz(k)/result1)
1345  ptmp1_tl = dts_tl(k)*(pf-pm2(i, k)) + dts(k)*(pf_tl-pm2_tl(i, &
1346 & k))
1347  ptmp1 = dts(k)*(pf-pm2(i, k))
1348  r_lo_tl(k) = wm_tl(k) + ptmp1_tl
1349  r_lo(k) = wm(k) + ptmp1
1350  r_hi_tl(k) = wm_tl(k) - ptmp1_tl
1351  r_hi(k) = wm(k) - ptmp1
1352  END DO
1353  ktop = ks1
1354  DO k=ks1,km
1355  IF (dt .GT. dts(k)) GOTO 110
1356  END DO
1357  ktop = km
1358  GOTO 333
1359  110 ktop = k - 1
1360  333 IF (ktop .GE. ks1) THEN
1361  DO k=ks1,ktop
1362  z_frac_tl = -(dt*dts_tl(k)/dts(k)**2)
1363  z_frac = dt/dts(k)
1364  r_bot_tl(k) = z_frac_tl*r_lo(k) + z_frac*r_lo_tl(k)
1365  r_bot(k) = z_frac*r_lo(k)
1366  r_top_tl(k+1) = z_frac_tl*r_hi(k) + z_frac*r_hi_tl(k)
1367  r_top(k+1) = z_frac*r_hi(k)
1368  m_bot_tl(k) = z_frac_tl*dm(k) + z_frac*dm_tl(k)
1369  m_bot(k) = z_frac*dm(k)
1370  m_top_tl(k+1) = m_bot_tl(k)
1371  m_top(k+1) = m_bot(k)
1372  END DO
1373  IF (ktop .EQ. km) GOTO 666
1374  END IF
1375  DO k=ktop+2,km+1
1376  m_top_tl(k) = 0.0
1377  m_top(k) = 0.
1378  r_top_tl(k) = 0.0
1379  r_top(k) = 0.
1380  END DO
1381  IF (1 .LT. ktop) THEN
1382  kt1 = ktop
1383  ELSE
1384  kt1 = 1
1385  END IF
1386  DO 444 ke=km+1,ktop+2,-1
1387  time_left = dt
1388  time_left_tl = 0.0
1389  DO k=ke-1,kt1,-1
1390  IF (time_left .GT. dts(k)) THEN
1391  time_left_tl = time_left_tl - dts_tl(k)
1392  time_left = time_left - dts(k)
1393  m_top_tl(ke) = m_top_tl(ke) + dm_tl(k)
1394  m_top(ke) = m_top(ke) + dm(k)
1395  r_top_tl(ke) = r_top_tl(ke) + r_hi_tl(k)
1396  r_top(ke) = r_top(ke) + r_hi(k)
1397  ELSE
1398  GOTO 120
1399  END IF
1400  END DO
1401  GOTO 444
1402  120 z_frac_tl = (time_left_tl*dts(k)-time_left*dts_tl(k))/dts(k)**&
1403 & 2
1404  z_frac = time_left/dts(k)
1405  m_top_tl(ke) = m_top_tl(ke) + z_frac_tl*dm(k) + z_frac*dm_tl(k&
1406 & )
1407  m_top(ke) = m_top(ke) + z_frac*dm(k)
1408  r_top_tl(ke) = r_top_tl(ke) + z_frac_tl*r_hi(k) + z_frac*&
1409 & r_hi_tl(k)
1410  r_top(ke) = r_top(ke) + z_frac*r_hi(k)
1411  444 CONTINUE
1412 ! next level
1413  DO k=ktop+1,km
1414  m_bot_tl(k) = 0.0
1415  m_bot(k) = 0.
1416  r_bot_tl(k) = 0.0
1417  r_bot(k) = 0.
1418  END DO
1419  DO 4000 ke=ktop+1,km
1420  time_left = dt
1421  time_left_tl = 0.0
1422  DO k=ke,km
1423  IF (time_left .GT. dts(k)) THEN
1424  time_left_tl = time_left_tl - dts_tl(k)
1425  time_left = time_left - dts(k)
1426  m_bot_tl(ke) = m_bot_tl(ke) + dm_tl(k)
1427  m_bot(ke) = m_bot(ke) + dm(k)
1428  r_bot_tl(ke) = r_bot_tl(ke) + r_lo_tl(k)
1429  r_bot(ke) = r_bot(ke) + r_lo(k)
1430  ELSE
1431  GOTO 140
1432  END IF
1433  END DO
1434 ! next interface
1435  m_surf_tl = m_bot_tl(ke)
1436  m_surf = m_bot(ke)
1437  DO k=km,kt1,-1
1438  IF (time_left .GT. dts(k)) THEN
1439  time_left_tl = time_left_tl - dts_tl(k)
1440  time_left = time_left - dts(k)
1441  m_bot_tl(ke) = m_bot_tl(ke) + dm_tl(k)
1442  m_bot(ke) = m_bot(ke) + dm(k)
1443  r_bot_tl(ke) = r_bot_tl(ke) - r_hi_tl(k)
1444  r_bot(ke) = r_bot(ke) - r_hi(k)
1445  ELSE
1446  GOTO 130
1447  END IF
1448  END DO
1449  GOTO 4000
1450  130 z_frac_tl = (time_left_tl*dts(k)-time_left*dts_tl(k))/dts(k)**&
1451 & 2
1452  z_frac = time_left/dts(k)
1453  m_bot_tl(ke) = m_bot_tl(ke) + z_frac_tl*dm(k) + z_frac*dm_tl(k&
1454 & )
1455  m_bot(ke) = m_bot(ke) + z_frac*dm(k)
1456  r_bot_tl(ke) = r_bot_tl(ke) - z_frac_tl*r_hi(k) - z_frac*&
1457 & r_hi_tl(k) + (m_bot_tl(ke)-m_surf_tl)*ws2(i) + (m_bot(ke)-&
1458 & m_surf)*ws2_tl(i)
1459  r_bot(ke) = r_bot(ke) - z_frac*r_hi(k) + (m_bot(ke)-m_surf)*&
1460 & ws2(i)
1461  GOTO 4000
1462  140 z_frac_tl = (time_left_tl*dts(k)-time_left*dts_tl(k))/dts(k)**&
1463 & 2
1464  z_frac = time_left/dts(k)
1465  m_bot_tl(ke) = m_bot_tl(ke) + z_frac_tl*dm(k) + z_frac*dm_tl(k&
1466 & )
1467  m_bot(ke) = m_bot(ke) + z_frac*dm(k)
1468  r_bot_tl(ke) = r_bot_tl(ke) + z_frac_tl*r_lo(k) + z_frac*&
1469 & r_lo_tl(k)
1470  r_bot(ke) = r_bot(ke) + z_frac*r_lo(k)
1471  4000 CONTINUE
1472 ! next interface
1473  666 IF (ks1 .EQ. 1) THEN
1474  wbar_tl(1) = (r_bot_tl(1)*m_bot(1)-r_bot(1)*m_bot_tl(1))/m_bot&
1475 & (1)**2
1476  wbar(1) = r_bot(1)/m_bot(1)
1477  END IF
1478  DO k=ks1+1,km
1479  wbar_tl(k) = ((r_bot_tl(k)+r_top_tl(k))*(m_top(k)+m_bot(k))-(&
1480 & r_bot(k)+r_top(k))*(m_top_tl(k)+m_bot_tl(k)))/(m_top(k)+&
1481 & m_bot(k))**2
1482  wbar(k) = (r_bot(k)+r_top(k))/(m_top(k)+m_bot(k))
1483  END DO
1484 ! pbar here is actually dt*pbar
1485  DO k=ks1+1,km+1
1486  pbar_tl(k) = m_top_tl(k)*wbar(k) + m_top(k)*wbar_tl(k) - &
1487 & r_top_tl(k)
1488  pbar(k) = m_top(k)*wbar(k) - r_top(k)
1489  pe1_tl(k) = pe1_tl(k) + pbar_tl(k)
1490  pe1(k) = pe1(k) + pbar(k)
1491  END DO
1492  IF (n .EQ. ms) THEN
1493  IF (c_core) THEN
1494  DO k=ks1,km
1495  dz2_tl(i, k) = dz_tl(k) + dt*(wbar_tl(k+1)-wbar_tl(k))
1496  dz2(i, k) = dz(k) + dt*(wbar(k+1)-wbar(k))
1497  END DO
1498  ELSE
1499  DO k=ks1,km
1500  dz2_tl(i, k) = dz_tl(k) + dt*(wbar_tl(k+1)-wbar_tl(k))
1501  dz2(i, k) = dz(k) + dt*(wbar(k+1)-wbar(k))
1502  w2_tl(i, k) = ((wm_tl(k)+pbar_tl(k+1)-pbar_tl(k))*dm(k)-(&
1503 & wm(k)+pbar(k+1)-pbar(k))*dm_tl(k))/dm(k)**2
1504  w2(i, k) = (wm(k)+pbar(k+1)-pbar(k))/dm(k)
1505  END DO
1506  END IF
1507  ELSE
1508  DO k=ks1,km
1509  dz_tl(k) = dz_tl(k) + dt*(wbar_tl(k+1)-wbar_tl(k))
1510  dz(k) = dz(k) + dt*(wbar(k+1)-wbar(k))
1511  wm_tl(k) = wm_tl(k) + pbar_tl(k+1) - pbar_tl(k)
1512  wm(k) = wm(k) + pbar(k+1) - pbar(k)
1513  END DO
1514  END IF
1515  END DO
1516  pe2_tl(i, 1) = 0.0
1517  pe2(i, 1) = 0.
1518  DO k=2,km+1
1519  pe2_tl(i, k) = rdt*pe1_tl(k)
1520  pe2(i, k) = pe1(k)*rdt
1521  END DO
1522  6000 CONTINUE
1523  END SUBROUTINE rim_2d_tlm
1524  SUBROUTINE rim_2d(ms, bdt, is, ie, km, rgas, gama, gm2, pe2, dm2, pm2&
1525 & , w2, dz2, pt2, ws, c_core)
1526  IMPLICIT NONE
1527  INTEGER, INTENT(IN) :: ms, is, ie, km
1528  REAL, INTENT(IN) :: bdt, gama, rgas
1529  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm2, pm2, gm2
1530  LOGICAL, INTENT(IN) :: c_core
1531  REAL, INTENT(IN) :: pt2(is:ie, km)
1532  REAL, INTENT(IN) :: ws(is:ie)
1533 ! IN/OUT:
1534  REAL, INTENT(INOUT) :: dz2(is:ie, km)
1535  REAL, INTENT(INOUT) :: w2(is:ie, km)
1536  REAL, INTENT(OUT) :: pe2(is:ie, km+1)
1537 ! Local:
1538  REAL :: ws2(is:ie)
1539  REAL, DIMENSION(km+1) :: m_bot, m_top, r_bot, r_top, pe1, pbar, wbar
1540  REAL, DIMENSION(km) :: r_hi, r_lo, dz, wm, dm, dts
1541  REAL, DIMENSION(km) :: pf1, wc, cm, pp, pt1
1542  REAL :: dt, rdt, grg, z_frac, ptmp1, rden, pf, time_left
1543  REAL :: m_surf
1544  INTEGER :: i, k, n, ke, kt1, ktop
1545  INTEGER :: ks0, ks1
1546  INTRINSIC real
1547  INTRINSIC log
1548  INTRINSIC exp
1549  INTRINSIC sqrt
1550  INTRINSIC max
1551  REAL :: arg1
1552  REAL :: result1
1553  grg = gama*rgas
1554  rdt = 1./bdt
1555  dt = bdt/REAL(ms)
1556  pbar(:) = 0.
1557  wbar(:) = 0.
1558  DO i=is,ie
1559  ws2(i) = 2.*ws(i)
1560  END DO
1561 ! end i-loop
1562  DO i=is,ie
1563  DO k=1,km
1564  dz(k) = dz2(i, k)
1565  dm(k) = dm2(i, k)
1566  wm(k) = w2(i, k)*dm(k)
1567  pt1(k) = pt2(i, k)
1568  END DO
1569  pe1(:) = 0.
1570  wbar(km+1) = ws(i)
1571  ks0 = 1
1572  IF (ms .GT. 1 .AND. ms .LT. 8) THEN
1573 ! Continuity of (pbar, wbar) is maintained
1574  DO k=1,km
1575  rden = -(rgas*dm(k)/dz(k))
1576  arg1 = gama*log(rden*pt1(k))
1577  pf1(k) = exp(arg1)
1578  arg1 = grg*pf1(k)/rden
1579  result1 = sqrt(arg1)
1580  dts(k) = -(dz(k)/result1)
1581  IF (bdt .GT. dts(k)) THEN
1582  ks0 = k - 1
1583  GOTO 222
1584  END IF
1585  END DO
1586  ks0 = km
1587  222 IF (ks0 .NE. 1) THEN
1588  DO k=1,ks0
1589  cm(k) = dm(k)/dts(k)
1590  wc(k) = wm(k)/dts(k)
1591  pp(k) = pf1(k) - pm2(i, k)
1592  END DO
1593  wbar(1) = (wc(1)+pp(1))/cm(1)
1594  DO k=2,ks0
1595  wbar(k) = (wc(k-1)+wc(k)+pp(k)-pp(k-1))/(cm(k-1)+cm(k))
1596  pbar(k) = bdt*(cm(k-1)*wbar(k)-wc(k-1)+pp(k-1))
1597  pe1(k) = pbar(k)
1598  END DO
1599  IF (ks0 .EQ. km) THEN
1600  pbar(km+1) = bdt*(cm(km)*wbar(km+1)-wc(km)+pp(km))
1601  IF (c_core) THEN
1602  DO k=1,km
1603  dz2(i, k) = dz(k) + bdt*(wbar(k+1)-wbar(k))
1604  END DO
1605  ELSE
1606  DO k=1,km
1607  dz2(i, k) = dz(k) + bdt*(wbar(k+1)-wbar(k))
1608  w2(i, k) = (wm(k)+pbar(k+1)-pbar(k))/dm(k)
1609  END DO
1610  END IF
1611  pe2(i, 1) = 0.
1612  DO k=2,km+1
1613  pe2(i, k) = pbar(k)*rdt
1614  END DO
1615  GOTO 6000
1616  ELSE
1617 ! next i
1618  IF (c_core) THEN
1619  DO k=1,ks0-1
1620  dz2(i, k) = dz(k) + bdt*(wbar(k+1)-wbar(k))
1621  END DO
1622  ELSE
1623  DO k=1,ks0-1
1624  dz2(i, k) = dz(k) + bdt*(wbar(k+1)-wbar(k))
1625  w2(i, k) = (wm(k)+pbar(k+1)-pbar(k))/dm(k)
1626  END DO
1627  END IF
1628  pbar(ks0) = pbar(ks0)/REAL(ms)
1629  END IF
1630  END IF
1631  END IF
1632  ks1 = ks0
1633  DO n=1,ms
1634  DO k=ks1,km
1635  rden = -(rgas*dm(k)/dz(k))
1636  arg1 = gama*log(rden*pt1(k))
1637  pf = exp(arg1)
1638  arg1 = grg*pf/rden
1639  result1 = sqrt(arg1)
1640  dts(k) = -(dz(k)/result1)
1641  ptmp1 = dts(k)*(pf-pm2(i, k))
1642  r_lo(k) = wm(k) + ptmp1
1643  r_hi(k) = wm(k) - ptmp1
1644  END DO
1645  ktop = ks1
1646  DO k=ks1,km
1647  IF (dt .GT. dts(k)) THEN
1648  ktop = k - 1
1649  GOTO 333
1650  END IF
1651  END DO
1652  ktop = km
1653  333 IF (ktop .GE. ks1) THEN
1654  DO k=ks1,ktop
1655  z_frac = dt/dts(k)
1656  r_bot(k) = z_frac*r_lo(k)
1657  r_top(k+1) = z_frac*r_hi(k)
1658  m_bot(k) = z_frac*dm(k)
1659  m_top(k+1) = m_bot(k)
1660  END DO
1661  IF (ktop .EQ. km) GOTO 666
1662  END IF
1663  DO k=ktop+2,km+1
1664  m_top(k) = 0.
1665  r_top(k) = 0.
1666  END DO
1667  IF (1 .LT. ktop) THEN
1668  kt1 = ktop
1669  ELSE
1670  kt1 = 1
1671  END IF
1672  DO ke=km+1,ktop+2,-1
1673  time_left = dt
1674  DO k=ke-1,kt1,-1
1675  IF (time_left .GT. dts(k)) THEN
1676  time_left = time_left - dts(k)
1677  m_top(ke) = m_top(ke) + dm(k)
1678  r_top(ke) = r_top(ke) + r_hi(k)
1679  ELSE
1680  z_frac = time_left/dts(k)
1681  m_top(ke) = m_top(ke) + z_frac*dm(k)
1682  r_top(ke) = r_top(ke) + z_frac*r_hi(k)
1683  GOTO 444
1684  END IF
1685  END DO
1686  444 CONTINUE
1687  END DO
1688 ! next level
1689  DO k=ktop+1,km
1690  m_bot(k) = 0.
1691  r_bot(k) = 0.
1692  END DO
1693  DO ke=ktop+1,km
1694  time_left = dt
1695  DO k=ke,km
1696  IF (time_left .GT. dts(k)) THEN
1697  time_left = time_left - dts(k)
1698  m_bot(ke) = m_bot(ke) + dm(k)
1699  r_bot(ke) = r_bot(ke) + r_lo(k)
1700  ELSE
1701  z_frac = time_left/dts(k)
1702  m_bot(ke) = m_bot(ke) + z_frac*dm(k)
1703  r_bot(ke) = r_bot(ke) + z_frac*r_lo(k)
1704  GOTO 4000
1705  END IF
1706  END DO
1707 ! next interface
1708  m_surf = m_bot(ke)
1709  DO k=km,kt1,-1
1710  IF (time_left .GT. dts(k)) THEN
1711  time_left = time_left - dts(k)
1712  m_bot(ke) = m_bot(ke) + dm(k)
1713  r_bot(ke) = r_bot(ke) - r_hi(k)
1714  ELSE
1715  z_frac = time_left/dts(k)
1716  m_bot(ke) = m_bot(ke) + z_frac*dm(k)
1717  r_bot(ke) = r_bot(ke) - z_frac*r_hi(k) + (m_bot(ke)-m_surf&
1718 & )*ws2(i)
1719  GOTO 4000
1720  END IF
1721  END DO
1722  4000 CONTINUE
1723  END DO
1724 ! next interface
1725  666 IF (ks1 .EQ. 1) wbar(1) = r_bot(1)/m_bot(1)
1726  DO k=ks1+1,km
1727  wbar(k) = (r_bot(k)+r_top(k))/(m_top(k)+m_bot(k))
1728  END DO
1729 ! pbar here is actually dt*pbar
1730  DO k=ks1+1,km+1
1731  pbar(k) = m_top(k)*wbar(k) - r_top(k)
1732  pe1(k) = pe1(k) + pbar(k)
1733  END DO
1734  IF (n .EQ. ms) THEN
1735  IF (c_core) THEN
1736  DO k=ks1,km
1737  dz2(i, k) = dz(k) + dt*(wbar(k+1)-wbar(k))
1738  END DO
1739  ELSE
1740  DO k=ks1,km
1741  dz2(i, k) = dz(k) + dt*(wbar(k+1)-wbar(k))
1742  w2(i, k) = (wm(k)+pbar(k+1)-pbar(k))/dm(k)
1743  END DO
1744  END IF
1745  ELSE
1746  DO k=ks1,km
1747  dz(k) = dz(k) + dt*(wbar(k+1)-wbar(k))
1748  wm(k) = wm(k) + pbar(k+1) - pbar(k)
1749  END DO
1750  END IF
1751  END DO
1752  pe2(i, 1) = 0.
1753  DO k=2,km+1
1754  pe2(i, k) = pe1(k)*rdt
1755  END DO
1756  6000 CONTINUE
1757  END DO
1758  END SUBROUTINE rim_2d
1759 ! Differentiation of sim3_solver in forward (tangent) mode:
1760 ! variations of useful results: pe2 dz2 w2
1761 ! with respect to varying inputs: ws dm pe2 dz2 w2 pem pt2
1762  SUBROUTINE sim3_solver_tlm(dt, is, ie, km, rgas, gama, kappa, pe2, &
1763 & pe2_tl, dm, dm_tl, pem, pem_tl, w2, w2_tl, dz2, dz2_tl, pt2, pt2_tl&
1764 & , ws, ws_tl, alpha, p_fac, scale_m)
1765  IMPLICIT NONE
1766  INTEGER, INTENT(IN) :: is, ie, km
1767  REAL, INTENT(IN) :: dt, rgas, gama, kappa, alpha, p_fac, scale_m
1768  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm, pt2
1769  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm_tl, pt2_tl
1770  REAL, INTENT(IN) :: ws(is:ie)
1771  REAL, INTENT(IN) :: ws_tl(is:ie)
1772  REAL, DIMENSION(is:ie, km+1), INTENT(IN) :: pem
1773  REAL, DIMENSION(is:ie, km+1), INTENT(IN) :: pem_tl
1774  REAL, INTENT(OUT) :: pe2(is:ie, km+1)
1775  REAL, INTENT(OUT) :: pe2_tl(is:ie, km+1)
1776  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2, w2
1777  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2_tl, w2_tl
1778 ! Local
1779  REAL, DIMENSION(is:ie, km) :: aa, bb, dd, w1, wk, g_rat, gam
1780  REAL, DIMENSION(is:ie, km) :: aa_tl, bb_tl, dd_tl, w1_tl, wk_tl, &
1781 & g_rat_tl, gam_tl
1782  REAL, DIMENSION(is:ie, km+1) :: pp
1783  REAL, DIMENSION(is:ie, km+1) :: pp_tl
1784  REAL, DIMENSION(is:ie) :: p1, wk1, bet
1785  REAL, DIMENSION(is:ie) :: p1_tl, wk1_tl, bet_tl
1786  REAL :: beta, t2, t1g, rdt, ra, capa1, r2g, r6g
1787  INTEGER :: i, k
1788  INTRINSIC log
1789  INTRINSIC exp
1790  INTRINSIC max
1791  REAL :: arg1
1792  REAL :: arg1_tl
1793  REAL :: arg2
1794  REAL :: arg2_tl
1795  beta = 1. - alpha
1796  ra = 1./alpha
1797  t2 = beta/alpha
1798  t1g = gama*2.*(alpha*dt)**2
1799  rdt = 1./dt
1800  capa1 = kappa - 1.
1801  r2g = grav/2.
1802  r6g = grav/6.
1803  aa_tl = 0.0
1804  w1_tl = 0.0
1805  DO k=1,km
1806  DO i=is,ie
1807  w1_tl(i, k) = w2_tl(i, k)
1808  w1(i, k) = w2(i, k)
1809 ! Full pressure at center
1810  arg1_tl = -(rgas*((dm_tl(i, k)*dz2(i, k)-dm(i, k)*dz2_tl(i, k))*&
1811 & pt2(i, k)/dz2(i, k)**2+dm(i, k)*pt2_tl(i, k)/dz2(i, k)))
1812  arg1 = -(dm(i, k)/dz2(i, k)*rgas*pt2(i, k))
1813  arg2_tl = gama*arg1_tl/arg1
1814  arg2 = gama*log(arg1)
1815  aa_tl(i, k) = arg2_tl*exp(arg2)
1816  aa(i, k) = exp(arg2)
1817  END DO
1818  END DO
1819  dd_tl = 0.0
1820  bb_tl = 0.0
1821  g_rat_tl = 0.0
1822  DO k=1,km-1
1823  DO i=is,ie
1824 ! for profile reconstruction
1825  g_rat_tl(i, k) = (dm_tl(i, k)*dm(i, k+1)-dm(i, k)*dm_tl(i, k+1))&
1826 & /dm(i, k+1)**2
1827  g_rat(i, k) = dm(i, k)/dm(i, k+1)
1828  bb_tl(i, k) = 2.*g_rat_tl(i, k)
1829  bb(i, k) = 2.*(1.+g_rat(i, k))
1830  dd_tl(i, k) = 3.*(aa_tl(i, k)+g_rat_tl(i, k)*aa(i, k+1)+g_rat(i&
1831 & , k)*aa_tl(i, k+1))
1832  dd(i, k) = 3.*(aa(i, k)+g_rat(i, k)*aa(i, k+1))
1833  END DO
1834  END DO
1835  bet_tl = 0.0
1836 ! pe2 is full p at edges
1837  DO i=is,ie
1838 ! Top:
1839  bet_tl(i) = bb_tl(i, 1)
1840  bet(i) = bb(i, 1)
1841  pe2_tl(i, 1) = pem_tl(i, 1)
1842  pe2(i, 1) = pem(i, 1)
1843  pe2_tl(i, 2) = ((dd_tl(i, 1)-pem_tl(i, 1))*bet(i)-(dd(i, 1)-pem(i&
1844 & , 1))*bet_tl(i))/bet(i)**2
1845  pe2(i, 2) = (dd(i, 1)-pem(i, 1))/bet(i)
1846 ! Bottom:
1847  bb_tl(i, km) = 0.0
1848  bb(i, km) = 2.
1849  dd_tl(i, km) = 3.*aa_tl(i, km) + r2g*dm_tl(i, km)
1850  dd(i, km) = 3.*aa(i, km) + r2g*dm(i, km)
1851  END DO
1852  gam_tl = 0.0
1853  DO k=2,km
1854  DO i=is,ie
1855  gam_tl(i, k) = (g_rat_tl(i, k-1)*bet(i)-g_rat(i, k-1)*bet_tl(i))&
1856 & /bet(i)**2
1857  gam(i, k) = g_rat(i, k-1)/bet(i)
1858  bet_tl(i) = bb_tl(i, k) - gam_tl(i, k)
1859  bet(i) = bb(i, k) - gam(i, k)
1860  pe2_tl(i, k+1) = ((dd_tl(i, k)-pe2_tl(i, k))*bet(i)-(dd(i, k)-&
1861 & pe2(i, k))*bet_tl(i))/bet(i)**2
1862  pe2(i, k+1) = (dd(i, k)-pe2(i, k))/bet(i)
1863  END DO
1864  END DO
1865  DO k=km,2,-1
1866  DO i=is,ie
1867  pe2_tl(i, k) = pe2_tl(i, k) - gam_tl(i, k)*pe2(i, k+1) - gam(i, &
1868 & k)*pe2_tl(i, k+1)
1869  pe2(i, k) = pe2(i, k) - gam(i, k)*pe2(i, k+1)
1870  END DO
1871  END DO
1872  pp_tl = 0.0
1873 ! done reconstruction of full:
1874 ! pp is pert. p at edges
1875  DO k=1,km+1
1876  DO i=is,ie
1877  pp_tl(i, k) = pe2_tl(i, k) - pem_tl(i, k)
1878  pp(i, k) = pe2(i, k) - pem(i, k)
1879  END DO
1880  END DO
1881  wk_tl = 0.0
1882  DO k=2,km
1883  DO i=is,ie
1884  aa_tl(i, k) = t1g*pe2_tl(i, k)/(dz2(i, k-1)+dz2(i, k)) - t1g*(&
1885 & dz2_tl(i, k-1)+dz2_tl(i, k))*pe2(i, k)/(dz2(i, k-1)+dz2(i, k))&
1886 & **2
1887  aa(i, k) = t1g/(dz2(i, k-1)+dz2(i, k))*pe2(i, k)
1888  wk_tl(i, k) = t2*(aa_tl(i, k)*(w1(i, k-1)-w1(i, k))+aa(i, k)*(&
1889 & w1_tl(i, k-1)-w1_tl(i, k)))
1890  wk(i, k) = t2*aa(i, k)*(w1(i, k-1)-w1(i, k))
1891  aa_tl(i, k) = aa_tl(i, k) - scale_m*dm_tl(i, 1)
1892  aa(i, k) = aa(i, k) - scale_m*dm(i, 1)
1893  END DO
1894  END DO
1895  DO i=is,ie
1896  bet_tl(i) = dm_tl(i, 1) - aa_tl(i, 2)
1897  bet(i) = dm(i, 1) - aa(i, 2)
1898  w2_tl(i, 1) = ((dm_tl(i, 1)*w1(i, 1)+dm(i, 1)*w1_tl(i, 1)+dt*pp_tl&
1899 & (i, 2)+wk_tl(i, 2))*bet(i)-(dm(i, 1)*w1(i, 1)+dt*pp(i, 2)+wk(i, &
1900 & 2))*bet_tl(i))/bet(i)**2
1901  w2(i, 1) = (dm(i, 1)*w1(i, 1)+dt*pp(i, 2)+wk(i, 2))/bet(i)
1902  END DO
1903  DO k=2,km-1
1904  DO i=is,ie
1905  gam_tl(i, k) = (aa_tl(i, k)*bet(i)-aa(i, k)*bet_tl(i))/bet(i)**2
1906  gam(i, k) = aa(i, k)/bet(i)
1907  bet_tl(i) = dm_tl(i, k) - aa_tl(i, k) - aa_tl(i, k+1) - aa_tl(i&
1908 & , k)*gam(i, k) - aa(i, k)*gam_tl(i, k)
1909  bet(i) = dm(i, k) - (aa(i, k)+aa(i, k+1)+aa(i, k)*gam(i, k))
1910  w2_tl(i, k) = ((dm_tl(i, k)*w1(i, k)+dm(i, k)*w1_tl(i, k)+dt*(&
1911 & pp_tl(i, k+1)-pp_tl(i, k))+wk_tl(i, k+1)-wk_tl(i, k)-aa_tl(i, &
1912 & k)*w2(i, k-1)-aa(i, k)*w2_tl(i, k-1))*bet(i)-(dm(i, k)*w1(i, k&
1913 & )+dt*(pp(i, k+1)-pp(i, k))+wk(i, k+1)-wk(i, k)-aa(i, k)*w2(i, &
1914 & k-1))*bet_tl(i))/bet(i)**2
1915  w2(i, k) = (dm(i, k)*w1(i, k)+dt*(pp(i, k+1)-pp(i, k))+wk(i, k+1&
1916 & )-wk(i, k)-aa(i, k)*w2(i, k-1))/bet(i)
1917  END DO
1918  END DO
1919  wk1_tl = 0.0
1920  DO i=is,ie
1921  wk1_tl(i) = t1g*pe2_tl(i, km+1)/dz2(i, km) - t1g*dz2_tl(i, km)*pe2&
1922 & (i, km+1)/dz2(i, km)**2
1923  wk1(i) = t1g/dz2(i, km)*pe2(i, km+1)
1924  gam_tl(i, km) = (aa_tl(i, km)*bet(i)-aa(i, km)*bet_tl(i))/bet(i)**&
1925 & 2
1926  gam(i, km) = aa(i, km)/bet(i)
1927  bet_tl(i) = dm_tl(i, km) - aa_tl(i, km) - wk1_tl(i) - aa_tl(i, km)&
1928 & *gam(i, km) - aa(i, km)*gam_tl(i, km)
1929  bet(i) = dm(i, km) - (aa(i, km)+wk1(i)+aa(i, km)*gam(i, km))
1930  w2_tl(i, km) = ((dm_tl(i, km)*w1(i, km)+dm(i, km)*w1_tl(i, km)+dt*&
1931 & (pp_tl(i, km+1)-pp_tl(i, km))-wk_tl(i, km)+wk1_tl(i)*(t2*w1(i, &
1932 & km)-ra*ws(i))+wk1(i)*(t2*w1_tl(i, km)-ra*ws_tl(i))-aa_tl(i, km)*&
1933 & w2(i, km-1)-aa(i, km)*w2_tl(i, km-1))*bet(i)-(dm(i, km)*w1(i, km&
1934 & )+dt*(pp(i, km+1)-pp(i, km))-wk(i, km)+wk1(i)*(t2*w1(i, km)-ra*&
1935 & ws(i))-aa(i, km)*w2(i, km-1))*bet_tl(i))/bet(i)**2
1936  w2(i, km) = (dm(i, km)*w1(i, km)+dt*(pp(i, km+1)-pp(i, km))-wk(i, &
1937 & km)+wk1(i)*(t2*w1(i, km)-ra*ws(i))-aa(i, km)*w2(i, km-1))/bet(i)
1938  END DO
1939  DO k=km-1,1,-1
1940  DO i=is,ie
1941  w2_tl(i, k) = w2_tl(i, k) - gam_tl(i, k+1)*w2(i, k+1) - gam(i, k&
1942 & +1)*w2_tl(i, k+1)
1943  w2(i, k) = w2(i, k) - gam(i, k+1)*w2(i, k+1)
1944  END DO
1945  END DO
1946 ! pe2 is updated perturbation p at edges
1947  DO i=is,ie
1948  pe2_tl(i, 1) = 0.0
1949  pe2(i, 1) = 0.
1950  END DO
1951  DO k=1,km
1952  DO i=is,ie
1953  pe2_tl(i, k+1) = pe2_tl(i, k) + ra*(rdt*(dm_tl(i, k)*(w2(i, k)-&
1954 & w1(i, k))+dm(i, k)*(w2_tl(i, k)-w1_tl(i, k)))-beta*(pp_tl(i, k&
1955 & +1)-pp_tl(i, k)))
1956  pe2(i, k+1) = pe2(i, k) + (dm(i, k)*(w2(i, k)-w1(i, k))*rdt-beta&
1957 & *(pp(i, k+1)-pp(i, k)))*ra
1958  END DO
1959  END DO
1960 ! Full non-hydro pressure at edges:
1961  DO i=is,ie
1962  pe2_tl(i, 1) = pem_tl(i, 1)
1963  pe2(i, 1) = pem(i, 1)
1964  END DO
1965  DO k=2,km+1
1966  DO i=is,ie
1967  IF (p_fac*pem(i, k) .LT. pe2(i, k) + pem(i, k)) THEN
1968  pe2_tl(i, k) = pe2_tl(i, k) + pem_tl(i, k)
1969  pe2(i, k) = pe2(i, k) + pem(i, k)
1970  ELSE
1971  pe2_tl(i, k) = p_fac*pem_tl(i, k)
1972  pe2(i, k) = p_fac*pem(i, k)
1973  END IF
1974  END DO
1975  END DO
1976  p1_tl = 0.0
1977  DO i=is,ie
1978 ! Recover cell-averaged pressure
1979  p1_tl(i) = r3*(pe2_tl(i, km)+2.*pe2_tl(i, km+1)) - r6g*dm_tl(i, km&
1980 & )
1981  p1(i) = (pe2(i, km)+2.*pe2(i, km+1))*r3 - r6g*dm(i, km)
1982  arg1_tl = capa1*p1_tl(i)/p1(i)
1983  arg1 = capa1*log(p1(i))
1984  dz2_tl(i, km) = -(rgas*((dm_tl(i, km)*pt2(i, km)+dm(i, km)*pt2_tl(&
1985 & i, km))*exp(arg1)+dm(i, km)*pt2(i, km)*arg1_tl*exp(arg1)))
1986  dz2(i, km) = -(dm(i, km)*rgas*pt2(i, km)*exp(arg1))
1987  END DO
1988  DO k=km-1,1,-1
1989  DO i=is,ie
1990  p1_tl(i) = r3*(pe2_tl(i, k)+bb_tl(i, k)*pe2(i, k+1)+bb(i, k)*&
1991 & pe2_tl(i, k+1)+g_rat_tl(i, k)*pe2(i, k+2)+g_rat(i, k)*pe2_tl(i&
1992 & , k+2)) - g_rat_tl(i, k)*p1(i) - g_rat(i, k)*p1_tl(i)
1993  p1(i) = (pe2(i, k)+bb(i, k)*pe2(i, k+1)+g_rat(i, k)*pe2(i, k+2))&
1994 & *r3 - g_rat(i, k)*p1(i)
1995  arg1_tl = capa1*p1_tl(i)/p1(i)
1996  arg1 = capa1*log(p1(i))
1997  dz2_tl(i, k) = -(rgas*((dm_tl(i, k)*pt2(i, k)+dm(i, k)*pt2_tl(i&
1998 & , k))*exp(arg1)+dm(i, k)*pt2(i, k)*arg1_tl*exp(arg1)))
1999  dz2(i, k) = -(dm(i, k)*rgas*pt2(i, k)*exp(arg1))
2000  END DO
2001  END DO
2002  DO k=1,km+1
2003  DO i=is,ie
2004  pe2_tl(i, k) = pe2_tl(i, k) - pem_tl(i, k)
2005  pe2(i, k) = pe2(i, k) - pem(i, k)
2006  pe2_tl(i, k) = pe2_tl(i, k) + beta*(pp_tl(i, k)-pe2_tl(i, k))
2007  pe2(i, k) = pe2(i, k) + beta*(pp(i, k)-pe2(i, k))
2008  END DO
2009  END DO
2010  END SUBROUTINE sim3_solver_tlm
2011  SUBROUTINE sim3_solver(dt, is, ie, km, rgas, gama, kappa, pe2, dm, pem&
2012 & , w2, dz2, pt2, ws, alpha, p_fac, scale_m)
2013  IMPLICIT NONE
2014  INTEGER, INTENT(IN) :: is, ie, km
2015  REAL, INTENT(IN) :: dt, rgas, gama, kappa, alpha, p_fac, scale_m
2016  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm, pt2
2017  REAL, INTENT(IN) :: ws(is:ie)
2018  REAL, DIMENSION(is:ie, km+1), INTENT(IN) :: pem
2019  REAL, INTENT(OUT) :: pe2(is:ie, km+1)
2020  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2, w2
2021 ! Local
2022  REAL, DIMENSION(is:ie, km) :: aa, bb, dd, w1, wk, g_rat, gam
2023  REAL, DIMENSION(is:ie, km+1) :: pp
2024  REAL, DIMENSION(is:ie) :: p1, wk1, bet
2025  REAL :: beta, t2, t1g, rdt, ra, capa1, r2g, r6g
2026  INTEGER :: i, k
2027  INTRINSIC log
2028  INTRINSIC exp
2029  INTRINSIC max
2030  REAL :: arg1
2031  REAL :: arg2
2032  beta = 1. - alpha
2033  ra = 1./alpha
2034  t2 = beta/alpha
2035  t1g = gama*2.*(alpha*dt)**2
2036  rdt = 1./dt
2037  capa1 = kappa - 1.
2038  r2g = grav/2.
2039  r6g = grav/6.
2040  DO k=1,km
2041  DO i=is,ie
2042  w1(i, k) = w2(i, k)
2043 ! Full pressure at center
2044  arg1 = -(dm(i, k)/dz2(i, k)*rgas*pt2(i, k))
2045  arg2 = gama*log(arg1)
2046  aa(i, k) = exp(arg2)
2047  END DO
2048  END DO
2049  DO k=1,km-1
2050  DO i=is,ie
2051 ! for profile reconstruction
2052  g_rat(i, k) = dm(i, k)/dm(i, k+1)
2053  bb(i, k) = 2.*(1.+g_rat(i, k))
2054  dd(i, k) = 3.*(aa(i, k)+g_rat(i, k)*aa(i, k+1))
2055  END DO
2056  END DO
2057 ! pe2 is full p at edges
2058  DO i=is,ie
2059 ! Top:
2060  bet(i) = bb(i, 1)
2061  pe2(i, 1) = pem(i, 1)
2062  pe2(i, 2) = (dd(i, 1)-pem(i, 1))/bet(i)
2063 ! Bottom:
2064  bb(i, km) = 2.
2065  dd(i, km) = 3.*aa(i, km) + r2g*dm(i, km)
2066  END DO
2067  DO k=2,km
2068  DO i=is,ie
2069  gam(i, k) = g_rat(i, k-1)/bet(i)
2070  bet(i) = bb(i, k) - gam(i, k)
2071  pe2(i, k+1) = (dd(i, k)-pe2(i, k))/bet(i)
2072  END DO
2073  END DO
2074  DO k=km,2,-1
2075  DO i=is,ie
2076  pe2(i, k) = pe2(i, k) - gam(i, k)*pe2(i, k+1)
2077  END DO
2078  END DO
2079 ! done reconstruction of full:
2080 ! pp is pert. p at edges
2081  DO k=1,km+1
2082  DO i=is,ie
2083  pp(i, k) = pe2(i, k) - pem(i, k)
2084  END DO
2085  END DO
2086  DO k=2,km
2087  DO i=is,ie
2088  aa(i, k) = t1g/(dz2(i, k-1)+dz2(i, k))*pe2(i, k)
2089  wk(i, k) = t2*aa(i, k)*(w1(i, k-1)-w1(i, k))
2090  aa(i, k) = aa(i, k) - scale_m*dm(i, 1)
2091  END DO
2092  END DO
2093  DO i=is,ie
2094  bet(i) = dm(i, 1) - aa(i, 2)
2095  w2(i, 1) = (dm(i, 1)*w1(i, 1)+dt*pp(i, 2)+wk(i, 2))/bet(i)
2096  END DO
2097  DO k=2,km-1
2098  DO i=is,ie
2099  gam(i, k) = aa(i, k)/bet(i)
2100  bet(i) = dm(i, k) - (aa(i, k)+aa(i, k+1)+aa(i, k)*gam(i, k))
2101  w2(i, k) = (dm(i, k)*w1(i, k)+dt*(pp(i, k+1)-pp(i, k))+wk(i, k+1&
2102 & )-wk(i, k)-aa(i, k)*w2(i, k-1))/bet(i)
2103  END DO
2104  END DO
2105  DO i=is,ie
2106  wk1(i) = t1g/dz2(i, km)*pe2(i, km+1)
2107  gam(i, km) = aa(i, km)/bet(i)
2108  bet(i) = dm(i, km) - (aa(i, km)+wk1(i)+aa(i, km)*gam(i, km))
2109  w2(i, km) = (dm(i, km)*w1(i, km)+dt*(pp(i, km+1)-pp(i, km))-wk(i, &
2110 & km)+wk1(i)*(t2*w1(i, km)-ra*ws(i))-aa(i, km)*w2(i, km-1))/bet(i)
2111  END DO
2112  DO k=km-1,1,-1
2113  DO i=is,ie
2114  w2(i, k) = w2(i, k) - gam(i, k+1)*w2(i, k+1)
2115  END DO
2116  END DO
2117 ! pe2 is updated perturbation p at edges
2118  DO i=is,ie
2119  pe2(i, 1) = 0.
2120  END DO
2121  DO k=1,km
2122  DO i=is,ie
2123  pe2(i, k+1) = pe2(i, k) + (dm(i, k)*(w2(i, k)-w1(i, k))*rdt-beta&
2124 & *(pp(i, k+1)-pp(i, k)))*ra
2125  END DO
2126  END DO
2127 ! Full non-hydro pressure at edges:
2128  DO i=is,ie
2129  pe2(i, 1) = pem(i, 1)
2130  END DO
2131  DO k=2,km+1
2132  DO i=is,ie
2133  IF (p_fac*pem(i, k) .LT. pe2(i, k) + pem(i, k)) THEN
2134  pe2(i, k) = pe2(i, k) + pem(i, k)
2135  ELSE
2136  pe2(i, k) = p_fac*pem(i, k)
2137  END IF
2138  END DO
2139  END DO
2140  DO i=is,ie
2141 ! Recover cell-averaged pressure
2142  p1(i) = (pe2(i, km)+2.*pe2(i, km+1))*r3 - r6g*dm(i, km)
2143  arg1 = capa1*log(p1(i))
2144  dz2(i, km) = -(dm(i, km)*rgas*pt2(i, km)*exp(arg1))
2145  END DO
2146  DO k=km-1,1,-1
2147  DO i=is,ie
2148  p1(i) = (pe2(i, k)+bb(i, k)*pe2(i, k+1)+g_rat(i, k)*pe2(i, k+2))&
2149 & *r3 - g_rat(i, k)*p1(i)
2150  arg1 = capa1*log(p1(i))
2151  dz2(i, k) = -(dm(i, k)*rgas*pt2(i, k)*exp(arg1))
2152  END DO
2153  END DO
2154  DO k=1,km+1
2155  DO i=is,ie
2156  pe2(i, k) = pe2(i, k) - pem(i, k)
2157  pe2(i, k) = pe2(i, k) + beta*(pp(i, k)-pe2(i, k))
2158  END DO
2159  END DO
2160  END SUBROUTINE sim3_solver
2161 ! Differentiation of sim3p0_solver in forward (tangent) mode:
2162 ! variations of useful results: pe2 dz2 w2
2163 ! with respect to varying inputs: ws dm pe2 dz2 w2 pem pt2
2164  SUBROUTINE sim3p0_solver_tlm(dt, is, ie, km, rgas, gama, kappa, pe2, &
2165 & pe2_tl, dm, dm_tl, pem, pem_tl, w2, w2_tl, dz2, dz2_tl, pt2, pt2_tl&
2166 & , ws, ws_tl, p_fac, scale_m)
2167  IMPLICIT NONE
2168 ! Sa SIM3, but for beta==0
2169  INTEGER, INTENT(IN) :: is, ie, km
2170  REAL, INTENT(IN) :: dt, rgas, gama, kappa, p_fac, scale_m
2171  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm, pt2
2172  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm_tl, pt2_tl
2173  REAL, INTENT(IN) :: ws(is:ie)
2174  REAL, INTENT(IN) :: ws_tl(is:ie)
2175  REAL, INTENT(IN) :: pem(is:ie, km+1)
2176  REAL, INTENT(IN) :: pem_tl(is:ie, km+1)
2177  REAL, INTENT(OUT) :: pe2(is:ie, km+1)
2178  REAL, INTENT(OUT) :: pe2_tl(is:ie, km+1)
2179  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2, w2
2180  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2_tl, w2_tl
2181 ! Local
2182  REAL, DIMENSION(is:ie, km) :: aa, bb, dd, w1, g_rat, gam
2183  REAL, DIMENSION(is:ie, km) :: aa_tl, bb_tl, dd_tl, w1_tl, g_rat_tl, &
2184 & gam_tl
2185  REAL, DIMENSION(is:ie, km+1) :: pp
2186  REAL, DIMENSION(is:ie, km+1) :: pp_tl
2187  REAL, DIMENSION(is:ie) :: p1, wk1, bet
2188  REAL, DIMENSION(is:ie) :: p1_tl, wk1_tl, bet_tl
2189  REAL :: t1g, rdt, capa1, r2g, r6g
2190  INTEGER :: i, k
2191  INTRINSIC log
2192  INTRINSIC exp
2193  INTRINSIC max
2194  REAL :: arg1
2195  REAL :: arg1_tl
2196  REAL :: arg2
2197  REAL :: arg2_tl
2198  t1g = 2.*gama*dt**2
2199  rdt = 1./dt
2200  capa1 = kappa - 1.
2201  r2g = grav/2.
2202  r6g = grav/6.
2203  aa_tl = 0.0
2204  w1_tl = 0.0
2205  DO k=1,km
2206  DO i=is,ie
2207  w1_tl(i, k) = w2_tl(i, k)
2208  w1(i, k) = w2(i, k)
2209 ! Full pressure at center
2210  arg1_tl = -(rgas*((dm_tl(i, k)*dz2(i, k)-dm(i, k)*dz2_tl(i, k))*&
2211 & pt2(i, k)/dz2(i, k)**2+dm(i, k)*pt2_tl(i, k)/dz2(i, k)))
2212  arg1 = -(dm(i, k)/dz2(i, k)*rgas*pt2(i, k))
2213  arg2_tl = gama*arg1_tl/arg1
2214  arg2 = gama*log(arg1)
2215  aa_tl(i, k) = arg2_tl*exp(arg2)
2216  aa(i, k) = exp(arg2)
2217  END DO
2218  END DO
2219  dd_tl = 0.0
2220  bb_tl = 0.0
2221  g_rat_tl = 0.0
2222  DO k=1,km-1
2223  DO i=is,ie
2224 ! for profile reconstruction
2225  g_rat_tl(i, k) = (dm_tl(i, k)*dm(i, k+1)-dm(i, k)*dm_tl(i, k+1))&
2226 & /dm(i, k+1)**2
2227  g_rat(i, k) = dm(i, k)/dm(i, k+1)
2228  bb_tl(i, k) = 2.*g_rat_tl(i, k)
2229  bb(i, k) = 2.*(1.+g_rat(i, k))
2230  dd_tl(i, k) = 3.*(aa_tl(i, k)+g_rat_tl(i, k)*aa(i, k+1)+g_rat(i&
2231 & , k)*aa_tl(i, k+1))
2232  dd(i, k) = 3.*(aa(i, k)+g_rat(i, k)*aa(i, k+1))
2233  END DO
2234  END DO
2235  bet_tl = 0.0
2236 ! pe2 is full p at edges
2237  DO i=is,ie
2238 ! Top:
2239  bet_tl(i) = bb_tl(i, 1)
2240  bet(i) = bb(i, 1)
2241  pe2_tl(i, 1) = pem_tl(i, 1)
2242  pe2(i, 1) = pem(i, 1)
2243  pe2_tl(i, 2) = ((dd_tl(i, 1)-pem_tl(i, 1))*bet(i)-(dd(i, 1)-pem(i&
2244 & , 1))*bet_tl(i))/bet(i)**2
2245  pe2(i, 2) = (dd(i, 1)-pem(i, 1))/bet(i)
2246 ! Bottom:
2247  bb_tl(i, km) = 0.0
2248  bb(i, km) = 2.
2249  dd_tl(i, km) = 3.*aa_tl(i, km) + r2g*dm_tl(i, km)
2250  dd(i, km) = 3.*aa(i, km) + r2g*dm(i, km)
2251  END DO
2252  gam_tl = 0.0
2253  DO k=2,km
2254  DO i=is,ie
2255  gam_tl(i, k) = (g_rat_tl(i, k-1)*bet(i)-g_rat(i, k-1)*bet_tl(i))&
2256 & /bet(i)**2
2257  gam(i, k) = g_rat(i, k-1)/bet(i)
2258  bet_tl(i) = bb_tl(i, k) - gam_tl(i, k)
2259  bet(i) = bb(i, k) - gam(i, k)
2260  pe2_tl(i, k+1) = ((dd_tl(i, k)-pe2_tl(i, k))*bet(i)-(dd(i, k)-&
2261 & pe2(i, k))*bet_tl(i))/bet(i)**2
2262  pe2(i, k+1) = (dd(i, k)-pe2(i, k))/bet(i)
2263  END DO
2264  END DO
2265  DO k=km,2,-1
2266  DO i=is,ie
2267  pe2_tl(i, k) = pe2_tl(i, k) - gam_tl(i, k)*pe2(i, k+1) - gam(i, &
2268 & k)*pe2_tl(i, k+1)
2269  pe2(i, k) = pe2(i, k) - gam(i, k)*pe2(i, k+1)
2270  END DO
2271  END DO
2272  pp_tl = 0.0
2273 ! done reconstruction of full:
2274 ! pp is pert. p at edges
2275  DO k=1,km+1
2276  DO i=is,ie
2277  pp_tl(i, k) = pe2_tl(i, k) - pem_tl(i, k)
2278  pp(i, k) = pe2(i, k) - pem(i, k)
2279  END DO
2280  END DO
2281  DO k=2,km
2282  DO i=is,ie
2283  aa_tl(i, k) = t1g*pe2_tl(i, k)/(dz2(i, k-1)+dz2(i, k)) - t1g*(&
2284 & dz2_tl(i, k-1)+dz2_tl(i, k))*pe2(i, k)/(dz2(i, k-1)+dz2(i, k))&
2285 & **2 - scale_m*dm_tl(i, 1)
2286  aa(i, k) = t1g/(dz2(i, k-1)+dz2(i, k))*pe2(i, k) - scale_m*dm(i&
2287 & , 1)
2288  END DO
2289  END DO
2290  DO i=is,ie
2291  bet_tl(i) = dm_tl(i, 1) - aa_tl(i, 2)
2292  bet(i) = dm(i, 1) - aa(i, 2)
2293  w2_tl(i, 1) = ((dm_tl(i, 1)*w1(i, 1)+dm(i, 1)*w1_tl(i, 1)+dt*pp_tl&
2294 & (i, 2))*bet(i)-(dm(i, 1)*w1(i, 1)+dt*pp(i, 2))*bet_tl(i))/bet(i)&
2295 & **2
2296  w2(i, 1) = (dm(i, 1)*w1(i, 1)+dt*pp(i, 2))/bet(i)
2297  END DO
2298  DO k=2,km-1
2299  DO i=is,ie
2300  gam_tl(i, k) = (aa_tl(i, k)*bet(i)-aa(i, k)*bet_tl(i))/bet(i)**2
2301  gam(i, k) = aa(i, k)/bet(i)
2302  bet_tl(i) = dm_tl(i, k) - aa_tl(i, k) - aa_tl(i, k+1) - aa_tl(i&
2303 & , k)*gam(i, k) - aa(i, k)*gam_tl(i, k)
2304  bet(i) = dm(i, k) - (aa(i, k)+aa(i, k+1)+aa(i, k)*gam(i, k))
2305  w2_tl(i, k) = ((dm_tl(i, k)*w1(i, k)+dm(i, k)*w1_tl(i, k)+dt*(&
2306 & pp_tl(i, k+1)-pp_tl(i, k))-aa_tl(i, k)*w2(i, k-1)-aa(i, k)*&
2307 & w2_tl(i, k-1))*bet(i)-(dm(i, k)*w1(i, k)+dt*(pp(i, k+1)-pp(i, &
2308 & k))-aa(i, k)*w2(i, k-1))*bet_tl(i))/bet(i)**2
2309  w2(i, k) = (dm(i, k)*w1(i, k)+dt*(pp(i, k+1)-pp(i, k))-aa(i, k)*&
2310 & w2(i, k-1))/bet(i)
2311  END DO
2312  END DO
2313  wk1_tl = 0.0
2314  DO i=is,ie
2315  wk1_tl(i) = t1g*pe2_tl(i, km+1)/dz2(i, km) - t1g*dz2_tl(i, km)*pe2&
2316 & (i, km+1)/dz2(i, km)**2
2317  wk1(i) = t1g/dz2(i, km)*pe2(i, km+1)
2318  gam_tl(i, km) = (aa_tl(i, km)*bet(i)-aa(i, km)*bet_tl(i))/bet(i)**&
2319 & 2
2320  gam(i, km) = aa(i, km)/bet(i)
2321  bet_tl(i) = dm_tl(i, km) - aa_tl(i, km) - wk1_tl(i) - aa_tl(i, km)&
2322 & *gam(i, km) - aa(i, km)*gam_tl(i, km)
2323  bet(i) = dm(i, km) - (aa(i, km)+wk1(i)+aa(i, km)*gam(i, km))
2324  w2_tl(i, km) = ((dm_tl(i, km)*w1(i, km)+dm(i, km)*w1_tl(i, km)+dt*&
2325 & (pp_tl(i, km+1)-pp_tl(i, km))-wk1_tl(i)*ws(i)-wk1(i)*ws_tl(i)-&
2326 & aa_tl(i, km)*w2(i, km-1)-aa(i, km)*w2_tl(i, km-1))*bet(i)-(dm(i&
2327 & , km)*w1(i, km)+dt*(pp(i, km+1)-pp(i, km))-wk1(i)*ws(i)-aa(i, km&
2328 & )*w2(i, km-1))*bet_tl(i))/bet(i)**2
2329  w2(i, km) = (dm(i, km)*w1(i, km)+dt*(pp(i, km+1)-pp(i, km))-wk1(i)&
2330 & *ws(i)-aa(i, km)*w2(i, km-1))/bet(i)
2331  END DO
2332  DO k=km-1,1,-1
2333  DO i=is,ie
2334  w2_tl(i, k) = w2_tl(i, k) - gam_tl(i, k+1)*w2(i, k+1) - gam(i, k&
2335 & +1)*w2_tl(i, k+1)
2336  w2(i, k) = w2(i, k) - gam(i, k+1)*w2(i, k+1)
2337  END DO
2338  END DO
2339 ! pe2 is updated perturbation p at edges
2340  DO i=is,ie
2341  pe2_tl(i, 1) = 0.0
2342  pe2(i, 1) = 0.
2343  END DO
2344  DO k=1,km
2345  DO i=is,ie
2346  pe2_tl(i, k+1) = pe2_tl(i, k) + rdt*(dm_tl(i, k)*(w2(i, k)-w1(i&
2347 & , k))+dm(i, k)*(w2_tl(i, k)-w1_tl(i, k)))
2348  pe2(i, k+1) = pe2(i, k) + dm(i, k)*(w2(i, k)-w1(i, k))*rdt
2349  END DO
2350  END DO
2351 ! Full non-hydro pressure at edges:
2352  DO i=is,ie
2353  pe2_tl(i, 1) = pem_tl(i, 1)
2354  pe2(i, 1) = pem(i, 1)
2355  END DO
2356  DO k=2,km+1
2357  DO i=is,ie
2358  IF (p_fac*pem(i, k) .LT. pe2(i, k) + pem(i, k)) THEN
2359  pe2_tl(i, k) = pe2_tl(i, k) + pem_tl(i, k)
2360  pe2(i, k) = pe2(i, k) + pem(i, k)
2361  ELSE
2362  pe2_tl(i, k) = p_fac*pem_tl(i, k)
2363  pe2(i, k) = p_fac*pem(i, k)
2364  END IF
2365  END DO
2366  END DO
2367  p1_tl = 0.0
2368  DO i=is,ie
2369 ! Recover cell-averaged pressure
2370  p1_tl(i) = r3*(pe2_tl(i, km)+2.*pe2_tl(i, km+1)) - r6g*dm_tl(i, km&
2371 & )
2372  p1(i) = (pe2(i, km)+2.*pe2(i, km+1))*r3 - r6g*dm(i, km)
2373  arg1_tl = capa1*p1_tl(i)/p1(i)
2374  arg1 = capa1*log(p1(i))
2375  dz2_tl(i, km) = -(rgas*((dm_tl(i, km)*pt2(i, km)+dm(i, km)*pt2_tl(&
2376 & i, km))*exp(arg1)+dm(i, km)*pt2(i, km)*arg1_tl*exp(arg1)))
2377  dz2(i, km) = -(dm(i, km)*rgas*pt2(i, km)*exp(arg1))
2378  END DO
2379  DO k=km-1,1,-1
2380  DO i=is,ie
2381  p1_tl(i) = r3*(pe2_tl(i, k)+bb_tl(i, k)*pe2(i, k+1)+bb(i, k)*&
2382 & pe2_tl(i, k+1)+g_rat_tl(i, k)*pe2(i, k+2)+g_rat(i, k)*pe2_tl(i&
2383 & , k+2)) - g_rat_tl(i, k)*p1(i) - g_rat(i, k)*p1_tl(i)
2384  p1(i) = (pe2(i, k)+bb(i, k)*pe2(i, k+1)+g_rat(i, k)*pe2(i, k+2))&
2385 & *r3 - g_rat(i, k)*p1(i)
2386  arg1_tl = capa1*p1_tl(i)/p1(i)
2387  arg1 = capa1*log(p1(i))
2388  dz2_tl(i, k) = -(rgas*((dm_tl(i, k)*pt2(i, k)+dm(i, k)*pt2_tl(i&
2389 & , k))*exp(arg1)+dm(i, k)*pt2(i, k)*arg1_tl*exp(arg1)))
2390  dz2(i, k) = -(dm(i, k)*rgas*pt2(i, k)*exp(arg1))
2391  END DO
2392  END DO
2393  DO k=1,km+1
2394  DO i=is,ie
2395  pe2_tl(i, k) = pe2_tl(i, k) - pem_tl(i, k)
2396  pe2(i, k) = pe2(i, k) - pem(i, k)
2397  END DO
2398  END DO
2399  END SUBROUTINE sim3p0_solver_tlm
2400  SUBROUTINE sim3p0_solver(dt, is, ie, km, rgas, gama, kappa, pe2, dm, &
2401 & pem, w2, dz2, pt2, ws, p_fac, scale_m)
2402  IMPLICIT NONE
2403 ! Sa SIM3, but for beta==0
2404  INTEGER, INTENT(IN) :: is, ie, km
2405  REAL, INTENT(IN) :: dt, rgas, gama, kappa, p_fac, scale_m
2406  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm, pt2
2407  REAL, INTENT(IN) :: ws(is:ie)
2408  REAL, INTENT(IN) :: pem(is:ie, km+1)
2409  REAL, INTENT(OUT) :: pe2(is:ie, km+1)
2410  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2, w2
2411 ! Local
2412  REAL, DIMENSION(is:ie, km) :: aa, bb, dd, w1, g_rat, gam
2413  REAL, DIMENSION(is:ie, km+1) :: pp
2414  REAL, DIMENSION(is:ie) :: p1, wk1, bet
2415  REAL :: t1g, rdt, capa1, r2g, r6g
2416  INTEGER :: i, k
2417  INTRINSIC log
2418  INTRINSIC exp
2419  INTRINSIC max
2420  REAL :: arg1
2421  REAL :: arg2
2422  t1g = 2.*gama*dt**2
2423  rdt = 1./dt
2424  capa1 = kappa - 1.
2425  r2g = grav/2.
2426  r6g = grav/6.
2427  DO k=1,km
2428  DO i=is,ie
2429  w1(i, k) = w2(i, k)
2430 ! Full pressure at center
2431  arg1 = -(dm(i, k)/dz2(i, k)*rgas*pt2(i, k))
2432  arg2 = gama*log(arg1)
2433  aa(i, k) = exp(arg2)
2434  END DO
2435  END DO
2436  DO k=1,km-1
2437  DO i=is,ie
2438 ! for profile reconstruction
2439  g_rat(i, k) = dm(i, k)/dm(i, k+1)
2440  bb(i, k) = 2.*(1.+g_rat(i, k))
2441  dd(i, k) = 3.*(aa(i, k)+g_rat(i, k)*aa(i, k+1))
2442  END DO
2443  END DO
2444 ! pe2 is full p at edges
2445  DO i=is,ie
2446 ! Top:
2447  bet(i) = bb(i, 1)
2448  pe2(i, 1) = pem(i, 1)
2449  pe2(i, 2) = (dd(i, 1)-pem(i, 1))/bet(i)
2450 ! Bottom:
2451  bb(i, km) = 2.
2452  dd(i, km) = 3.*aa(i, km) + r2g*dm(i, km)
2453  END DO
2454  DO k=2,km
2455  DO i=is,ie
2456  gam(i, k) = g_rat(i, k-1)/bet(i)
2457  bet(i) = bb(i, k) - gam(i, k)
2458  pe2(i, k+1) = (dd(i, k)-pe2(i, k))/bet(i)
2459  END DO
2460  END DO
2461  DO k=km,2,-1
2462  DO i=is,ie
2463  pe2(i, k) = pe2(i, k) - gam(i, k)*pe2(i, k+1)
2464  END DO
2465  END DO
2466 ! done reconstruction of full:
2467 ! pp is pert. p at edges
2468  DO k=1,km+1
2469  DO i=is,ie
2470  pp(i, k) = pe2(i, k) - pem(i, k)
2471  END DO
2472  END DO
2473  DO k=2,km
2474  DO i=is,ie
2475  aa(i, k) = t1g/(dz2(i, k-1)+dz2(i, k))*pe2(i, k) - scale_m*dm(i&
2476 & , 1)
2477  END DO
2478  END DO
2479  DO i=is,ie
2480  bet(i) = dm(i, 1) - aa(i, 2)
2481  w2(i, 1) = (dm(i, 1)*w1(i, 1)+dt*pp(i, 2))/bet(i)
2482  END DO
2483  DO k=2,km-1
2484  DO i=is,ie
2485  gam(i, k) = aa(i, k)/bet(i)
2486  bet(i) = dm(i, k) - (aa(i, k)+aa(i, k+1)+aa(i, k)*gam(i, k))
2487  w2(i, k) = (dm(i, k)*w1(i, k)+dt*(pp(i, k+1)-pp(i, k))-aa(i, k)*&
2488 & w2(i, k-1))/bet(i)
2489  END DO
2490  END DO
2491  DO i=is,ie
2492  wk1(i) = t1g/dz2(i, km)*pe2(i, km+1)
2493  gam(i, km) = aa(i, km)/bet(i)
2494  bet(i) = dm(i, km) - (aa(i, km)+wk1(i)+aa(i, km)*gam(i, km))
2495  w2(i, km) = (dm(i, km)*w1(i, km)+dt*(pp(i, km+1)-pp(i, km))-wk1(i)&
2496 & *ws(i)-aa(i, km)*w2(i, km-1))/bet(i)
2497  END DO
2498  DO k=km-1,1,-1
2499  DO i=is,ie
2500  w2(i, k) = w2(i, k) - gam(i, k+1)*w2(i, k+1)
2501  END DO
2502  END DO
2503 ! pe2 is updated perturbation p at edges
2504  DO i=is,ie
2505  pe2(i, 1) = 0.
2506  END DO
2507  DO k=1,km
2508  DO i=is,ie
2509  pe2(i, k+1) = pe2(i, k) + dm(i, k)*(w2(i, k)-w1(i, k))*rdt
2510  END DO
2511  END DO
2512 ! Full non-hydro pressure at edges:
2513  DO i=is,ie
2514  pe2(i, 1) = pem(i, 1)
2515  END DO
2516  DO k=2,km+1
2517  DO i=is,ie
2518  IF (p_fac*pem(i, k) .LT. pe2(i, k) + pem(i, k)) THEN
2519  pe2(i, k) = pe2(i, k) + pem(i, k)
2520  ELSE
2521  pe2(i, k) = p_fac*pem(i, k)
2522  END IF
2523  END DO
2524  END DO
2525  DO i=is,ie
2526 ! Recover cell-averaged pressure
2527  p1(i) = (pe2(i, km)+2.*pe2(i, km+1))*r3 - r6g*dm(i, km)
2528  arg1 = capa1*log(p1(i))
2529  dz2(i, km) = -(dm(i, km)*rgas*pt2(i, km)*exp(arg1))
2530  END DO
2531  DO k=km-1,1,-1
2532  DO i=is,ie
2533  p1(i) = (pe2(i, k)+bb(i, k)*pe2(i, k+1)+g_rat(i, k)*pe2(i, k+2))&
2534 & *r3 - g_rat(i, k)*p1(i)
2535  arg1 = capa1*log(p1(i))
2536  dz2(i, k) = -(dm(i, k)*rgas*pt2(i, k)*exp(arg1))
2537  END DO
2538  END DO
2539  DO k=1,km+1
2540  DO i=is,ie
2541  pe2(i, k) = pe2(i, k) - pem(i, k)
2542  END DO
2543  END DO
2544  END SUBROUTINE sim3p0_solver
2545 ! Differentiation of sim1_solver in forward (tangent) mode:
2546 ! variations of useful results: dz2 w2 pe
2547 ! with respect to varying inputs: ws dm2 dz2 w2 pm2 pem pe pt2
2548  SUBROUTINE sim1_solver_tlm(dt, is, ie, km, rgas, gama, gm2, cp2, kappa&
2549 & , pe, pe_tl, dm2, dm2_tl, pm2, pm2_tl, pem, pem_tl, w2, w2_tl, dz2, &
2550 & dz2_tl, pt2, pt2_tl, ws, ws_tl, p_fac)
2551  IMPLICIT NONE
2552  INTEGER, INTENT(IN) :: is, ie, km
2553  REAL, INTENT(IN) :: dt, rgas, gama, kappa, p_fac
2554  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm2, pt2, pm2, gm2, cp2
2555  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm2_tl, pt2_tl, pm2_tl
2556  REAL, INTENT(IN) :: ws(is:ie)
2557  REAL, INTENT(IN) :: ws_tl(is:ie)
2558  REAL, DIMENSION(is:ie, km+1), INTENT(IN) :: pem
2559  REAL, DIMENSION(is:ie, km+1), INTENT(IN) :: pem_tl
2560  REAL, INTENT(OUT) :: pe(is:ie, km+1)
2561  REAL, INTENT(OUT) :: pe_tl(is:ie, km+1)
2562  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2, w2
2563  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2_tl, w2_tl
2564 ! Local
2565  REAL, DIMENSION(is:ie, km) :: aa, bb, dd, w1, g_rat, gam
2566  REAL, DIMENSION(is:ie, km) :: aa_tl, bb_tl, dd_tl, w1_tl, g_rat_tl, &
2567 & gam_tl
2568  REAL, DIMENSION(is:ie, km+1) :: pp
2569  REAL, DIMENSION(is:ie, km+1) :: pp_tl
2570  REAL, DIMENSION(is:ie) :: p1, bet
2571  REAL, DIMENSION(is:ie) :: p1_tl, bet_tl
2572  REAL :: t1g, rdt, capa1
2573  INTEGER :: i, k
2574  INTRINSIC log
2575  INTRINSIC exp
2576  INTRINSIC max
2577  REAL :: max1
2578  REAL :: max1_tl
2579  REAL :: max2
2580  REAL :: max2_tl
2581  REAL :: arg1
2582  REAL :: arg1_tl
2583  REAL :: arg2
2584  REAL :: arg2_tl
2585  t1g = gama*2.*dt*dt
2586  rdt = 1./dt
2587  capa1 = kappa - 1.
2588  w1_tl = 0.0
2589  DO k=1,km
2590  DO i=is,ie
2591  w1_tl(i, k) = w2_tl(i, k)
2592  w1(i, k) = w2(i, k)
2593  arg1_tl = -(rgas*((dm2_tl(i, k)*dz2(i, k)-dm2(i, k)*dz2_tl(i, k)&
2594 & )*pt2(i, k)/dz2(i, k)**2+dm2(i, k)*pt2_tl(i, k)/dz2(i, k)))
2595  arg1 = -(dm2(i, k)/dz2(i, k)*rgas*pt2(i, k))
2596  arg2_tl = gama*arg1_tl/arg1
2597  arg2 = gama*log(arg1)
2598  pe_tl(i, k) = arg2_tl*exp(arg2) - pm2_tl(i, k)
2599  pe(i, k) = exp(arg2) - pm2(i, k)
2600  END DO
2601  END DO
2602  dd_tl = 0.0
2603  bb_tl = 0.0
2604  g_rat_tl = 0.0
2605  DO k=1,km-1
2606  DO i=is,ie
2607  g_rat_tl(i, k) = (dm2_tl(i, k)*dm2(i, k+1)-dm2(i, k)*dm2_tl(i, k&
2608 & +1))/dm2(i, k+1)**2
2609  g_rat(i, k) = dm2(i, k)/dm2(i, k+1)
2610  bb_tl(i, k) = 2.*g_rat_tl(i, k)
2611  bb(i, k) = 2.*(1.+g_rat(i, k))
2612  dd_tl(i, k) = 3.*(pe_tl(i, k)+g_rat_tl(i, k)*pe(i, k+1)+g_rat(i&
2613 & , k)*pe_tl(i, k+1))
2614  dd(i, k) = 3.*(pe(i, k)+g_rat(i, k)*pe(i, k+1))
2615  END DO
2616  END DO
2617  bet_tl = 0.0
2618  pp_tl = 0.0
2619  DO i=is,ie
2620  bet_tl(i) = bb_tl(i, 1)
2621  bet(i) = bb(i, 1)
2622  pp_tl(i, 1) = 0.0
2623  pp(i, 1) = 0.
2624  pp_tl(i, 2) = (dd_tl(i, 1)*bet(i)-dd(i, 1)*bet_tl(i))/bet(i)**2
2625  pp(i, 2) = dd(i, 1)/bet(i)
2626  bb_tl(i, km) = 0.0
2627  bb(i, km) = 2.
2628  dd_tl(i, km) = 3.*pe_tl(i, km)
2629  dd(i, km) = 3.*pe(i, km)
2630  END DO
2631  gam_tl = 0.0
2632  DO k=2,km
2633  DO i=is,ie
2634  gam_tl(i, k) = (g_rat_tl(i, k-1)*bet(i)-g_rat(i, k-1)*bet_tl(i))&
2635 & /bet(i)**2
2636  gam(i, k) = g_rat(i, k-1)/bet(i)
2637  bet_tl(i) = bb_tl(i, k) - gam_tl(i, k)
2638  bet(i) = bb(i, k) - gam(i, k)
2639  pp_tl(i, k+1) = ((dd_tl(i, k)-pp_tl(i, k))*bet(i)-(dd(i, k)-pp(i&
2640 & , k))*bet_tl(i))/bet(i)**2
2641  pp(i, k+1) = (dd(i, k)-pp(i, k))/bet(i)
2642  END DO
2643  END DO
2644  DO k=km,2,-1
2645  DO i=is,ie
2646  pp_tl(i, k) = pp_tl(i, k) - gam_tl(i, k)*pp(i, k+1) - gam(i, k)*&
2647 & pp_tl(i, k+1)
2648  pp(i, k) = pp(i, k) - gam(i, k)*pp(i, k+1)
2649  END DO
2650  END DO
2651  aa_tl = 0.0
2652 ! Start the w-solver
2653  DO k=2,km
2654  DO i=is,ie
2655  aa_tl(i, k) = t1g*(pem_tl(i, k)+pp_tl(i, k))/(dz2(i, k-1)+dz2(i&
2656 & , k)) - t1g*(dz2_tl(i, k-1)+dz2_tl(i, k))*(pem(i, k)+pp(i, k))&
2657 & /(dz2(i, k-1)+dz2(i, k))**2
2658  aa(i, k) = t1g/(dz2(i, k-1)+dz2(i, k))*(pem(i, k)+pp(i, k))
2659  END DO
2660  END DO
2661  DO i=is,ie
2662  bet_tl(i) = dm2_tl(i, 1) - aa_tl(i, 2)
2663  bet(i) = dm2(i, 1) - aa(i, 2)
2664  w2_tl(i, 1) = ((dm2_tl(i, 1)*w1(i, 1)+dm2(i, 1)*w1_tl(i, 1)+dt*&
2665 & pp_tl(i, 2))*bet(i)-(dm2(i, 1)*w1(i, 1)+dt*pp(i, 2))*bet_tl(i))/&
2666 & bet(i)**2
2667  w2(i, 1) = (dm2(i, 1)*w1(i, 1)+dt*pp(i, 2))/bet(i)
2668  END DO
2669  DO k=2,km-1
2670  DO i=is,ie
2671  gam_tl(i, k) = (aa_tl(i, k)*bet(i)-aa(i, k)*bet_tl(i))/bet(i)**2
2672  gam(i, k) = aa(i, k)/bet(i)
2673  bet_tl(i) = dm2_tl(i, k) - aa_tl(i, k) - aa_tl(i, k+1) - aa_tl(i&
2674 & , k)*gam(i, k) - aa(i, k)*gam_tl(i, k)
2675  bet(i) = dm2(i, k) - (aa(i, k)+aa(i, k+1)+aa(i, k)*gam(i, k))
2676  w2_tl(i, k) = ((dm2_tl(i, k)*w1(i, k)+dm2(i, k)*w1_tl(i, k)+dt*(&
2677 & pp_tl(i, k+1)-pp_tl(i, k))-aa_tl(i, k)*w2(i, k-1)-aa(i, k)*&
2678 & w2_tl(i, k-1))*bet(i)-(dm2(i, k)*w1(i, k)+dt*(pp(i, k+1)-pp(i&
2679 & , k))-aa(i, k)*w2(i, k-1))*bet_tl(i))/bet(i)**2
2680  w2(i, k) = (dm2(i, k)*w1(i, k)+dt*(pp(i, k+1)-pp(i, k))-aa(i, k)&
2681 & *w2(i, k-1))/bet(i)
2682  END DO
2683  END DO
2684  p1_tl = 0.0
2685  DO i=is,ie
2686  p1_tl(i) = t1g*(pem_tl(i, km+1)+pp_tl(i, km+1))/dz2(i, km) - t1g*&
2687 & dz2_tl(i, km)*(pem(i, km+1)+pp(i, km+1))/dz2(i, km)**2
2688  p1(i) = t1g/dz2(i, km)*(pem(i, km+1)+pp(i, km+1))
2689  gam_tl(i, km) = (aa_tl(i, km)*bet(i)-aa(i, km)*bet_tl(i))/bet(i)**&
2690 & 2
2691  gam(i, km) = aa(i, km)/bet(i)
2692  bet_tl(i) = dm2_tl(i, km) - aa_tl(i, km) - p1_tl(i) - aa_tl(i, km)&
2693 & *gam(i, km) - aa(i, km)*gam_tl(i, km)
2694  bet(i) = dm2(i, km) - (aa(i, km)+p1(i)+aa(i, km)*gam(i, km))
2695  w2_tl(i, km) = ((dm2_tl(i, km)*w1(i, km)+dm2(i, km)*w1_tl(i, km)+&
2696 & dt*(pp_tl(i, km+1)-pp_tl(i, km))-p1_tl(i)*ws(i)-p1(i)*ws_tl(i)-&
2697 & aa_tl(i, km)*w2(i, km-1)-aa(i, km)*w2_tl(i, km-1))*bet(i)-(dm2(i&
2698 & , km)*w1(i, km)+dt*(pp(i, km+1)-pp(i, km))-p1(i)*ws(i)-aa(i, km)&
2699 & *w2(i, km-1))*bet_tl(i))/bet(i)**2
2700  w2(i, km) = (dm2(i, km)*w1(i, km)+dt*(pp(i, km+1)-pp(i, km))-p1(i)&
2701 & *ws(i)-aa(i, km)*w2(i, km-1))/bet(i)
2702  END DO
2703  DO k=km-1,1,-1
2704  DO i=is,ie
2705  w2_tl(i, k) = w2_tl(i, k) - gam_tl(i, k+1)*w2(i, k+1) - gam(i, k&
2706 & +1)*w2_tl(i, k+1)
2707  w2(i, k) = w2(i, k) - gam(i, k+1)*w2(i, k+1)
2708  END DO
2709  END DO
2710  DO i=is,ie
2711  pe_tl(i, 1) = 0.0
2712  pe(i, 1) = 0.
2713  END DO
2714  DO k=1,km
2715  DO i=is,ie
2716  pe_tl(i, k+1) = pe_tl(i, k) + rdt*(dm2_tl(i, k)*(w2(i, k)-w1(i, &
2717 & k))+dm2(i, k)*(w2_tl(i, k)-w1_tl(i, k)))
2718  pe(i, k+1) = pe(i, k) + dm2(i, k)*(w2(i, k)-w1(i, k))*rdt
2719  END DO
2720  END DO
2721  DO i=is,ie
2722  p1_tl(i) = r3*(pe_tl(i, km)+2.*pe_tl(i, km+1))
2723  p1(i) = (pe(i, km)+2.*pe(i, km+1))*r3
2724  IF (p_fac*pm2(i, km) .LT. p1(i) + pm2(i, km)) THEN
2725  max1_tl = p1_tl(i) + pm2_tl(i, km)
2726  max1 = p1(i) + pm2(i, km)
2727  ELSE
2728  max1_tl = p_fac*pm2_tl(i, km)
2729  max1 = p_fac*pm2(i, km)
2730  END IF
2731  arg1_tl = capa1*max1_tl/max1
2732  arg1 = capa1*log(max1)
2733  dz2_tl(i, km) = -(rgas*((dm2_tl(i, km)*pt2(i, km)+dm2(i, km)*&
2734 & pt2_tl(i, km))*exp(arg1)+dm2(i, km)*pt2(i, km)*arg1_tl*exp(arg1)&
2735 & ))
2736  dz2(i, km) = -(dm2(i, km)*rgas*pt2(i, km)*exp(arg1))
2737  END DO
2738  DO k=km-1,1,-1
2739  DO i=is,ie
2740  p1_tl(i) = r3*(pe_tl(i, k)+bb_tl(i, k)*pe(i, k+1)+bb(i, k)*pe_tl&
2741 & (i, k+1)+g_rat_tl(i, k)*pe(i, k+2)+g_rat(i, k)*pe_tl(i, k+2)) &
2742 & - g_rat_tl(i, k)*p1(i) - g_rat(i, k)*p1_tl(i)
2743  p1(i) = (pe(i, k)+bb(i, k)*pe(i, k+1)+g_rat(i, k)*pe(i, k+2))*r3&
2744 & - g_rat(i, k)*p1(i)
2745  IF (p_fac*pm2(i, k) .LT. p1(i) + pm2(i, k)) THEN
2746  max2_tl = p1_tl(i) + pm2_tl(i, k)
2747  max2 = p1(i) + pm2(i, k)
2748  ELSE
2749  max2_tl = p_fac*pm2_tl(i, k)
2750  max2 = p_fac*pm2(i, k)
2751  END IF
2752  arg1_tl = capa1*max2_tl/max2
2753  arg1 = capa1*log(max2)
2754  dz2_tl(i, k) = -(rgas*((dm2_tl(i, k)*pt2(i, k)+dm2(i, k)*pt2_tl(&
2755 & i, k))*exp(arg1)+dm2(i, k)*pt2(i, k)*arg1_tl*exp(arg1)))
2756  dz2(i, k) = -(dm2(i, k)*rgas*pt2(i, k)*exp(arg1))
2757  END DO
2758  END DO
2759  END SUBROUTINE sim1_solver_tlm
2760  SUBROUTINE sim1_solver(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe&
2761 & , dm2, pm2, pem, w2, dz2, pt2, ws, p_fac)
2762  IMPLICIT NONE
2763  INTEGER, INTENT(IN) :: is, ie, km
2764  REAL, INTENT(IN) :: dt, rgas, gama, kappa, p_fac
2765  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm2, pt2, pm2, gm2, cp2
2766  REAL, INTENT(IN) :: ws(is:ie)
2767  REAL, DIMENSION(is:ie, km+1), INTENT(IN) :: pem
2768  REAL, INTENT(OUT) :: pe(is:ie, km+1)
2769  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2, w2
2770 ! Local
2771  REAL, DIMENSION(is:ie, km) :: aa, bb, dd, w1, g_rat, gam
2772  REAL, DIMENSION(is:ie, km+1) :: pp
2773  REAL, DIMENSION(is:ie) :: p1, bet
2774  REAL :: t1g, rdt, capa1
2775  INTEGER :: i, k
2776  INTRINSIC log
2777  INTRINSIC exp
2778  INTRINSIC max
2779  REAL :: max1
2780  REAL :: max2
2781  REAL :: arg1
2782  REAL :: arg2
2783  t1g = gama*2.*dt*dt
2784  rdt = 1./dt
2785  capa1 = kappa - 1.
2786  DO k=1,km
2787  DO i=is,ie
2788  w1(i, k) = w2(i, k)
2789  arg1 = -(dm2(i, k)/dz2(i, k)*rgas*pt2(i, k))
2790  arg2 = gama*log(arg1)
2791  pe(i, k) = exp(arg2) - pm2(i, k)
2792  END DO
2793  END DO
2794  DO k=1,km-1
2795  DO i=is,ie
2796  g_rat(i, k) = dm2(i, k)/dm2(i, k+1)
2797  bb(i, k) = 2.*(1.+g_rat(i, k))
2798  dd(i, k) = 3.*(pe(i, k)+g_rat(i, k)*pe(i, k+1))
2799  END DO
2800  END DO
2801  DO i=is,ie
2802  bet(i) = bb(i, 1)
2803  pp(i, 1) = 0.
2804  pp(i, 2) = dd(i, 1)/bet(i)
2805  bb(i, km) = 2.
2806  dd(i, km) = 3.*pe(i, km)
2807  END DO
2808  DO k=2,km
2809  DO i=is,ie
2810  gam(i, k) = g_rat(i, k-1)/bet(i)
2811  bet(i) = bb(i, k) - gam(i, k)
2812  pp(i, k+1) = (dd(i, k)-pp(i, k))/bet(i)
2813  END DO
2814  END DO
2815  DO k=km,2,-1
2816  DO i=is,ie
2817  pp(i, k) = pp(i, k) - gam(i, k)*pp(i, k+1)
2818  END DO
2819  END DO
2820 ! Start the w-solver
2821  DO k=2,km
2822  DO i=is,ie
2823  aa(i, k) = t1g/(dz2(i, k-1)+dz2(i, k))*(pem(i, k)+pp(i, k))
2824  END DO
2825  END DO
2826  DO i=is,ie
2827  bet(i) = dm2(i, 1) - aa(i, 2)
2828  w2(i, 1) = (dm2(i, 1)*w1(i, 1)+dt*pp(i, 2))/bet(i)
2829  END DO
2830  DO k=2,km-1
2831  DO i=is,ie
2832  gam(i, k) = aa(i, k)/bet(i)
2833  bet(i) = dm2(i, k) - (aa(i, k)+aa(i, k+1)+aa(i, k)*gam(i, k))
2834  w2(i, k) = (dm2(i, k)*w1(i, k)+dt*(pp(i, k+1)-pp(i, k))-aa(i, k)&
2835 & *w2(i, k-1))/bet(i)
2836  END DO
2837  END DO
2838  DO i=is,ie
2839  p1(i) = t1g/dz2(i, km)*(pem(i, km+1)+pp(i, km+1))
2840  gam(i, km) = aa(i, km)/bet(i)
2841  bet(i) = dm2(i, km) - (aa(i, km)+p1(i)+aa(i, km)*gam(i, km))
2842  w2(i, km) = (dm2(i, km)*w1(i, km)+dt*(pp(i, km+1)-pp(i, km))-p1(i)&
2843 & *ws(i)-aa(i, km)*w2(i, km-1))/bet(i)
2844  END DO
2845  DO k=km-1,1,-1
2846  DO i=is,ie
2847  w2(i, k) = w2(i, k) - gam(i, k+1)*w2(i, k+1)
2848  END DO
2849  END DO
2850  DO i=is,ie
2851  pe(i, 1) = 0.
2852  END DO
2853  DO k=1,km
2854  DO i=is,ie
2855  pe(i, k+1) = pe(i, k) + dm2(i, k)*(w2(i, k)-w1(i, k))*rdt
2856  END DO
2857  END DO
2858  DO i=is,ie
2859  p1(i) = (pe(i, km)+2.*pe(i, km+1))*r3
2860  IF (p_fac*pm2(i, km) .LT. p1(i) + pm2(i, km)) THEN
2861  max1 = p1(i) + pm2(i, km)
2862  ELSE
2863  max1 = p_fac*pm2(i, km)
2864  END IF
2865  arg1 = capa1*log(max1)
2866  dz2(i, km) = -(dm2(i, km)*rgas*pt2(i, km)*exp(arg1))
2867  END DO
2868  DO k=km-1,1,-1
2869  DO i=is,ie
2870  p1(i) = (pe(i, k)+bb(i, k)*pe(i, k+1)+g_rat(i, k)*pe(i, k+2))*r3&
2871 & - g_rat(i, k)*p1(i)
2872  IF (p_fac*pm2(i, k) .LT. p1(i) + pm2(i, k)) THEN
2873  max2 = p1(i) + pm2(i, k)
2874  ELSE
2875  max2 = p_fac*pm2(i, k)
2876  END IF
2877  arg1 = capa1*log(max2)
2878  dz2(i, k) = -(dm2(i, k)*rgas*pt2(i, k)*exp(arg1))
2879  END DO
2880  END DO
2881  END SUBROUTINE sim1_solver
2882 ! Differentiation of sim_solver in forward (tangent) mode:
2883 ! variations of useful results: pe2 dz2 w2
2884 ! with respect to varying inputs: ws pe2 dm2 dz2 w2 pm2 pem pt2
2885  SUBROUTINE sim_solver_tlm(dt, is, ie, km, rgas, gama, gm2, cp2, kappa&
2886 & , pe2, pe2_tl, dm2, dm2_tl, pm2, pm2_tl, pem, pem_tl, w2, w2_tl, dz2&
2887 & , dz2_tl, pt2, pt2_tl, ws, ws_tl, alpha, p_fac, scale_m)
2888  IMPLICIT NONE
2889  INTEGER, INTENT(IN) :: is, ie, km
2890  REAL, INTENT(IN) :: dt, rgas, gama, kappa, p_fac, alpha, scale_m
2891  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm2, pt2, pm2, gm2, cp2
2892  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm2_tl, pt2_tl, pm2_tl
2893  REAL, INTENT(IN) :: ws(is:ie)
2894  REAL, INTENT(IN) :: ws_tl(is:ie)
2895  REAL, DIMENSION(is:ie, km+1), INTENT(IN) :: pem
2896  REAL, DIMENSION(is:ie, km+1), INTENT(IN) :: pem_tl
2897  REAL, INTENT(OUT) :: pe2(is:ie, km+1)
2898  REAL, INTENT(OUT) :: pe2_tl(is:ie, km+1)
2899  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2, w2
2900  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2_tl, w2_tl
2901 ! Local
2902  REAL, DIMENSION(is:ie, km) :: aa, bb, dd, w1, wk, g_rat, gam
2903  REAL, DIMENSION(is:ie, km) :: aa_tl, bb_tl, dd_tl, w1_tl, wk_tl, &
2904 & g_rat_tl, gam_tl
2905  REAL, DIMENSION(is:ie, km+1) :: pp
2906  REAL, DIMENSION(is:ie, km+1) :: pp_tl
2907  REAL, DIMENSION(is:ie) :: p1, wk1, bet
2908  REAL, DIMENSION(is:ie) :: p1_tl, wk1_tl, bet_tl
2909  REAL :: beta, t2, t1g, rdt, ra, capa1
2910  INTEGER :: i, k
2911  INTRINSIC log
2912  INTRINSIC exp
2913  INTRINSIC max
2914  REAL :: max1
2915  REAL :: max1_tl
2916  REAL :: max2
2917  REAL :: max2_tl
2918  REAL :: arg1
2919  REAL :: arg1_tl
2920  REAL :: arg2
2921  REAL :: arg2_tl
2922  beta = 1. - alpha
2923  ra = 1./alpha
2924  t2 = beta/alpha
2925  t1g = 2.*gama*(alpha*dt)**2
2926  rdt = 1./dt
2927  capa1 = kappa - 1.
2928  w1_tl = 0.0
2929  DO k=1,km
2930  DO i=is,ie
2931  w1_tl(i, k) = w2_tl(i, k)
2932  w1(i, k) = w2(i, k)
2933 ! P_g perturbation
2934  arg1_tl = -(rgas*((dm2_tl(i, k)*dz2(i, k)-dm2(i, k)*dz2_tl(i, k)&
2935 & )*pt2(i, k)/dz2(i, k)**2+dm2(i, k)*pt2_tl(i, k)/dz2(i, k)))
2936  arg1 = -(dm2(i, k)/dz2(i, k)*rgas*pt2(i, k))
2937  arg2_tl = gama*arg1_tl/arg1
2938  arg2 = gama*log(arg1)
2939  pe2_tl(i, k) = arg2_tl*exp(arg2) - pm2_tl(i, k)
2940  pe2(i, k) = exp(arg2) - pm2(i, k)
2941  END DO
2942  END DO
2943  dd_tl = 0.0
2944  bb_tl = 0.0
2945  g_rat_tl = 0.0
2946  DO k=1,km-1
2947  DO i=is,ie
2948  g_rat_tl(i, k) = (dm2_tl(i, k)*dm2(i, k+1)-dm2(i, k)*dm2_tl(i, k&
2949 & +1))/dm2(i, k+1)**2
2950  g_rat(i, k) = dm2(i, k)/dm2(i, k+1)
2951  bb_tl(i, k) = 2.*g_rat_tl(i, k)
2952  bb(i, k) = 2.*(1.+g_rat(i, k))
2953  dd_tl(i, k) = 3.*(pe2_tl(i, k)+g_rat_tl(i, k)*pe2(i, k+1)+g_rat(&
2954 & i, k)*pe2_tl(i, k+1))
2955  dd(i, k) = 3.*(pe2(i, k)+g_rat(i, k)*pe2(i, k+1))
2956  END DO
2957  END DO
2958  bet_tl = 0.0
2959  pp_tl = 0.0
2960  DO i=is,ie
2961  bet_tl(i) = bb_tl(i, 1)
2962  bet(i) = bb(i, 1)
2963  pp_tl(i, 1) = 0.0
2964  pp(i, 1) = 0.
2965  pp_tl(i, 2) = (dd_tl(i, 1)*bet(i)-dd(i, 1)*bet_tl(i))/bet(i)**2
2966  pp(i, 2) = dd(i, 1)/bet(i)
2967  bb_tl(i, km) = 0.0
2968  bb(i, km) = 2.
2969  dd_tl(i, km) = 3.*pe2_tl(i, km)
2970  dd(i, km) = 3.*pe2(i, km)
2971  END DO
2972  gam_tl = 0.0
2973  DO k=2,km
2974  DO i=is,ie
2975  gam_tl(i, k) = (g_rat_tl(i, k-1)*bet(i)-g_rat(i, k-1)*bet_tl(i))&
2976 & /bet(i)**2
2977  gam(i, k) = g_rat(i, k-1)/bet(i)
2978  bet_tl(i) = bb_tl(i, k) - gam_tl(i, k)
2979  bet(i) = bb(i, k) - gam(i, k)
2980  pp_tl(i, k+1) = ((dd_tl(i, k)-pp_tl(i, k))*bet(i)-(dd(i, k)-pp(i&
2981 & , k))*bet_tl(i))/bet(i)**2
2982  pp(i, k+1) = (dd(i, k)-pp(i, k))/bet(i)
2983  END DO
2984  END DO
2985  DO k=km,2,-1
2986  DO i=is,ie
2987  pp_tl(i, k) = pp_tl(i, k) - gam_tl(i, k)*pp(i, k+1) - gam(i, k)*&
2988 & pp_tl(i, k+1)
2989  pp(i, k) = pp(i, k) - gam(i, k)*pp(i, k+1)
2990  END DO
2991  END DO
2992  DO k=1,km+1
2993  DO i=is,ie
2994 ! pe2 is Full p
2995  pe2_tl(i, k) = pem_tl(i, k) + pp_tl(i, k)
2996  pe2(i, k) = pem(i, k) + pp(i, k)
2997  END DO
2998  END DO
2999  aa_tl = 0.0
3000  wk_tl = 0.0
3001  DO k=2,km
3002  DO i=is,ie
3003  aa_tl(i, k) = t1g*pe2_tl(i, k)/(dz2(i, k-1)+dz2(i, k)) - t1g*(&
3004 & dz2_tl(i, k-1)+dz2_tl(i, k))*pe2(i, k)/(dz2(i, k-1)+dz2(i, k))&
3005 & **2
3006  aa(i, k) = t1g/(dz2(i, k-1)+dz2(i, k))*pe2(i, k)
3007  wk_tl(i, k) = t2*(aa_tl(i, k)*(w1(i, k-1)-w1(i, k))+aa(i, k)*(&
3008 & w1_tl(i, k-1)-w1_tl(i, k)))
3009  wk(i, k) = t2*aa(i, k)*(w1(i, k-1)-w1(i, k))
3010  aa_tl(i, k) = aa_tl(i, k) - scale_m*dm2_tl(i, 1)
3011  aa(i, k) = aa(i, k) - scale_m*dm2(i, 1)
3012  END DO
3013  END DO
3014 ! Top:
3015  DO i=is,ie
3016  bet_tl(i) = dm2_tl(i, 1) - aa_tl(i, 2)
3017  bet(i) = dm2(i, 1) - aa(i, 2)
3018  w2_tl(i, 1) = ((dm2_tl(i, 1)*w1(i, 1)+dm2(i, 1)*w1_tl(i, 1)+dt*&
3019 & pp_tl(i, 2)+wk_tl(i, 2))*bet(i)-(dm2(i, 1)*w1(i, 1)+dt*pp(i, 2)+&
3020 & wk(i, 2))*bet_tl(i))/bet(i)**2
3021  w2(i, 1) = (dm2(i, 1)*w1(i, 1)+dt*pp(i, 2)+wk(i, 2))/bet(i)
3022  END DO
3023 ! Interior:
3024  DO k=2,km-1
3025  DO i=is,ie
3026  gam_tl(i, k) = (aa_tl(i, k)*bet(i)-aa(i, k)*bet_tl(i))/bet(i)**2
3027  gam(i, k) = aa(i, k)/bet(i)
3028  bet_tl(i) = dm2_tl(i, k) - aa_tl(i, k) - aa_tl(i, k+1) - aa_tl(i&
3029 & , k)*gam(i, k) - aa(i, k)*gam_tl(i, k)
3030  bet(i) = dm2(i, k) - (aa(i, k)+aa(i, k+1)+aa(i, k)*gam(i, k))
3031  w2_tl(i, k) = ((dm2_tl(i, k)*w1(i, k)+dm2(i, k)*w1_tl(i, k)+dt*(&
3032 & pp_tl(i, k+1)-pp_tl(i, k))+wk_tl(i, k+1)-wk_tl(i, k)-aa_tl(i, &
3033 & k)*w2(i, k-1)-aa(i, k)*w2_tl(i, k-1))*bet(i)-(dm2(i, k)*w1(i, &
3034 & k)+dt*(pp(i, k+1)-pp(i, k))+wk(i, k+1)-wk(i, k)-aa(i, k)*w2(i&
3035 & , k-1))*bet_tl(i))/bet(i)**2
3036  w2(i, k) = (dm2(i, k)*w1(i, k)+dt*(pp(i, k+1)-pp(i, k))+wk(i, k+&
3037 & 1)-wk(i, k)-aa(i, k)*w2(i, k-1))/bet(i)
3038  END DO
3039  END DO
3040  wk1_tl = 0.0
3041 ! Bottom: k=km
3042  DO i=is,ie
3043  wk1_tl(i) = t1g*pe2_tl(i, km+1)/dz2(i, km) - t1g*dz2_tl(i, km)*pe2&
3044 & (i, km+1)/dz2(i, km)**2
3045  wk1(i) = t1g/dz2(i, km)*pe2(i, km+1)
3046  gam_tl(i, km) = (aa_tl(i, km)*bet(i)-aa(i, km)*bet_tl(i))/bet(i)**&
3047 & 2
3048  gam(i, km) = aa(i, km)/bet(i)
3049  bet_tl(i) = dm2_tl(i, km) - aa_tl(i, km) - wk1_tl(i) - aa_tl(i, km&
3050 & )*gam(i, km) - aa(i, km)*gam_tl(i, km)
3051  bet(i) = dm2(i, km) - (aa(i, km)+wk1(i)+aa(i, km)*gam(i, km))
3052  w2_tl(i, km) = ((dm2_tl(i, km)*w1(i, km)+dm2(i, km)*w1_tl(i, km)+&
3053 & dt*(pp_tl(i, km+1)-pp_tl(i, km))-wk_tl(i, km)+wk1_tl(i)*(t2*w1(i&
3054 & , km)-ra*ws(i))+wk1(i)*(t2*w1_tl(i, km)-ra*ws_tl(i))-aa_tl(i, km&
3055 & )*w2(i, km-1)-aa(i, km)*w2_tl(i, km-1))*bet(i)-(dm2(i, km)*w1(i&
3056 & , km)+dt*(pp(i, km+1)-pp(i, km))-wk(i, km)+wk1(i)*(t2*w1(i, km)-&
3057 & ra*ws(i))-aa(i, km)*w2(i, km-1))*bet_tl(i))/bet(i)**2
3058  w2(i, km) = (dm2(i, km)*w1(i, km)+dt*(pp(i, km+1)-pp(i, km))-wk(i&
3059 & , km)+wk1(i)*(t2*w1(i, km)-ra*ws(i))-aa(i, km)*w2(i, km-1))/bet(&
3060 & i)
3061  END DO
3062  DO k=km-1,1,-1
3063  DO i=is,ie
3064  w2_tl(i, k) = w2_tl(i, k) - gam_tl(i, k+1)*w2(i, k+1) - gam(i, k&
3065 & +1)*w2_tl(i, k+1)
3066  w2(i, k) = w2(i, k) - gam(i, k+1)*w2(i, k+1)
3067  END DO
3068  END DO
3069  DO i=is,ie
3070  pe2_tl(i, 1) = 0.0
3071  pe2(i, 1) = 0.
3072  END DO
3073  DO k=1,km
3074  DO i=is,ie
3075  pe2_tl(i, k+1) = pe2_tl(i, k) + ra*(rdt*(dm2_tl(i, k)*(w2(i, k)-&
3076 & w1(i, k))+dm2(i, k)*(w2_tl(i, k)-w1_tl(i, k)))-beta*(pp_tl(i, &
3077 & k+1)-pp_tl(i, k)))
3078  pe2(i, k+1) = pe2(i, k) + (dm2(i, k)*(w2(i, k)-w1(i, k))*rdt-&
3079 & beta*(pp(i, k+1)-pp(i, k)))*ra
3080  END DO
3081  END DO
3082  p1_tl = 0.0
3083  DO i=is,ie
3084  p1_tl(i) = r3*(pe2_tl(i, km)+2.*pe2_tl(i, km+1))
3085  p1(i) = (pe2(i, km)+2.*pe2(i, km+1))*r3
3086  IF (p_fac*pm2(i, km) .LT. p1(i) + pm2(i, km)) THEN
3087  max1_tl = p1_tl(i) + pm2_tl(i, km)
3088  max1 = p1(i) + pm2(i, km)
3089  ELSE
3090  max1_tl = p_fac*pm2_tl(i, km)
3091  max1 = p_fac*pm2(i, km)
3092  END IF
3093  arg1_tl = capa1*max1_tl/max1
3094  arg1 = capa1*log(max1)
3095  dz2_tl(i, km) = -(rgas*((dm2_tl(i, km)*pt2(i, km)+dm2(i, km)*&
3096 & pt2_tl(i, km))*exp(arg1)+dm2(i, km)*pt2(i, km)*arg1_tl*exp(arg1)&
3097 & ))
3098  dz2(i, km) = -(dm2(i, km)*rgas*pt2(i, km)*exp(arg1))
3099  END DO
3100  DO k=km-1,1,-1
3101  DO i=is,ie
3102  p1_tl(i) = r3*(pe2_tl(i, k)+bb_tl(i, k)*pe2(i, k+1)+bb(i, k)*&
3103 & pe2_tl(i, k+1)+g_rat_tl(i, k)*pe2(i, k+2)+g_rat(i, k)*pe2_tl(i&
3104 & , k+2)) - g_rat_tl(i, k)*p1(i) - g_rat(i, k)*p1_tl(i)
3105  p1(i) = (pe2(i, k)+bb(i, k)*pe2(i, k+1)+g_rat(i, k)*pe2(i, k+2))&
3106 & *r3 - g_rat(i, k)*p1(i)
3107  IF (p_fac*pm2(i, k) .LT. p1(i) + pm2(i, k)) THEN
3108  max2_tl = p1_tl(i) + pm2_tl(i, k)
3109  max2 = p1(i) + pm2(i, k)
3110  ELSE
3111  max2_tl = p_fac*pm2_tl(i, k)
3112  max2 = p_fac*pm2(i, k)
3113  END IF
3114 ! delz = -dm*R*T_m / p_gas
3115  arg1_tl = capa1*max2_tl/max2
3116  arg1 = capa1*log(max2)
3117  dz2_tl(i, k) = -(rgas*((dm2_tl(i, k)*pt2(i, k)+dm2(i, k)*pt2_tl(&
3118 & i, k))*exp(arg1)+dm2(i, k)*pt2(i, k)*arg1_tl*exp(arg1)))
3119  dz2(i, k) = -(dm2(i, k)*rgas*pt2(i, k)*exp(arg1))
3120  END DO
3121  END DO
3122  DO k=1,km+1
3123  DO i=is,ie
3124  pe2_tl(i, k) = pe2_tl(i, k) + beta*(pp_tl(i, k)-pe2_tl(i, k))
3125  pe2(i, k) = pe2(i, k) + beta*(pp(i, k)-pe2(i, k))
3126  END DO
3127  END DO
3128  END SUBROUTINE sim_solver_tlm
3129  SUBROUTINE sim_solver(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe2&
3130 & , dm2, pm2, pem, w2, dz2, pt2, ws, alpha, p_fac, scale_m)
3131  IMPLICIT NONE
3132  INTEGER, INTENT(IN) :: is, ie, km
3133  REAL, INTENT(IN) :: dt, rgas, gama, kappa, p_fac, alpha, scale_m
3134  REAL, DIMENSION(is:ie, km), INTENT(IN) :: dm2, pt2, pm2, gm2, cp2
3135  REAL, INTENT(IN) :: ws(is:ie)
3136  REAL, DIMENSION(is:ie, km+1), INTENT(IN) :: pem
3137  REAL, INTENT(OUT) :: pe2(is:ie, km+1)
3138  REAL, DIMENSION(is:ie, km), INTENT(INOUT) :: dz2, w2
3139 ! Local
3140  REAL, DIMENSION(is:ie, km) :: aa, bb, dd, w1, wk, g_rat, gam
3141  REAL, DIMENSION(is:ie, km+1) :: pp
3142  REAL, DIMENSION(is:ie) :: p1, wk1, bet
3143  REAL :: beta, t2, t1g, rdt, ra, capa1
3144  INTEGER :: i, k
3145  INTRINSIC log
3146  INTRINSIC exp
3147  INTRINSIC max
3148  REAL :: max1
3149  REAL :: max2
3150  REAL :: arg1
3151  REAL :: arg2
3152  beta = 1. - alpha
3153  ra = 1./alpha
3154  t2 = beta/alpha
3155  t1g = 2.*gama*(alpha*dt)**2
3156  rdt = 1./dt
3157  capa1 = kappa - 1.
3158  DO k=1,km
3159  DO i=is,ie
3160  w1(i, k) = w2(i, k)
3161 ! P_g perturbation
3162  arg1 = -(dm2(i, k)/dz2(i, k)*rgas*pt2(i, k))
3163  arg2 = gama*log(arg1)
3164  pe2(i, k) = exp(arg2) - pm2(i, k)
3165  END DO
3166  END DO
3167  DO k=1,km-1
3168  DO i=is,ie
3169  g_rat(i, k) = dm2(i, k)/dm2(i, k+1)
3170  bb(i, k) = 2.*(1.+g_rat(i, k))
3171  dd(i, k) = 3.*(pe2(i, k)+g_rat(i, k)*pe2(i, k+1))
3172  END DO
3173  END DO
3174  DO i=is,ie
3175  bet(i) = bb(i, 1)
3176  pp(i, 1) = 0.
3177  pp(i, 2) = dd(i, 1)/bet(i)
3178  bb(i, km) = 2.
3179  dd(i, km) = 3.*pe2(i, km)
3180  END DO
3181  DO k=2,km
3182  DO i=is,ie
3183  gam(i, k) = g_rat(i, k-1)/bet(i)
3184  bet(i) = bb(i, k) - gam(i, k)
3185  pp(i, k+1) = (dd(i, k)-pp(i, k))/bet(i)
3186  END DO
3187  END DO
3188  DO k=km,2,-1
3189  DO i=is,ie
3190  pp(i, k) = pp(i, k) - gam(i, k)*pp(i, k+1)
3191  END DO
3192  END DO
3193  DO k=1,km+1
3194  DO i=is,ie
3195 ! pe2 is Full p
3196  pe2(i, k) = pem(i, k) + pp(i, k)
3197  END DO
3198  END DO
3199  DO k=2,km
3200  DO i=is,ie
3201  aa(i, k) = t1g/(dz2(i, k-1)+dz2(i, k))*pe2(i, k)
3202  wk(i, k) = t2*aa(i, k)*(w1(i, k-1)-w1(i, k))
3203  aa(i, k) = aa(i, k) - scale_m*dm2(i, 1)
3204  END DO
3205  END DO
3206 ! Top:
3207  DO i=is,ie
3208  bet(i) = dm2(i, 1) - aa(i, 2)
3209  w2(i, 1) = (dm2(i, 1)*w1(i, 1)+dt*pp(i, 2)+wk(i, 2))/bet(i)
3210  END DO
3211 ! Interior:
3212  DO k=2,km-1
3213  DO i=is,ie
3214  gam(i, k) = aa(i, k)/bet(i)
3215  bet(i) = dm2(i, k) - (aa(i, k)+aa(i, k+1)+aa(i, k)*gam(i, k))
3216  w2(i, k) = (dm2(i, k)*w1(i, k)+dt*(pp(i, k+1)-pp(i, k))+wk(i, k+&
3217 & 1)-wk(i, k)-aa(i, k)*w2(i, k-1))/bet(i)
3218  END DO
3219  END DO
3220 ! Bottom: k=km
3221  DO i=is,ie
3222  wk1(i) = t1g/dz2(i, km)*pe2(i, km+1)
3223  gam(i, km) = aa(i, km)/bet(i)
3224  bet(i) = dm2(i, km) - (aa(i, km)+wk1(i)+aa(i, km)*gam(i, km))
3225  w2(i, km) = (dm2(i, km)*w1(i, km)+dt*(pp(i, km+1)-pp(i, km))-wk(i&
3226 & , km)+wk1(i)*(t2*w1(i, km)-ra*ws(i))-aa(i, km)*w2(i, km-1))/bet(&
3227 & i)
3228  END DO
3229  DO k=km-1,1,-1
3230  DO i=is,ie
3231  w2(i, k) = w2(i, k) - gam(i, k+1)*w2(i, k+1)
3232  END DO
3233  END DO
3234  DO i=is,ie
3235  pe2(i, 1) = 0.
3236  END DO
3237  DO k=1,km
3238  DO i=is,ie
3239  pe2(i, k+1) = pe2(i, k) + (dm2(i, k)*(w2(i, k)-w1(i, k))*rdt-&
3240 & beta*(pp(i, k+1)-pp(i, k)))*ra
3241  END DO
3242  END DO
3243  DO i=is,ie
3244  p1(i) = (pe2(i, km)+2.*pe2(i, km+1))*r3
3245  IF (p_fac*pm2(i, km) .LT. p1(i) + pm2(i, km)) THEN
3246  max1 = p1(i) + pm2(i, km)
3247  ELSE
3248  max1 = p_fac*pm2(i, km)
3249  END IF
3250  arg1 = capa1*log(max1)
3251  dz2(i, km) = -(dm2(i, km)*rgas*pt2(i, km)*exp(arg1))
3252  END DO
3253  DO k=km-1,1,-1
3254  DO i=is,ie
3255  p1(i) = (pe2(i, k)+bb(i, k)*pe2(i, k+1)+g_rat(i, k)*pe2(i, k+2))&
3256 & *r3 - g_rat(i, k)*p1(i)
3257  IF (p_fac*pm2(i, k) .LT. p1(i) + pm2(i, k)) THEN
3258  max2 = p1(i) + pm2(i, k)
3259  ELSE
3260  max2 = p_fac*pm2(i, k)
3261  END IF
3262 ! delz = -dm*R*T_m / p_gas
3263  arg1 = capa1*log(max2)
3264  dz2(i, k) = -(dm2(i, k)*rgas*pt2(i, k)*exp(arg1))
3265  END DO
3266  END DO
3267  DO k=1,km+1
3268  DO i=is,ie
3269  pe2(i, k) = pe2(i, k) + beta*(pp(i, k)-pe2(i, k))
3270  END DO
3271  END DO
3272  END SUBROUTINE sim_solver
3273  SUBROUTINE edge_scalar(q1, qe, i1, i2, km, id)
3274  IMPLICIT NONE
3275 ! Optimized for wind profile reconstruction:
3276  INTEGER, INTENT(IN) :: i1, i2, km
3277 ! 0: pp 1: wind
3278  INTEGER, INTENT(IN) :: id
3279  REAL, DIMENSION(i1:i2, km), INTENT(IN) :: q1
3280  REAL, DIMENSION(i1:i2, km+1), INTENT(OUT) :: qe
3281 !-----------------------------------------------------------------------
3282  REAL, PARAMETER :: r2o3=2./3.
3283  REAL, PARAMETER :: r4o3=4./3.
3284  REAL :: gak(km)
3285  REAL :: bet
3286  INTEGER :: i, k
3287 !------------------------------------------------
3288 ! Optimized coding for uniform grid: SJL Apr 2007
3289 !------------------------------------------------
3290  IF (id .EQ. 1) THEN
3291  DO i=i1,i2
3292  qe(i, 1) = r4o3*q1(i, 1) + r2o3*q1(i, 2)
3293  END DO
3294  ELSE
3295  DO i=i1,i2
3296  qe(i, 1) = 1.e30
3297  END DO
3298  END IF
3299  gak(1) = 7./3.
3300  DO k=2,km
3301  gak(k) = 1./(4.-gak(k-1))
3302  DO i=i1,i2
3303  qe(i, k) = (3.*(q1(i, k-1)+q1(i, k))-qe(i, k-1))*gak(k)
3304  END DO
3305  END DO
3306  bet = 1./(1.5-3.5*gak(km))
3307  DO i=i1,i2
3308  qe(i, km+1) = (4.*q1(i, km)+q1(i, km-1)-3.5*qe(i, km))*bet
3309  END DO
3310  DO k=km,1,-1
3311  DO i=i1,i2
3312  qe(i, k) = qe(i, k) - gak(k)*qe(i, k+1)
3313  END DO
3314  END DO
3315  END SUBROUTINE edge_scalar
3316 ! Differentiation of edge_profile in forward (tangent) mode:
3317 ! variations of useful results: q1e q2e
3318 ! with respect to varying inputs: q1e q2e q1 q2
3319  SUBROUTINE edge_profile_tlm(q1, q1_tl, q2, q2_tl, q1e, q1e_tl, q2e, &
3320 & q2e_tl, i1, i2, j1, j2, j, km, dp0, uniform_grid, limiter)
3321  IMPLICIT NONE
3322 ! Optimized for wind profile reconstruction:
3323  INTEGER, INTENT(IN) :: i1, i2, j1, j2
3324  INTEGER, INTENT(IN) :: j, km
3325  INTEGER, INTENT(IN) :: limiter
3326  LOGICAL, INTENT(IN) :: uniform_grid
3327  REAL, INTENT(IN) :: dp0(km)
3328  REAL, DIMENSION(i1:i2, j1:j2, km), INTENT(IN) :: q1, q2
3329  REAL, DIMENSION(i1:i2, j1:j2, km), INTENT(IN) :: q1_tl, q2_tl
3330  REAL, DIMENSION(i1:i2, j1:j2, km+1), INTENT(OUT) :: q1e, q2e
3331  REAL, DIMENSION(i1:i2, j1:j2, km+1), INTENT(OUT) :: q1e_tl, q2e_tl
3332 !-----------------------------------------------------------------------
3333 ! edge values
3334  REAL, DIMENSION(i1:i2, km+1) :: qe1, qe2, gam
3335  REAL, DIMENSION(i1:i2, km+1) :: qe1_tl, qe2_tl
3336  REAL :: gak(km)
3337  REAL :: bet, r2o3, r4o3
3338  REAL :: g0, gk, xt1, xt2, a_bot
3339  INTEGER :: i, k
3340  IF (uniform_grid) THEN
3341 !------------------------------------------------
3342 ! Optimized coding for uniform grid: SJL Apr 2007
3343 !------------------------------------------------
3344  r2o3 = 2./3.
3345  r4o3 = 4./3.
3346  qe1_tl = 0.0
3347  qe2_tl = 0.0
3348  DO i=i1,i2
3349  qe1_tl(i, 1) = r4o3*q1_tl(i, j, 1) + r2o3*q1_tl(i, j, 2)
3350  qe1(i, 1) = r4o3*q1(i, j, 1) + r2o3*q1(i, j, 2)
3351  qe2_tl(i, 1) = r4o3*q2_tl(i, j, 1) + r2o3*q2_tl(i, j, 2)
3352  qe2(i, 1) = r4o3*q2(i, j, 1) + r2o3*q2(i, j, 2)
3353  END DO
3354  gak(1) = 7./3.
3355  DO k=2,km
3356  gak(k) = 1./(4.-gak(k-1))
3357  DO i=i1,i2
3358  qe1_tl(i, k) = gak(k)*(3.*(q1_tl(i, j, k-1)+q1_tl(i, j, k))-&
3359 & qe1_tl(i, k-1))
3360  qe1(i, k) = (3.*(q1(i, j, k-1)+q1(i, j, k))-qe1(i, k-1))*gak(k&
3361 & )
3362  qe2_tl(i, k) = gak(k)*(3.*(q2_tl(i, j, k-1)+q2_tl(i, j, k))-&
3363 & qe2_tl(i, k-1))
3364  qe2(i, k) = (3.*(q2(i, j, k-1)+q2(i, j, k))-qe2(i, k-1))*gak(k&
3365 & )
3366  END DO
3367  END DO
3368  bet = 1./(1.5-3.5*gak(km))
3369  DO i=i1,i2
3370  qe1_tl(i, km+1) = bet*(4.*q1_tl(i, j, km)+q1_tl(i, j, km-1)-3.5*&
3371 & qe1_tl(i, km))
3372  qe1(i, km+1) = (4.*q1(i, j, km)+q1(i, j, km-1)-3.5*qe1(i, km))*&
3373 & bet
3374  qe2_tl(i, km+1) = bet*(4.*q2_tl(i, j, km)+q2_tl(i, j, km-1)-3.5*&
3375 & qe2_tl(i, km))
3376  qe2(i, km+1) = (4.*q2(i, j, km)+q2(i, j, km-1)-3.5*qe2(i, km))*&
3377 & bet
3378  END DO
3379  DO k=km,1,-1
3380  DO i=i1,i2
3381  qe1_tl(i, k) = qe1_tl(i, k) - gak(k)*qe1_tl(i, k+1)
3382  qe1(i, k) = qe1(i, k) - gak(k)*qe1(i, k+1)
3383  qe2_tl(i, k) = qe2_tl(i, k) - gak(k)*qe2_tl(i, k+1)
3384  qe2(i, k) = qe2(i, k) - gak(k)*qe2(i, k+1)
3385  END DO
3386  END DO
3387  ELSE
3388 ! Assuming grid varying in vertical only
3389  g0 = dp0(2)/dp0(1)
3390  xt1 = 2.*g0*(g0+1.)
3391  bet = g0*(g0+0.5)
3392  qe1_tl = 0.0
3393  qe2_tl = 0.0
3394  DO i=i1,i2
3395  qe1_tl(i, 1) = (xt1*q1_tl(i, j, 1)+q1_tl(i, j, 2))/bet
3396  qe1(i, 1) = (xt1*q1(i, j, 1)+q1(i, j, 2))/bet
3397  qe2_tl(i, 1) = (xt1*q2_tl(i, j, 1)+q2_tl(i, j, 2))/bet
3398  qe2(i, 1) = (xt1*q2(i, j, 1)+q2(i, j, 2))/bet
3399  gam(i, 1) = (1.+g0*(g0+1.5))/bet
3400  END DO
3401  DO k=2,km
3402  gk = dp0(k-1)/dp0(k)
3403  DO i=i1,i2
3404  bet = 2. + 2.*gk - gam(i, k-1)
3405  qe1_tl(i, k) = (3.*(q1_tl(i, j, k-1)+gk*q1_tl(i, j, k))-qe1_tl&
3406 & (i, k-1))/bet
3407  qe1(i, k) = (3.*(q1(i, j, k-1)+gk*q1(i, j, k))-qe1(i, k-1))/&
3408 & bet
3409  qe2_tl(i, k) = (3.*(q2_tl(i, j, k-1)+gk*q2_tl(i, j, k))-qe2_tl&
3410 & (i, k-1))/bet
3411  qe2(i, k) = (3.*(q2(i, j, k-1)+gk*q2(i, j, k))-qe2(i, k-1))/&
3412 & bet
3413  gam(i, k) = gk/bet
3414  END DO
3415  END DO
3416  a_bot = 1. + gk*(gk+1.5)
3417  xt1 = 2.*gk*(gk+1.)
3418  DO i=i1,i2
3419  xt2 = gk*(gk+0.5) - a_bot*gam(i, km)
3420  qe1_tl(i, km+1) = (xt1*q1_tl(i, j, km)+q1_tl(i, j, km-1)-a_bot*&
3421 & qe1_tl(i, km))/xt2
3422  qe1(i, km+1) = (xt1*q1(i, j, km)+q1(i, j, km-1)-a_bot*qe1(i, km)&
3423 & )/xt2
3424  qe2_tl(i, km+1) = (xt1*q2_tl(i, j, km)+q2_tl(i, j, km-1)-a_bot*&
3425 & qe2_tl(i, km))/xt2
3426  qe2(i, km+1) = (xt1*q2(i, j, km)+q2(i, j, km-1)-a_bot*qe2(i, km)&
3427 & )/xt2
3428  END DO
3429  DO k=km,1,-1
3430  DO i=i1,i2
3431  qe1_tl(i, k) = qe1_tl(i, k) - gam(i, k)*qe1_tl(i, k+1)
3432  qe1(i, k) = qe1(i, k) - gam(i, k)*qe1(i, k+1)
3433  qe2_tl(i, k) = qe2_tl(i, k) - gam(i, k)*qe2_tl(i, k+1)
3434  qe2(i, k) = qe2(i, k) - gam(i, k)*qe2(i, k+1)
3435  END DO
3436  END DO
3437  END IF
3438 !------------------
3439 ! Apply constraints
3440 !------------------
3441  IF (limiter .NE. 0) THEN
3442 ! limit the top & bottom winds
3443  DO i=i1,i2
3444 ! Top
3445  IF (q1(i, j, 1)*qe1(i, 1) .LT. 0.) THEN
3446  qe1_tl(i, 1) = 0.0
3447  qe1(i, 1) = 0.
3448  END IF
3449  IF (q2(i, j, 1)*qe2(i, 1) .LT. 0.) THEN
3450  qe2_tl(i, 1) = 0.0
3451  qe2(i, 1) = 0.
3452  END IF
3453 ! Surface:
3454  IF (q1(i, j, km)*qe1(i, km+1) .LT. 0.) THEN
3455  qe1_tl(i, km+1) = 0.0
3456  qe1(i, km+1) = 0.
3457  END IF
3458  IF (q2(i, j, km)*qe2(i, km+1) .LT. 0.) THEN
3459  qe2_tl(i, km+1) = 0.0
3460  qe2(i, km+1) = 0.
3461  END IF
3462  END DO
3463  END IF
3464  DO k=1,km+1
3465  DO i=i1,i2
3466  q1e_tl(i, j, k) = qe1_tl(i, k)
3467  q1e(i, j, k) = qe1(i, k)
3468  q2e_tl(i, j, k) = qe2_tl(i, k)
3469  q2e(i, j, k) = qe2(i, k)
3470  END DO
3471  END DO
3472  END SUBROUTINE edge_profile_tlm
3473  SUBROUTINE edge_profile(q1, q2, q1e, q2e, i1, i2, j1, j2, j, km, dp0, &
3474 & uniform_grid, limiter)
3475  IMPLICIT NONE
3476 ! Optimized for wind profile reconstruction:
3477  INTEGER, INTENT(IN) :: i1, i2, j1, j2
3478  INTEGER, INTENT(IN) :: j, km
3479  INTEGER, INTENT(IN) :: limiter
3480  LOGICAL, INTENT(IN) :: uniform_grid
3481  REAL, INTENT(IN) :: dp0(km)
3482  REAL, DIMENSION(i1:i2, j1:j2, km), INTENT(IN) :: q1, q2
3483  REAL, DIMENSION(i1:i2, j1:j2, km+1), INTENT(OUT) :: q1e, q2e
3484 !-----------------------------------------------------------------------
3485 ! edge values
3486  REAL, DIMENSION(i1:i2, km+1) :: qe1, qe2, gam
3487  REAL :: gak(km)
3488  REAL :: bet, r2o3, r4o3
3489  REAL :: g0, gk, xt1, xt2, a_bot
3490  INTEGER :: i, k
3491  IF (uniform_grid) THEN
3492 !------------------------------------------------
3493 ! Optimized coding for uniform grid: SJL Apr 2007
3494 !------------------------------------------------
3495  r2o3 = 2./3.
3496  r4o3 = 4./3.
3497  DO i=i1,i2
3498  qe1(i, 1) = r4o3*q1(i, j, 1) + r2o3*q1(i, j, 2)
3499  qe2(i, 1) = r4o3*q2(i, j, 1) + r2o3*q2(i, j, 2)
3500  END DO
3501  gak(1) = 7./3.
3502  DO k=2,km
3503  gak(k) = 1./(4.-gak(k-1))
3504  DO i=i1,i2
3505  qe1(i, k) = (3.*(q1(i, j, k-1)+q1(i, j, k))-qe1(i, k-1))*gak(k&
3506 & )
3507  qe2(i, k) = (3.*(q2(i, j, k-1)+q2(i, j, k))-qe2(i, k-1))*gak(k&
3508 & )
3509  END DO
3510  END DO
3511  bet = 1./(1.5-3.5*gak(km))
3512  DO i=i1,i2
3513  qe1(i, km+1) = (4.*q1(i, j, km)+q1(i, j, km-1)-3.5*qe1(i, km))*&
3514 & bet
3515  qe2(i, km+1) = (4.*q2(i, j, km)+q2(i, j, km-1)-3.5*qe2(i, km))*&
3516 & bet
3517  END DO
3518  DO k=km,1,-1
3519  DO i=i1,i2
3520  qe1(i, k) = qe1(i, k) - gak(k)*qe1(i, k+1)
3521  qe2(i, k) = qe2(i, k) - gak(k)*qe2(i, k+1)
3522  END DO
3523  END DO
3524  ELSE
3525 ! Assuming grid varying in vertical only
3526  g0 = dp0(2)/dp0(1)
3527  xt1 = 2.*g0*(g0+1.)
3528  bet = g0*(g0+0.5)
3529  DO i=i1,i2
3530  qe1(i, 1) = (xt1*q1(i, j, 1)+q1(i, j, 2))/bet
3531  qe2(i, 1) = (xt1*q2(i, j, 1)+q2(i, j, 2))/bet
3532  gam(i, 1) = (1.+g0*(g0+1.5))/bet
3533  END DO
3534  DO k=2,km
3535  gk = dp0(k-1)/dp0(k)
3536  DO i=i1,i2
3537  bet = 2. + 2.*gk - gam(i, k-1)
3538  qe1(i, k) = (3.*(q1(i, j, k-1)+gk*q1(i, j, k))-qe1(i, k-1))/&
3539 & bet
3540  qe2(i, k) = (3.*(q2(i, j, k-1)+gk*q2(i, j, k))-qe2(i, k-1))/&
3541 & bet
3542  gam(i, k) = gk/bet
3543  END DO
3544  END DO
3545  a_bot = 1. + gk*(gk+1.5)
3546  xt1 = 2.*gk*(gk+1.)
3547  DO i=i1,i2
3548  xt2 = gk*(gk+0.5) - a_bot*gam(i, km)
3549  qe1(i, km+1) = (xt1*q1(i, j, km)+q1(i, j, km-1)-a_bot*qe1(i, km)&
3550 & )/xt2
3551  qe2(i, km+1) = (xt1*q2(i, j, km)+q2(i, j, km-1)-a_bot*qe2(i, km)&
3552 & )/xt2
3553  END DO
3554  DO k=km,1,-1
3555  DO i=i1,i2
3556  qe1(i, k) = qe1(i, k) - gam(i, k)*qe1(i, k+1)
3557  qe2(i, k) = qe2(i, k) - gam(i, k)*qe2(i, k+1)
3558  END DO
3559  END DO
3560  END IF
3561 !------------------
3562 ! Apply constraints
3563 !------------------
3564  IF (limiter .NE. 0) THEN
3565 ! limit the top & bottom winds
3566  DO i=i1,i2
3567 ! Top
3568  IF (q1(i, j, 1)*qe1(i, 1) .LT. 0.) qe1(i, 1) = 0.
3569  IF (q2(i, j, 1)*qe2(i, 1) .LT. 0.) qe2(i, 1) = 0.
3570 ! Surface:
3571  IF (q1(i, j, km)*qe1(i, km+1) .LT. 0.) qe1(i, km+1) = 0.
3572  IF (q2(i, j, km)*qe2(i, km+1) .LT. 0.) qe2(i, km+1) = 0.
3573  END DO
3574  END IF
3575  DO k=1,km+1
3576  DO i=i1,i2
3577  q1e(i, j, k) = qe1(i, k)
3578  q2e(i, j, k) = qe2(i, k)
3579  END DO
3580  END DO
3581  END SUBROUTINE edge_profile
3582 ! Differentiation of nest_halo_nh in forward (tangent) mode:
3583 ! variations of useful results: pk3 gz pkc
3584 ! with respect to varying inputs: pk3 gz delp delz pkc pt
3585  SUBROUTINE nest_halo_nh_tlm(ptop, grav, kappa, cp, delp, delp_tl, delz&
3586 & , delz_tl, pt, pt_tl, phis, pkc, pkc_tl, gz, gz_tl, pk3, pk3_tl, npx&
3587 & , npy, npz, nested, pkc_pertn, computepk3, fullhalo, bd)
3588  IMPLICIT NONE
3589 !INPUT: delp, delz, pt
3590 !OUTPUT: gz, pkc, pk3 (optional)
3591  INTEGER, INTENT(IN) :: npx, npy, npz
3592  LOGICAL, INTENT(IN) :: pkc_pertn, computepk3, fullhalo, nested
3593  REAL, INTENT(IN) :: ptop, kappa, cp, grav
3594  TYPE(fv_grid_bounds_type), INTENT(IN) :: bd
3595  REAL, INTENT(IN) :: phis(bd%isd:bd%ied, bd%jsd:bd%jed)
3596  REAL, DIMENSION(bd%isd:bd%ied, bd%jsd:bd%jed, npz), INTENT(IN) :: pt&
3597 & , delp, delz
3598  REAL, DIMENSION(bd%isd:bd%ied, bd%jsd:bd%jed, npz), INTENT(IN) :: &
3599 & pt_tl, delp_tl, delz_tl
3600  REAL, DIMENSION(bd%isd:bd%ied, bd%jsd:bd%jed, npz+1), INTENT(INOUT) &
3601 & :: gz, pkc, pk3
3602  REAL, DIMENSION(bd%isd:bd%ied, bd%jsd:bd%jed, npz+1), INTENT(INOUT) &
3603 & :: gz_tl, pkc_tl, pk3_tl
3604  INTEGER :: i, j, k
3605 !'gamma'
3606  REAL :: gama
3607  REAL :: ptk, rgrav, rkap, peln1, rdg
3608  REAL, DIMENSION(bd%isd:bd%ied, npz+1, bd%jsd:bd%jed) :: pe, peln
3609  REAL, DIMENSION(bd%isd:bd%ied, npz+1, bd%jsd:bd%jed) :: pe_tl, &
3610 & peln_tl
3611  REAL, DIMENSION(bd%isd:bd%ied, npz) :: gam, bb, dd, pkz
3612  REAL, DIMENSION(bd%isd:bd%ied, npz) :: gam_tl, bb_tl, dd_tl, pkz_tl
3613  REAL, DIMENSION(bd%isd:bd%ied, npz-1) :: g_rat
3614  REAL, DIMENSION(bd%isd:bd%ied, npz-1) :: g_rat_tl
3615  REAL, DIMENSION(bd%isd:bd%ied) :: bet
3616  REAL, DIMENSION(bd%isd:bd%ied) :: bet_tl
3617  REAL :: pm
3618  REAL :: pm_tl
3619  INTEGER :: ifirst, ilast, jfirst, jlast
3620  INTEGER :: is, ie, js, je
3621  INTEGER :: isd, ied, jsd, jed
3622  INTRINSIC log
3623  INTRINSIC exp
3624  REAL :: arg1
3625  REAL :: arg1_tl
3626  REAL :: arg2
3627  REAL :: arg2_tl
3628  is = bd%is
3629  ie = bd%ie
3630  js = bd%js
3631  je = bd%je
3632  isd = bd%isd
3633  ied = bd%ied
3634  jsd = bd%jsd
3635  jed = bd%jed
3636  IF (.NOT.nested) THEN
3637  RETURN
3638  ELSE
3639  ifirst = isd
3640  jfirst = jsd
3641  ilast = ied
3642  jlast = jed
3643 !Remember we want to compute these in the HALO. Note also this routine
3644 !requires an appropriate
3645  rgrav = 1./grav
3646  gama = 1./(1.-kappa)
3647  ptk = ptop**kappa
3648  rkap = 1./kappa
3649  peln1 = log(ptop)
3650  rdg = -(rdgas*rgrav)
3651 !NOTE: Compiler does NOT like this sort of nested-grid BC code. Is it trying to do some ugly optimization?
3652  IF (is .EQ. 1) THEN
3653  dd_tl = 0.0
3654  peln_tl = 0.0
3655  bet_tl = 0.0
3656  bb_tl = 0.0
3657  pkz_tl = 0.0
3658  pe_tl = 0.0
3659  g_rat_tl = 0.0
3660  gam_tl = 0.0
3661  DO j=jfirst,jlast
3662 !GZ
3663  DO i=ifirst,0
3664  gz_tl(i, j, npz+1) = 0.0
3665  gz(i, j, npz+1) = phis(i, j)
3666  END DO
3667  DO k=npz,1,-1
3668  DO i=ifirst,0
3669  gz_tl(i, j, k) = gz_tl(i, j, k+1) - grav*delz_tl(i, j, k)
3670  gz(i, j, k) = gz(i, j, k+1) - delz(i, j, k)*grav
3671  END DO
3672  END DO
3673 !Hydrostatic interface pressure
3674  DO i=ifirst,0
3675  pe_tl(i, 1, j) = 0.0
3676  pe(i, 1, j) = ptop
3677  peln_tl(i, 1, j) = 0.0
3678  peln(i, 1, j) = peln1
3679  END DO
3680  DO k=2,npz+1
3681  DO i=ifirst,0
3682  pe_tl(i, k, j) = pe_tl(i, k-1, j) + delp_tl(i, j, k-1)
3683  pe(i, k, j) = pe(i, k-1, j) + delp(i, j, k-1)
3684  peln_tl(i, k, j) = pe_tl(i, k, j)/pe(i, k, j)
3685  peln(i, k, j) = log(pe(i, k, j))
3686  END DO
3687  END DO
3688 !Perturbation nonhydro layer-mean pressure (NOT to the kappa)
3689  DO k=1,npz
3690  DO i=ifirst,0
3691 !Full p
3692  arg1_tl = -(rdgas*((rgrav*delp_tl(i, j, k)*delz(i, j, k)-&
3693 & delp(i, j, k)*rgrav*delz_tl(i, j, k))*pt(i, j, k)/delz(i&
3694 & , j, k)**2+delp(i, j, k)*rgrav*pt_tl(i, j, k)/delz(i, j&
3695 & , k)))
3696  arg1 = -(delp(i, j, k)*rgrav/delz(i, j, k)*rdgas*pt(i, j, &
3697 & k))
3698  arg2_tl = gama*arg1_tl/arg1
3699  arg2 = gama*log(arg1)
3700  pkz_tl(i, k) = arg2_tl*exp(arg2)
3701  pkz(i, k) = exp(arg2)
3702 !hydro
3703  pm_tl = (delp_tl(i, j, k)*(peln(i, k+1, j)-peln(i, k, j))-&
3704 & delp(i, j, k)*(peln_tl(i, k+1, j)-peln_tl(i, k, j)))/(&
3705 & peln(i, k+1, j)-peln(i, k, j))**2
3706  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
3707 !Remove hydro cell-mean pressure
3708  pkz_tl(i, k) = pkz_tl(i, k) - pm_tl
3709  pkz(i, k) = pkz(i, k) - pm
3710  END DO
3711  END DO
3712 !pressure solver
3713  DO k=1,npz-1
3714  DO i=ifirst,0
3715  g_rat_tl(i, k) = (delp_tl(i, j, k)*delp(i, j, k+1)-delp(i&
3716 & , j, k)*delp_tl(i, j, k+1))/delp(i, j, k+1)**2
3717  g_rat(i, k) = delp(i, j, k)/delp(i, j, k+1)
3718  bb_tl(i, k) = 2.*g_rat_tl(i, k)
3719  bb(i, k) = 2.*(1.+g_rat(i, k))
3720  dd_tl(i, k) = 3.*(pkz_tl(i, k)+g_rat_tl(i, k)*pkz(i, k+1)+&
3721 & g_rat(i, k)*pkz_tl(i, k+1))
3722  dd(i, k) = 3.*(pkz(i, k)+g_rat(i, k)*pkz(i, k+1))
3723  END DO
3724  END DO
3725  DO i=ifirst,0
3726  bet_tl(i) = bb_tl(i, 1)
3727  bet(i) = bb(i, 1)
3728  pkc_tl(i, j, 1) = 0.0
3729  pkc(i, j, 1) = 0.
3730  pkc_tl(i, j, 2) = (dd_tl(i, 1)*bet(i)-dd(i, 1)*bet_tl(i))/&
3731 & bet(i)**2
3732  pkc(i, j, 2) = dd(i, 1)/bet(i)
3733  bb_tl(i, npz) = 0.0
3734  bb(i, npz) = 2.
3735  dd_tl(i, npz) = 3.*pkz_tl(i, npz)
3736  dd(i, npz) = 3.*pkz(i, npz)
3737  END DO
3738  DO k=2,npz
3739  DO i=ifirst,0
3740  gam_tl(i, k) = (g_rat_tl(i, k-1)*bet(i)-g_rat(i, k-1)*&
3741 & bet_tl(i))/bet(i)**2
3742  gam(i, k) = g_rat(i, k-1)/bet(i)
3743  bet_tl(i) = bb_tl(i, k) - gam_tl(i, k)
3744  bet(i) = bb(i, k) - gam(i, k)
3745  pkc_tl(i, j, k+1) = ((dd_tl(i, k)-pkc_tl(i, j, k))*bet(i)-&
3746 & (dd(i, k)-pkc(i, j, k))*bet_tl(i))/bet(i)**2
3747  pkc(i, j, k+1) = (dd(i, k)-pkc(i, j, k))/bet(i)
3748  END DO
3749  END DO
3750  DO k=npz,2,-1
3751  DO i=ifirst,0
3752  pkc_tl(i, j, k) = pkc_tl(i, j, k) - gam_tl(i, k)*pkc(i, j&
3753 & , k+1) - gam(i, k)*pkc_tl(i, j, k+1)
3754  pkc(i, j, k) = pkc(i, j, k) - gam(i, k)*pkc(i, j, k+1)
3755  END DO
3756  END DO
3757  END DO
3758  DO j=jfirst,jlast
3759  IF (.NOT.pkc_pertn) THEN
3760  DO k=npz+1,1,-1
3761  DO i=ifirst,0
3762  pkc_tl(i, j, k) = pkc_tl(i, j, k) + pe_tl(i, k, j)
3763  pkc(i, j, k) = pkc(i, j, k) + pe(i, k, j)
3764  END DO
3765  END DO
3766  END IF
3767 !pk3 if necessary; doesn't require condenstate loading calculation
3768  IF (computepk3) THEN
3769  DO i=ifirst,0
3770  pk3_tl(i, j, 1) = 0.0
3771  pk3(i, j, 1) = ptk
3772  END DO
3773  DO k=2,npz+1
3774  DO i=ifirst,0
3775  arg1_tl = kappa*pe_tl(i, k, j)/pe(i, k, j)
3776  arg1 = kappa*log(pe(i, k, j))
3777  pk3_tl(i, j, k) = arg1_tl*exp(arg1)
3778  pk3(i, j, k) = exp(arg1)
3779  END DO
3780  END DO
3781  END IF
3782  END DO
3783  ELSE
3784  dd_tl = 0.0
3785  peln_tl = 0.0
3786  bet_tl = 0.0
3787  bb_tl = 0.0
3788  pkz_tl = 0.0
3789  pe_tl = 0.0
3790  g_rat_tl = 0.0
3791  gam_tl = 0.0
3792  END IF
3793  IF (ie .EQ. npx - 1) THEN
3794  DO j=jfirst,jlast
3795 !GZ
3796  DO i=npx,ilast
3797  gz_tl(i, j, npz+1) = 0.0
3798  gz(i, j, npz+1) = phis(i, j)
3799  END DO
3800  DO k=npz,1,-1
3801  DO i=npx,ilast
3802  gz_tl(i, j, k) = gz_tl(i, j, k+1) - grav*delz_tl(i, j, k)
3803  gz(i, j, k) = gz(i, j, k+1) - delz(i, j, k)*grav
3804  END DO
3805  END DO
3806 !Hydrostatic interface pressure
3807  DO i=npx,ilast
3808  pe_tl(i, 1, j) = 0.0
3809  pe(i, 1, j) = ptop
3810  peln_tl(i, 1, j) = 0.0
3811  peln(i, 1, j) = peln1
3812  END DO
3813  DO k=2,npz+1
3814  DO i=npx,ilast
3815  pe_tl(i, k, j) = pe_tl(i, k-1, j) + delp_tl(i, j, k-1)
3816  pe(i, k, j) = pe(i, k-1, j) + delp(i, j, k-1)
3817  peln_tl(i, k, j) = pe_tl(i, k, j)/pe(i, k, j)
3818  peln(i, k, j) = log(pe(i, k, j))
3819  END DO
3820  END DO
3821 !Perturbation nonhydro layer-mean pressure (NOT to the kappa)
3822  DO k=1,npz
3823  DO i=npx,ilast
3824 !Full p
3825  arg1_tl = -(rdgas*((rgrav*delp_tl(i, j, k)*delz(i, j, k)-&
3826 & delp(i, j, k)*rgrav*delz_tl(i, j, k))*pt(i, j, k)/delz(i&
3827 & , j, k)**2+delp(i, j, k)*rgrav*pt_tl(i, j, k)/delz(i, j&
3828 & , k)))
3829  arg1 = -(delp(i, j, k)*rgrav/delz(i, j, k)*rdgas*pt(i, j, &
3830 & k))
3831  arg2_tl = gama*arg1_tl/arg1
3832  arg2 = gama*log(arg1)
3833  pkz_tl(i, k) = arg2_tl*exp(arg2)
3834  pkz(i, k) = exp(arg2)
3835 !hydro
3836  pm_tl = (delp_tl(i, j, k)*(peln(i, k+1, j)-peln(i, k, j))-&
3837 & delp(i, j, k)*(peln_tl(i, k+1, j)-peln_tl(i, k, j)))/(&
3838 & peln(i, k+1, j)-peln(i, k, j))**2
3839  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
3840 !Remove hydro cell-mean pressure
3841  pkz_tl(i, k) = pkz_tl(i, k) - pm_tl
3842  pkz(i, k) = pkz(i, k) - pm
3843  END DO
3844  END DO
3845 !pressure solver
3846  DO k=1,npz-1
3847  DO i=npx,ilast
3848  g_rat_tl(i, k) = (delp_tl(i, j, k)*delp(i, j, k+1)-delp(i&
3849 & , j, k)*delp_tl(i, j, k+1))/delp(i, j, k+1)**2
3850  g_rat(i, k) = delp(i, j, k)/delp(i, j, k+1)
3851  bb_tl(i, k) = 2.*g_rat_tl(i, k)
3852  bb(i, k) = 2.*(1.+g_rat(i, k))
3853  dd_tl(i, k) = 3.*(pkz_tl(i, k)+g_rat_tl(i, k)*pkz(i, k+1)+&
3854 & g_rat(i, k)*pkz_tl(i, k+1))
3855  dd(i, k) = 3.*(pkz(i, k)+g_rat(i, k)*pkz(i, k+1))
3856  END DO
3857  END DO
3858  DO i=npx,ilast
3859  bet_tl(i) = bb_tl(i, 1)
3860  bet(i) = bb(i, 1)
3861  pkc_tl(i, j, 1) = 0.0
3862  pkc(i, j, 1) = 0.
3863  pkc_tl(i, j, 2) = (dd_tl(i, 1)*bet(i)-dd(i, 1)*bet_tl(i))/&
3864 & bet(i)**2
3865  pkc(i, j, 2) = dd(i, 1)/bet(i)
3866  bb_tl(i, npz) = 0.0
3867  bb(i, npz) = 2.
3868  dd_tl(i, npz) = 3.*pkz_tl(i, npz)
3869  dd(i, npz) = 3.*pkz(i, npz)
3870  END DO
3871  DO k=2,npz
3872  DO i=npx,ilast
3873  gam_tl(i, k) = (g_rat_tl(i, k-1)*bet(i)-g_rat(i, k-1)*&
3874 & bet_tl(i))/bet(i)**2
3875  gam(i, k) = g_rat(i, k-1)/bet(i)
3876  bet_tl(i) = bb_tl(i, k) - gam_tl(i, k)
3877  bet(i) = bb(i, k) - gam(i, k)
3878  pkc_tl(i, j, k+1) = ((dd_tl(i, k)-pkc_tl(i, j, k))*bet(i)-&
3879 & (dd(i, k)-pkc(i, j, k))*bet_tl(i))/bet(i)**2
3880  pkc(i, j, k+1) = (dd(i, k)-pkc(i, j, k))/bet(i)
3881  END DO
3882  END DO
3883  DO k=npz,2,-1
3884  DO i=npx,ilast
3885  pkc_tl(i, j, k) = pkc_tl(i, j, k) - gam_tl(i, k)*pkc(i, j&
3886 & , k+1) - gam(i, k)*pkc_tl(i, j, k+1)
3887  pkc(i, j, k) = pkc(i, j, k) - gam(i, k)*pkc(i, j, k+1)
3888  END DO
3889  END DO
3890  END DO
3891  DO j=jfirst,jlast
3892  IF (.NOT.pkc_pertn) THEN
3893  DO k=npz+1,1,-1
3894  DO i=npx,ilast
3895  pkc_tl(i, j, k) = pkc_tl(i, j, k) + pe_tl(i, k, j)
3896  pkc(i, j, k) = pkc(i, j, k) + pe(i, k, j)
3897  END DO
3898  END DO
3899  END IF
3900 !pk3 if necessary
3901  IF (computepk3) THEN
3902  DO i=npx,ilast
3903  pk3_tl(i, j, 1) = 0.0
3904  pk3(i, j, 1) = ptk
3905  END DO
3906  DO k=2,npz+1
3907  DO i=npx,ilast
3908  arg1_tl = kappa*pe_tl(i, k, j)/pe(i, k, j)
3909  arg1 = kappa*log(pe(i, k, j))
3910  pk3_tl(i, j, k) = arg1_tl*exp(arg1)
3911  pk3(i, j, k) = exp(arg1)
3912  END DO
3913  END DO
3914  END IF
3915  END DO
3916  END IF
3917  IF (js .EQ. 1) THEN
3918  DO j=jfirst,0
3919 !GZ
3920  DO i=ifirst,ilast
3921  gz_tl(i, j, npz+1) = 0.0
3922  gz(i, j, npz+1) = phis(i, j)
3923  END DO
3924  DO k=npz,1,-1
3925  DO i=ifirst,ilast
3926  gz_tl(i, j, k) = gz_tl(i, j, k+1) - grav*delz_tl(i, j, k)
3927  gz(i, j, k) = gz(i, j, k+1) - delz(i, j, k)*grav
3928  END DO
3929  END DO
3930 !Hydrostatic interface pressure
3931  DO i=ifirst,ilast
3932  pe_tl(i, 1, j) = 0.0
3933  pe(i, 1, j) = ptop
3934  peln_tl(i, 1, j) = 0.0
3935  peln(i, 1, j) = peln1
3936  END DO
3937  DO k=2,npz+1
3938  DO i=ifirst,ilast
3939  pe_tl(i, k, j) = pe_tl(i, k-1, j) + delp_tl(i, j, k-1)
3940  pe(i, k, j) = pe(i, k-1, j) + delp(i, j, k-1)
3941  peln_tl(i, k, j) = pe_tl(i, k, j)/pe(i, k, j)
3942  peln(i, k, j) = log(pe(i, k, j))
3943  END DO
3944  END DO
3945 !Perturbation nonhydro layer-mean pressure (NOT to the kappa)
3946  DO k=1,npz
3947  DO i=ifirst,ilast
3948 !Full p
3949  arg1_tl = -(rdgas*((rgrav*delp_tl(i, j, k)*delz(i, j, k)-&
3950 & delp(i, j, k)*rgrav*delz_tl(i, j, k))*pt(i, j, k)/delz(i&
3951 & , j, k)**2+delp(i, j, k)*rgrav*pt_tl(i, j, k)/delz(i, j&
3952 & , k)))
3953  arg1 = -(delp(i, j, k)*rgrav/delz(i, j, k)*rdgas*pt(i, j, &
3954 & k))
3955  arg2_tl = gama*arg1_tl/arg1
3956  arg2 = gama*log(arg1)
3957  pkz_tl(i, k) = arg2_tl*exp(arg2)
3958  pkz(i, k) = exp(arg2)
3959 !hydro
3960  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
3961 !hydro
3962  pm_tl = (delp_tl(i, j, k)*(peln(i, k+1, j)-peln(i, k, j))-&
3963 & delp(i, j, k)*(peln_tl(i, k+1, j)-peln_tl(i, k, j)))/(&
3964 & peln(i, k+1, j)-peln(i, k, j))**2
3965  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
3966 !Remove hydro cell-mean pressure
3967  pkz_tl(i, k) = pkz_tl(i, k) - pm_tl
3968  pkz(i, k) = pkz(i, k) - pm
3969  END DO
3970  END DO
3971 !pressure solver
3972  DO k=1,npz-1
3973  DO i=ifirst,ilast
3974  g_rat_tl(i, k) = (delp_tl(i, j, k)*delp(i, j, k+1)-delp(i&
3975 & , j, k)*delp_tl(i, j, k+1))/delp(i, j, k+1)**2
3976  g_rat(i, k) = delp(i, j, k)/delp(i, j, k+1)
3977  bb_tl(i, k) = 2.*g_rat_tl(i, k)
3978  bb(i, k) = 2.*(1.+g_rat(i, k))
3979  dd_tl(i, k) = 3.*(pkz_tl(i, k)+g_rat_tl(i, k)*pkz(i, k+1)+&
3980 & g_rat(i, k)*pkz_tl(i, k+1))
3981  dd(i, k) = 3.*(pkz(i, k)+g_rat(i, k)*pkz(i, k+1))
3982  END DO
3983  END DO
3984  DO i=ifirst,ilast
3985  bet_tl(i) = bb_tl(i, 1)
3986  bet(i) = bb(i, 1)
3987  pkc_tl(i, j, 1) = 0.0
3988  pkc(i, j, 1) = 0.
3989  pkc_tl(i, j, 2) = (dd_tl(i, 1)*bet(i)-dd(i, 1)*bet_tl(i))/&
3990 & bet(i)**2
3991  pkc(i, j, 2) = dd(i, 1)/bet(i)
3992  bb_tl(i, npz) = 0.0
3993  bb(i, npz) = 2.
3994  dd_tl(i, npz) = 3.*pkz_tl(i, npz)
3995  dd(i, npz) = 3.*pkz(i, npz)
3996  END DO
3997  DO k=2,npz
3998  DO i=ifirst,ilast
3999  gam_tl(i, k) = (g_rat_tl(i, k-1)*bet(i)-g_rat(i, k-1)*&
4000 & bet_tl(i))/bet(i)**2
4001  gam(i, k) = g_rat(i, k-1)/bet(i)
4002  bet_tl(i) = bb_tl(i, k) - gam_tl(i, k)
4003  bet(i) = bb(i, k) - gam(i, k)
4004  pkc_tl(i, j, k+1) = ((dd_tl(i, k)-pkc_tl(i, j, k))*bet(i)-&
4005 & (dd(i, k)-pkc(i, j, k))*bet_tl(i))/bet(i)**2
4006  pkc(i, j, k+1) = (dd(i, k)-pkc(i, j, k))/bet(i)
4007  END DO
4008  END DO
4009  DO k=npz,2,-1
4010  DO i=ifirst,ilast
4011  pkc_tl(i, j, k) = pkc_tl(i, j, k) - gam_tl(i, k)*pkc(i, j&
4012 & , k+1) - gam(i, k)*pkc_tl(i, j, k+1)
4013  pkc(i, j, k) = pkc(i, j, k) - gam(i, k)*pkc(i, j, k+1)
4014  END DO
4015  END DO
4016  END DO
4017  DO j=jfirst,0
4018  IF (.NOT.pkc_pertn) THEN
4019  DO k=npz+1,1,-1
4020  DO i=ifirst,ilast
4021  pkc_tl(i, j, k) = pkc_tl(i, j, k) + pe_tl(i, k, j)
4022  pkc(i, j, k) = pkc(i, j, k) + pe(i, k, j)
4023  END DO
4024  END DO
4025  END IF
4026 !pk3 if necessary
4027  IF (computepk3) THEN
4028  DO i=ifirst,ilast
4029  pk3_tl(i, j, 1) = 0.0
4030  pk3(i, j, 1) = ptk
4031  END DO
4032  DO k=2,npz+1
4033  DO i=ifirst,ilast
4034  arg1_tl = kappa*pe_tl(i, k, j)/pe(i, k, j)
4035  arg1 = kappa*log(pe(i, k, j))
4036  pk3_tl(i, j, k) = arg1_tl*exp(arg1)
4037  pk3(i, j, k) = exp(arg1)
4038  END DO
4039  END DO
4040  END IF
4041  END DO
4042  END IF
4043  IF (je .EQ. npy - 1) THEN
4044  DO j=npy,jlast
4045 !GZ
4046  DO i=ifirst,ilast
4047  gz_tl(i, j, npz+1) = 0.0
4048  gz(i, j, npz+1) = phis(i, j)
4049  END DO
4050  DO k=npz,1,-1
4051  DO i=ifirst,ilast
4052  gz_tl(i, j, k) = gz_tl(i, j, k+1) - grav*delz_tl(i, j, k)
4053  gz(i, j, k) = gz(i, j, k+1) - delz(i, j, k)*grav
4054  END DO
4055  END DO
4056 !Hydrostatic interface pressure
4057  DO i=ifirst,ilast
4058  pe_tl(i, 1, j) = 0.0
4059  pe(i, 1, j) = ptop
4060  peln_tl(i, 1, j) = 0.0
4061  peln(i, 1, j) = peln1
4062  END DO
4063  DO k=2,npz+1
4064  DO i=ifirst,ilast
4065  pe_tl(i, k, j) = pe_tl(i, k-1, j) + delp_tl(i, j, k-1)
4066  pe(i, k, j) = pe(i, k-1, j) + delp(i, j, k-1)
4067  peln_tl(i, k, j) = pe_tl(i, k, j)/pe(i, k, j)
4068  peln(i, k, j) = log(pe(i, k, j))
4069  END DO
4070  END DO
4071 !Perturbation nonhydro layer-mean pressure (NOT to the kappa)
4072  DO k=1,npz
4073  DO i=ifirst,ilast
4074 !Full p
4075  arg1_tl = -(rdgas*((rgrav*delp_tl(i, j, k)*delz(i, j, k)-&
4076 & delp(i, j, k)*rgrav*delz_tl(i, j, k))*pt(i, j, k)/delz(i&
4077 & , j, k)**2+delp(i, j, k)*rgrav*pt_tl(i, j, k)/delz(i, j&
4078 & , k)))
4079  arg1 = -(delp(i, j, k)*rgrav/delz(i, j, k)*rdgas*pt(i, j, &
4080 & k))
4081  arg2_tl = gama*arg1_tl/arg1
4082  arg2 = gama*log(arg1)
4083  pkz_tl(i, k) = arg2_tl*exp(arg2)
4084  pkz(i, k) = exp(arg2)
4085 !hydro
4086  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
4087 !hydro
4088  pm_tl = (delp_tl(i, j, k)*(peln(i, k+1, j)-peln(i, k, j))-&
4089 & delp(i, j, k)*(peln_tl(i, k+1, j)-peln_tl(i, k, j)))/(&
4090 & peln(i, k+1, j)-peln(i, k, j))**2
4091  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
4092 !Remove hydro cell-mean pressure
4093  pkz_tl(i, k) = pkz_tl(i, k) - pm_tl
4094  pkz(i, k) = pkz(i, k) - pm
4095  END DO
4096  END DO
4097 !Reversible interpolation on layer NH pressure perturbation
4098 ! to recover lastge NH pressure perturbation
4099  DO k=1,npz-1
4100  DO i=ifirst,ilast
4101  g_rat_tl(i, k) = (delp_tl(i, j, k)*delp(i, j, k+1)-delp(i&
4102 & , j, k)*delp_tl(i, j, k+1))/delp(i, j, k+1)**2
4103  g_rat(i, k) = delp(i, j, k)/delp(i, j, k+1)
4104  bb_tl(i, k) = 2.*g_rat_tl(i, k)
4105  bb(i, k) = 2.*(1.+g_rat(i, k))
4106  dd_tl(i, k) = 3.*(pkz_tl(i, k)+g_rat_tl(i, k)*pkz(i, k+1)+&
4107 & g_rat(i, k)*pkz_tl(i, k+1))
4108  dd(i, k) = 3.*(pkz(i, k)+g_rat(i, k)*pkz(i, k+1))
4109  END DO
4110  END DO
4111  DO i=ifirst,ilast
4112  bet_tl(i) = bb_tl(i, 1)
4113  bet(i) = bb(i, 1)
4114  pkc_tl(i, j, 1) = 0.0
4115  pkc(i, j, 1) = 0.
4116  pkc_tl(i, j, 2) = (dd_tl(i, 1)*bet(i)-dd(i, 1)*bet_tl(i))/&
4117 & bet(i)**2
4118  pkc(i, j, 2) = dd(i, 1)/bet(i)
4119  bb_tl(i, npz) = 0.0
4120  bb(i, npz) = 2.
4121  dd_tl(i, npz) = 3.*pkz_tl(i, npz)
4122  dd(i, npz) = 3.*pkz(i, npz)
4123  END DO
4124  DO k=2,npz
4125  DO i=ifirst,ilast
4126  gam_tl(i, k) = (g_rat_tl(i, k-1)*bet(i)-g_rat(i, k-1)*&
4127 & bet_tl(i))/bet(i)**2
4128  gam(i, k) = g_rat(i, k-1)/bet(i)
4129  bet_tl(i) = bb_tl(i, k) - gam_tl(i, k)
4130  bet(i) = bb(i, k) - gam(i, k)
4131  pkc_tl(i, j, k+1) = ((dd_tl(i, k)-pkc_tl(i, j, k))*bet(i)-&
4132 & (dd(i, k)-pkc(i, j, k))*bet_tl(i))/bet(i)**2
4133  pkc(i, j, k+1) = (dd(i, k)-pkc(i, j, k))/bet(i)
4134  END DO
4135  END DO
4136  DO k=npz,2,-1
4137  DO i=ifirst,ilast
4138  pkc_tl(i, j, k) = pkc_tl(i, j, k) - gam_tl(i, k)*pkc(i, j&
4139 & , k+1) - gam(i, k)*pkc_tl(i, j, k+1)
4140  pkc(i, j, k) = pkc(i, j, k) - gam(i, k)*pkc(i, j, k+1)
4141  END DO
4142  END DO
4143  END DO
4144  DO j=npy,jlast
4145  IF (.NOT.pkc_pertn) THEN
4146  DO k=npz+1,1,-1
4147  DO i=ifirst,ilast
4148  pkc_tl(i, j, k) = pkc_tl(i, j, k) + pe_tl(i, k, j)
4149  pkc(i, j, k) = pkc(i, j, k) + pe(i, k, j)
4150  END DO
4151  END DO
4152  END IF
4153 !pk3 if necessary
4154  IF (computepk3) THEN
4155  DO i=ifirst,ilast
4156  pk3_tl(i, j, 1) = 0.0
4157  pk3(i, j, 1) = ptk
4158  END DO
4159  DO k=2,npz+1
4160  DO i=ifirst,ilast
4161  arg1_tl = kappa*pe_tl(i, k, j)/pe(i, k, j)
4162  arg1 = kappa*log(pe(i, k, j))
4163  pk3_tl(i, j, k) = arg1_tl*exp(arg1)
4164  pk3(i, j, k) = exp(arg1)
4165  END DO
4166  END DO
4167  END IF
4168  END DO
4169  END IF
4170  END IF
4171  END SUBROUTINE nest_halo_nh_tlm
4172  SUBROUTINE nest_halo_nh(ptop, grav, kappa, cp, delp, delz, pt, phis, &
4173 & pkc, gz, pk3, npx, npy, npz, nested, pkc_pertn, computepk3, fullhalo&
4174 & , bd)
4175  IMPLICIT NONE
4176 !INPUT: delp, delz, pt
4177 !OUTPUT: gz, pkc, pk3 (optional)
4178  INTEGER, INTENT(IN) :: npx, npy, npz
4179  LOGICAL, INTENT(IN) :: pkc_pertn, computepk3, fullhalo, nested
4180  REAL, INTENT(IN) :: ptop, kappa, cp, grav
4181  TYPE(fv_grid_bounds_type), INTENT(IN) :: bd
4182  REAL, INTENT(IN) :: phis(bd%isd:bd%ied, bd%jsd:bd%jed)
4183  REAL, DIMENSION(bd%isd:bd%ied, bd%jsd:bd%jed, npz), INTENT(IN) :: pt&
4184 & , delp, delz
4185  REAL, DIMENSION(bd%isd:bd%ied, bd%jsd:bd%jed, npz+1), INTENT(INOUT) &
4186 & :: gz, pkc, pk3
4187  INTEGER :: i, j, k
4188 !'gamma'
4189  REAL :: gama
4190  REAL :: ptk, rgrav, rkap, peln1, rdg
4191  REAL, DIMENSION(bd%isd:bd%ied, npz+1, bd%jsd:bd%jed) :: pe, peln
4192  REAL, DIMENSION(bd%isd:bd%ied, npz) :: gam, bb, dd, pkz
4193  REAL, DIMENSION(bd%isd:bd%ied, npz-1) :: g_rat
4194  REAL, DIMENSION(bd%isd:bd%ied) :: bet
4195  REAL :: pm
4196  INTEGER :: ifirst, ilast, jfirst, jlast
4197  INTEGER :: is, ie, js, je
4198  INTEGER :: isd, ied, jsd, jed
4199  INTRINSIC log
4200  INTRINSIC exp
4201  REAL :: arg1
4202  REAL :: arg2
4203  is = bd%is
4204  ie = bd%ie
4205  js = bd%js
4206  je = bd%je
4207  isd = bd%isd
4208  ied = bd%ied
4209  jsd = bd%jsd
4210  jed = bd%jed
4211  IF (.NOT.nested) THEN
4212  RETURN
4213  ELSE
4214  ifirst = isd
4215  jfirst = jsd
4216  ilast = ied
4217  jlast = jed
4218 !Remember we want to compute these in the HALO. Note also this routine
4219 !requires an appropriate
4220  rgrav = 1./grav
4221  gama = 1./(1.-kappa)
4222  ptk = ptop**kappa
4223  rkap = 1./kappa
4224  peln1 = log(ptop)
4225  rdg = -(rdgas*rgrav)
4226 !NOTE: Compiler does NOT like this sort of nested-grid BC code. Is it trying to do some ugly optimization?
4227  IF (is .EQ. 1) THEN
4228  DO j=jfirst,jlast
4229 !GZ
4230  DO i=ifirst,0
4231  gz(i, j, npz+1) = phis(i, j)
4232  END DO
4233  DO k=npz,1,-1
4234  DO i=ifirst,0
4235  gz(i, j, k) = gz(i, j, k+1) - delz(i, j, k)*grav
4236  END DO
4237  END DO
4238 !Hydrostatic interface pressure
4239  DO i=ifirst,0
4240  pe(i, 1, j) = ptop
4241  peln(i, 1, j) = peln1
4242  END DO
4243  DO k=2,npz+1
4244  DO i=ifirst,0
4245  pe(i, k, j) = pe(i, k-1, j) + delp(i, j, k-1)
4246  peln(i, k, j) = log(pe(i, k, j))
4247  END DO
4248  END DO
4249 !Perturbation nonhydro layer-mean pressure (NOT to the kappa)
4250  DO k=1,npz
4251  DO i=ifirst,0
4252 !Full p
4253  arg1 = -(delp(i, j, k)*rgrav/delz(i, j, k)*rdgas*pt(i, j, &
4254 & k))
4255  arg2 = gama*log(arg1)
4256  pkz(i, k) = exp(arg2)
4257 !hydro
4258  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
4259 !Remove hydro cell-mean pressure
4260  pkz(i, k) = pkz(i, k) - pm
4261  END DO
4262  END DO
4263 !pressure solver
4264  DO k=1,npz-1
4265  DO i=ifirst,0
4266  g_rat(i, k) = delp(i, j, k)/delp(i, j, k+1)
4267  bb(i, k) = 2.*(1.+g_rat(i, k))
4268  dd(i, k) = 3.*(pkz(i, k)+g_rat(i, k)*pkz(i, k+1))
4269  END DO
4270  END DO
4271  DO i=ifirst,0
4272  bet(i) = bb(i, 1)
4273  pkc(i, j, 1) = 0.
4274  pkc(i, j, 2) = dd(i, 1)/bet(i)
4275  bb(i, npz) = 2.
4276  dd(i, npz) = 3.*pkz(i, npz)
4277  END DO
4278  DO k=2,npz
4279  DO i=ifirst,0
4280  gam(i, k) = g_rat(i, k-1)/bet(i)
4281  bet(i) = bb(i, k) - gam(i, k)
4282  pkc(i, j, k+1) = (dd(i, k)-pkc(i, j, k))/bet(i)
4283  END DO
4284  END DO
4285  DO k=npz,2,-1
4286  DO i=ifirst,0
4287  pkc(i, j, k) = pkc(i, j, k) - gam(i, k)*pkc(i, j, k+1)
4288  END DO
4289  END DO
4290  END DO
4291  DO j=jfirst,jlast
4292  IF (.NOT.pkc_pertn) THEN
4293  DO k=npz+1,1,-1
4294  DO i=ifirst,0
4295  pkc(i, j, k) = pkc(i, j, k) + pe(i, k, j)
4296  END DO
4297  END DO
4298  END IF
4299 !pk3 if necessary; doesn't require condenstate loading calculation
4300  IF (computepk3) THEN
4301  DO i=ifirst,0
4302  pk3(i, j, 1) = ptk
4303  END DO
4304  DO k=2,npz+1
4305  DO i=ifirst,0
4306  arg1 = kappa*log(pe(i, k, j))
4307  pk3(i, j, k) = exp(arg1)
4308  END DO
4309  END DO
4310  END IF
4311  END DO
4312  END IF
4313  IF (ie .EQ. npx - 1) THEN
4314  DO j=jfirst,jlast
4315 !GZ
4316  DO i=npx,ilast
4317  gz(i, j, npz+1) = phis(i, j)
4318  END DO
4319  DO k=npz,1,-1
4320  DO i=npx,ilast
4321  gz(i, j, k) = gz(i, j, k+1) - delz(i, j, k)*grav
4322  END DO
4323  END DO
4324 !Hydrostatic interface pressure
4325  DO i=npx,ilast
4326  pe(i, 1, j) = ptop
4327  peln(i, 1, j) = peln1
4328  END DO
4329  DO k=2,npz+1
4330  DO i=npx,ilast
4331  pe(i, k, j) = pe(i, k-1, j) + delp(i, j, k-1)
4332  peln(i, k, j) = log(pe(i, k, j))
4333  END DO
4334  END DO
4335 !Perturbation nonhydro layer-mean pressure (NOT to the kappa)
4336  DO k=1,npz
4337  DO i=npx,ilast
4338 !Full p
4339  arg1 = -(delp(i, j, k)*rgrav/delz(i, j, k)*rdgas*pt(i, j, &
4340 & k))
4341  arg2 = gama*log(arg1)
4342  pkz(i, k) = exp(arg2)
4343 !hydro
4344  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
4345 !Remove hydro cell-mean pressure
4346  pkz(i, k) = pkz(i, k) - pm
4347  END DO
4348  END DO
4349 !pressure solver
4350  DO k=1,npz-1
4351  DO i=npx,ilast
4352  g_rat(i, k) = delp(i, j, k)/delp(i, j, k+1)
4353  bb(i, k) = 2.*(1.+g_rat(i, k))
4354  dd(i, k) = 3.*(pkz(i, k)+g_rat(i, k)*pkz(i, k+1))
4355  END DO
4356  END DO
4357  DO i=npx,ilast
4358  bet(i) = bb(i, 1)
4359  pkc(i, j, 1) = 0.
4360  pkc(i, j, 2) = dd(i, 1)/bet(i)
4361  bb(i, npz) = 2.
4362  dd(i, npz) = 3.*pkz(i, npz)
4363  END DO
4364  DO k=2,npz
4365  DO i=npx,ilast
4366  gam(i, k) = g_rat(i, k-1)/bet(i)
4367  bet(i) = bb(i, k) - gam(i, k)
4368  pkc(i, j, k+1) = (dd(i, k)-pkc(i, j, k))/bet(i)
4369  END DO
4370  END DO
4371  DO k=npz,2,-1
4372  DO i=npx,ilast
4373  pkc(i, j, k) = pkc(i, j, k) - gam(i, k)*pkc(i, j, k+1)
4374  END DO
4375  END DO
4376  END DO
4377  DO j=jfirst,jlast
4378  IF (.NOT.pkc_pertn) THEN
4379  DO k=npz+1,1,-1
4380  DO i=npx,ilast
4381  pkc(i, j, k) = pkc(i, j, k) + pe(i, k, j)
4382  END DO
4383  END DO
4384  END IF
4385 !pk3 if necessary
4386  IF (computepk3) THEN
4387  DO i=npx,ilast
4388  pk3(i, j, 1) = ptk
4389  END DO
4390  DO k=2,npz+1
4391  DO i=npx,ilast
4392  arg1 = kappa*log(pe(i, k, j))
4393  pk3(i, j, k) = exp(arg1)
4394  END DO
4395  END DO
4396  END IF
4397  END DO
4398  END IF
4399  IF (js .EQ. 1) THEN
4400  DO j=jfirst,0
4401 !GZ
4402  DO i=ifirst,ilast
4403  gz(i, j, npz+1) = phis(i, j)
4404  END DO
4405  DO k=npz,1,-1
4406  DO i=ifirst,ilast
4407  gz(i, j, k) = gz(i, j, k+1) - delz(i, j, k)*grav
4408  END DO
4409  END DO
4410 !Hydrostatic interface pressure
4411  DO i=ifirst,ilast
4412  pe(i, 1, j) = ptop
4413  peln(i, 1, j) = peln1
4414  END DO
4415  DO k=2,npz+1
4416  DO i=ifirst,ilast
4417  pe(i, k, j) = pe(i, k-1, j) + delp(i, j, k-1)
4418  peln(i, k, j) = log(pe(i, k, j))
4419  END DO
4420  END DO
4421 !Perturbation nonhydro layer-mean pressure (NOT to the kappa)
4422  DO k=1,npz
4423  DO i=ifirst,ilast
4424 !Full p
4425  arg1 = -(delp(i, j, k)*rgrav/delz(i, j, k)*rdgas*pt(i, j, &
4426 & k))
4427  arg2 = gama*log(arg1)
4428  pkz(i, k) = exp(arg2)
4429 !hydro
4430  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
4431 !hydro
4432  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
4433 !Remove hydro cell-mean pressure
4434  pkz(i, k) = pkz(i, k) - pm
4435  END DO
4436  END DO
4437 !pressure solver
4438  DO k=1,npz-1
4439  DO i=ifirst,ilast
4440  g_rat(i, k) = delp(i, j, k)/delp(i, j, k+1)
4441  bb(i, k) = 2.*(1.+g_rat(i, k))
4442  dd(i, k) = 3.*(pkz(i, k)+g_rat(i, k)*pkz(i, k+1))
4443  END DO
4444  END DO
4445  DO i=ifirst,ilast
4446  bet(i) = bb(i, 1)
4447  pkc(i, j, 1) = 0.
4448  pkc(i, j, 2) = dd(i, 1)/bet(i)
4449  bb(i, npz) = 2.
4450  dd(i, npz) = 3.*pkz(i, npz)
4451  END DO
4452  DO k=2,npz
4453  DO i=ifirst,ilast
4454  gam(i, k) = g_rat(i, k-1)/bet(i)
4455  bet(i) = bb(i, k) - gam(i, k)
4456  pkc(i, j, k+1) = (dd(i, k)-pkc(i, j, k))/bet(i)
4457  END DO
4458  END DO
4459  DO k=npz,2,-1
4460  DO i=ifirst,ilast
4461  pkc(i, j, k) = pkc(i, j, k) - gam(i, k)*pkc(i, j, k+1)
4462  END DO
4463  END DO
4464  END DO
4465  DO j=jfirst,0
4466  IF (.NOT.pkc_pertn) THEN
4467  DO k=npz+1,1,-1
4468  DO i=ifirst,ilast
4469  pkc(i, j, k) = pkc(i, j, k) + pe(i, k, j)
4470  END DO
4471  END DO
4472  END IF
4473 !pk3 if necessary
4474  IF (computepk3) THEN
4475  DO i=ifirst,ilast
4476  pk3(i, j, 1) = ptk
4477  END DO
4478  DO k=2,npz+1
4479  DO i=ifirst,ilast
4480  arg1 = kappa*log(pe(i, k, j))
4481  pk3(i, j, k) = exp(arg1)
4482  END DO
4483  END DO
4484  END IF
4485  END DO
4486  END IF
4487  IF (je .EQ. npy - 1) THEN
4488  DO j=npy,jlast
4489 !GZ
4490  DO i=ifirst,ilast
4491  gz(i, j, npz+1) = phis(i, j)
4492  END DO
4493  DO k=npz,1,-1
4494  DO i=ifirst,ilast
4495  gz(i, j, k) = gz(i, j, k+1) - delz(i, j, k)*grav
4496  END DO
4497  END DO
4498 !Hydrostatic interface pressure
4499  DO i=ifirst,ilast
4500  pe(i, 1, j) = ptop
4501  peln(i, 1, j) = peln1
4502  END DO
4503  DO k=2,npz+1
4504  DO i=ifirst,ilast
4505  pe(i, k, j) = pe(i, k-1, j) + delp(i, j, k-1)
4506  peln(i, k, j) = log(pe(i, k, j))
4507  END DO
4508  END DO
4509 !Perturbation nonhydro layer-mean pressure (NOT to the kappa)
4510  DO k=1,npz
4511  DO i=ifirst,ilast
4512 !Full p
4513  arg1 = -(delp(i, j, k)*rgrav/delz(i, j, k)*rdgas*pt(i, j, &
4514 & k))
4515  arg2 = gama*log(arg1)
4516  pkz(i, k) = exp(arg2)
4517 !hydro
4518  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
4519 !hydro
4520  pm = delp(i, j, k)/(peln(i, k+1, j)-peln(i, k, j))
4521 !Remove hydro cell-mean pressure
4522  pkz(i, k) = pkz(i, k) - pm
4523  END DO
4524  END DO
4525 !Reversible interpolation on layer NH pressure perturbation
4526 ! to recover lastge NH pressure perturbation
4527  DO k=1,npz-1
4528  DO i=ifirst,ilast
4529  g_rat(i, k) = delp(i, j, k)/delp(i, j, k+1)
4530  bb(i, k) = 2.*(1.+g_rat(i, k))
4531  dd(i, k) = 3.*(pkz(i, k)+g_rat(i, k)*pkz(i, k+1))
4532  END DO
4533  END DO
4534  DO i=ifirst,ilast
4535  bet(i) = bb(i, 1)
4536  pkc(i, j, 1) = 0.
4537  pkc(i, j, 2) = dd(i, 1)/bet(i)
4538  bb(i, npz) = 2.
4539  dd(i, npz) = 3.*pkz(i, npz)
4540  END DO
4541  DO k=2,npz
4542  DO i=ifirst,ilast
4543  gam(i, k) = g_rat(i, k-1)/bet(i)
4544  bet(i) = bb(i, k) - gam(i, k)
4545  pkc(i, j, k+1) = (dd(i, k)-pkc(i, j, k))/bet(i)
4546  END DO
4547  END DO
4548  DO k=npz,2,-1
4549  DO i=ifirst,ilast
4550  pkc(i, j, k) = pkc(i, j, k) - gam(i, k)*pkc(i, j, k+1)
4551  END DO
4552  END DO
4553  END DO
4554  DO j=npy,jlast
4555  IF (.NOT.pkc_pertn) THEN
4556  DO k=npz+1,1,-1
4557  DO i=ifirst,ilast
4558  pkc(i, j, k) = pkc(i, j, k) + pe(i, k, j)
4559  END DO
4560  END DO
4561  END IF
4562 !pk3 if necessary
4563  IF (computepk3) THEN
4564  DO i=ifirst,ilast
4565  pk3(i, j, 1) = ptk
4566  END DO
4567  DO k=2,npz+1
4568  DO i=ifirst,ilast
4569  arg1 = kappa*log(pe(i, k, j))
4570  pk3(i, j, k) = exp(arg1)
4571  END DO
4572  END DO
4573  END IF
4574  END DO
4575  END IF
4576  END IF
4577  END SUBROUTINE nest_halo_nh
4578 
4579 end module nh_utils_tlm_mod
subroutine edge_scalar(q1, qe, i1, i2, km, id)
subroutine, public nest_halo_nh_tlm(ptop, grav, kappa, cp, delp, delp_tl, delz, delz_tl, pt, pt_tl, phis, pkc, pkc_tl, gz, gz_tl, pk3, pk3_tl, npx, npy, npz, nested, pkc_pertn, computepk3, fullhalo, bd)
subroutine, public fv_tp_2d_tlm(q, q_tl, crx, crx_tl, cry, cry_tl, npx, npy, hord, fx, fx_tl, fy, fy_tl, xfx, xfx_tl, yfx, yfx_tl, gridstruct, bd, ra_x, ra_x_tl, ra_y, ra_y_tl, mfx, mfx_tl, mfy, mfy_tl, mass, mass_tl, nord, damp_c)
subroutine, public riem_solver_c(ms, dt, is, ie, js, je, km, ng, akap, cappa, cp, ptop, hs, w3, pt, q_con, delp, gz, pef, ws, p_fac, a_imp, scale_m)
subroutine, public sim1_solver_tlm(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe, pe_tl, dm2, dm2_tl, pm2, pm2_tl, pem, pem_tl, w2, w2_tl, dz2, dz2_tl, pt2, pt2_tl, ws, ws_tl, p_fac)
subroutine, public fill_4corners_tlm(q, q_tl, dir, bd, npx, npy, sw_corner, se_corner, ne_corner, nw_corner)
subroutine, public update_dz_d(ndif, damp, hord, is, ie, js, je, km, ng, npx, npy, area, rarea, dp0, zs, zh, crx, cry, xfx, yfx, delz, ws, rdt, gridstruct, bd, hord_pert)
subroutine, public fill_4corners(q, dir, bd, npx, npy, sw_corner, se_corner, ne_corner, nw_corner)
real, parameter, public rdgas
Gas constant for dry air [J/kg/deg].
Definition: constants.F90:77
real, parameter dz_min
subroutine, public sim3_solver(dt, is, ie, km, rgas, gama, kappa, pe2, dm, pem, w2, dz2, pt2, ws, alpha, p_fac, scale_m)
subroutine edge_profile(q1, q2, q1e, q2e, i1, i2, j1, j2, j, km, dp0, uniform_grid, limiter)
subroutine, public sim3p0_solver(dt, is, ie, km, rgas, gama, kappa, pe2, dm, pem, w2, dz2, pt2, ws, p_fac, scale_m)
subroutine, public update_dz_d_tlm(ndif, damp, hord, is, ie, js, je, km, ng, npx, npy, area, rarea, dp0, zs, zh, zh_tl, crx, crx_tl, cry, cry_tl, xfx, xfx_tl, yfx, yfx_tl, delz, ws, ws_tl, rdt, gridstruct, bd, hord_pert)
real, parameter, public cp_air
Specific heat capacity of dry air at constant pressure [J/kg/deg].
Definition: constants.F90:83
subroutine, public update_dz_c(is, ie, js, je, km, ng, dt, dp0, zs, area, ut, vt, gz, ws, npx, npy, sw_corner, se_corner, ne_corner, nw_corner, bd, grid_type)
subroutine, public sim_solver(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe2, dm2, pm2, pem, w2, dz2, pt2, ws, alpha, p_fac, scale_m)
subroutine, public riem_solver_c_tlm(ms, dt, is, ie, js, je, km, ng, akap, cappa, cp, ptop, hs, w3, w3_tl, pt, pt_tl, q_con, delp, delp_tl, gz, gz_tl, pef, pef_tl, ws, ws_tl, p_fac, a_imp, scale_m)
subroutine, public sim3_solver_tlm(dt, is, ie, km, rgas, gama, kappa, pe2, pe2_tl, dm, dm_tl, pem, pem_tl, w2, w2_tl, dz2, dz2_tl, pt2, pt2_tl, ws, ws_tl, alpha, p_fac, scale_m)
real, parameter, public grav
Acceleration due to gravity [m/s^2].
Definition: constants.F90:76
subroutine, public rim_2d_tlm(ms, bdt, is, ie, km, rgas, gama, gm2, pe2, pe2_tl, dm2, dm2_tl, pm2, pm2_tl, w2, w2_tl, dz2, dz2_tl, pt2, pt2_tl, ws, ws_tl, c_core)
subroutine, public del6_vt_flux_tlm(nord, npx, npy, damp, q, q_tl, d2, d2_tl, fx2, fx2_tl, fy2, fy2_tl, gridstruct, bd)
#define max(a, b)
Definition: mosaic_util.h:33
real, parameter r3
subroutine, public fv_tp_2d(q, crx, cry, npx, npy, hord, fx, fy, xfx, yfx, gridstruct, bd, ra_x, ra_y, mfx, mfy, mass, nord, damp_c)
Definition: tp_core_tlm.F90:85
subroutine edge_profile_tlm(q1, q1_tl, q2, q2_tl, q1e, q1e_tl, q2e, q2e_tl, i1, i2, j1, j2, j, km, dp0, uniform_grid, limiter)
subroutine, public del6_vt_flux(nord, npx, npy, damp, q, d2, fx2, fy2, gridstruct, bd)
subroutine, public update_dz_c_tlm(is, ie, js, je, km, ng, dt, dp0, zs, area, ut, ut_tl, vt, vt_tl, gz, gz_tl, ws, ws_tl, npx, npy, sw_corner, se_corner, ne_corner, nw_corner, bd, grid_type)
subroutine, public rim_2d(ms, bdt, is, ie, km, rgas, gama, gm2, pe2, dm2, pm2, w2, dz2, pt2, ws, c_core)
subroutine, public sim_solver_tlm(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe2, pe2_tl, dm2, dm2_tl, pm2, pm2_tl, pem, pem_tl, w2, w2_tl, dz2, dz2_tl, pt2, pt2_tl, ws, ws_tl, alpha, p_fac, scale_m)
Derived type containing the data.
subroutine riem_solver3test(ms, dt, is, ie, js, je, km, ng, isd, ied, jsd, jed, akap, cappa, cp, ptop, zs, q_con, w, delz, pt, delp, zh, pe, ppe, pk3, pk, peln, ws, scale_m, p_fac, a_imp, use_logp, last_call, fp_out)
subroutine imp_diff_w(j, is, ie, js, je, ng, km, cd, delz, ws, w, w3)
subroutine, public sim3p0_solver_tlm(dt, is, ie, km, rgas, gama, kappa, pe2, pe2_tl, dm, dm_tl, pem, pem_tl, w2, w2_tl, dz2, dz2_tl, pt2, pt2_tl, ws, ws_tl, p_fac, scale_m)
subroutine, public nest_halo_nh(ptop, grav, kappa, cp, delp, delz, pt, phis, pkc, gz, pk3, npx, npy, npz, nested, pkc_pertn, computepk3, fullhalo, bd)
subroutine, public sim1_solver(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe, dm2, pm2, pem, w2, dz2, pt2, ws, p_fac)