FV3 Bundle
nh_core_adm.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_adm_mod, only: fv_tp_2d
40 
43 
44  implicit none
45  private
46 
47  public riem_solver3, riem_solver_c, update_dz_c, update_dz_d, nest_halo_nh
48  public riem_solver3_fwd, riem_solver_c_fwd, update_dz_c_fwd, update_dz_d_fwd, nest_halo_nh_fwd
49  public riem_solver3_bwd, riem_solver_c_bwd, update_dz_c_bwd, update_dz_d_bwd, nest_halo_nh_bwd
50  real, parameter:: r3 = 1./3.
51 
52 CONTAINS
53 ! Differentiation of riem_solver3 in reverse (adjoint) mode, forward sweep (with options split(a2b_edge_mod.a2b_ord4 a2b_edge
54 !_mod.a2b_ord2 dyn_core_mod.dyn_core dyn_core_mod.pk3_halo dyn_core_mod.pln_halo dyn_core_mod.pe_halo dyn_core_mod.adv_pe dyn_cor
55 !e_mod.p_grad_c dyn_core_mod.nh_p_grad dyn_core_mod.split_p_grad dyn_core_mod.one_grad_p dyn_core_mod.grad1_p_update dyn_core_mod
56 !.mix_dp dyn_core_mod.geopk dyn_core_mod.del2_cubed dyn_core_mod.Rayleigh_fast fv_dynamics_mod.fv_dynamics fv_dynamics_mod.Raylei
57 !gh_Super fv_dynamics_mod.Rayleigh_Friction fv_dynamics_mod.compute_aam fv_grid_utils_mod.cubed_to_latlon fv_grid_utils_mod.c2l_o
58 !rd4 fv_grid_utils_mod.c2l_ord2 fv_mapz_mod.Lagrangian_to_Eulerian fv_mapz_mod.compute_total_energy fv_mapz_mod.pkez fv_mapz_mod.
59 !remap_z fv_mapz_mod.map_scalar fv_mapz_mod.map1_ppm fv_mapz_mod.mapn_tracer fv_mapz_mod.map1_q2 fv_mapz_mod.remap_2d
60 ! fv_mapz_mod.scalar_profile fv_mapz_mod.cs_profile fv_mapz_mod.cs_limiters fv_mapz_mod.ppm_profile fv_mapz_mod.ppm_limiter
61 !s fv_mapz_mod.steepz fv_mapz_mod.rst_remap fv_mapz_mod.mappm fv_mapz_mod.moist_cv fv_mapz_mod.moist_cp fv_mapz_mod.map1_cubic fv
62 !_restart_mod.d2c_setup fv_tracer2d_mod.tracer_2d_1L fv_tracer2d_mod.tracer_2d fv_tracer2d_mod.tracer_2d_nested fv_sg_mod.fv_subg
63 !rid_z main_mod.compute_pressures main_mod.run nh_core_mod.Riem_Solver3 nh_utils_mod.update_dz_c nh_utils_mod.update_dz_d nh_util
64 !s_mod.Riem_Solver_c nh_utils_mod.Riem_Solver3test nh_utils_mod.imp_diff_w nh_utils_mod.RIM_2D nh_utils_mod.SIM3_solver nh_utils_
65 !mod.SIM3p0_solver nh_utils_mod.SIM1_solver nh_utils_mod.SIM_solver nh_utils_mod.edge_scalar nh_utils_mod.edge_profile nh_utils_m
66 !od.nest_halo_nh sw_core_mod.c_sw sw_core_mod.d_sw sw_core_mod.divergence_corner sw_core_mod.divergence_corner_nest sw_core_mod.
67 !d2a2c_vect sw_core_mod.fill3_4corners sw_core_mod.fill2_4corners sw_core_mod.fill_4corners sw_core_mod.xtp_u sw_core_mod.ytp_
68 !v_fb sw_core_mod.compute_divergence_damping sw_core_mod.smag_corner tp_core_mod.mp_ghost_ew tp_core_mod.fv_tp_2d tp_cor
69 !e_mod.copy_corners tp_core_mod.xppm tp_core_mod.yppm tp_core_mod.deln_flux a2b_edge_mod.extrap_corner fv_grid_uti
70 !ls_mod.great_circle_dist sw_core_mod.edge_interpolate4)):
71 ! gradient of useful results: pk3 ws ppe peln w delp delz
72 ! pe pk zh pt
73 ! with respect to varying inputs: pk3 ws ppe peln w delp delz
74 ! pe pk zh pt
75  SUBROUTINE riem_solver3_fwd(ms, dt, is, ie, js, je, km, ng, isd, ied, &
76 & jsd, jed, akap, cappa, cp, ptop, zs, q_con, w, delz, pt, delp, zh, &
77 & pe, ppe, pk3, pk, peln, ws, scale_m, p_fac, a_imp, use_logp, &
78 & last_call, fp_out)
79  IMPLICIT NONE
80 !--------------------------------------------
81 ! !OUTPUT PARAMETERS
82 ! Ouput: gz: grav*height at edges
83 ! pe: full hydrostatic pressure
84 ! ppe: non-hydrostatic pressure perturbation
85 !--------------------------------------------
86  INTEGER, INTENT(IN) :: ms, is, ie, js, je, km, ng
87  INTEGER, INTENT(IN) :: isd, ied, jsd, jed
88 ! the BIG horizontal Lagrangian time step
89  REAL, INTENT(IN) :: dt
90  REAL, INTENT(IN) :: akap, cp, ptop, p_fac, a_imp, scale_m
91  REAL, INTENT(IN) :: zs(isd:ied, jsd:jed)
92  LOGICAL, INTENT(IN) :: last_call, use_logp, fp_out
93  REAL, INTENT(IN) :: ws(is:ie, js:je)
94  REAL, DIMENSION(isd:, jsd:, :), INTENT(IN) :: q_con, cappa
95  REAL, DIMENSION(isd:ied, jsd:jed, km), INTENT(IN) :: delp, pt
96  REAL, DIMENSION(isd:ied, jsd:jed, km+1), INTENT(INOUT) :: zh
97  REAL, DIMENSION(isd:ied, jsd:jed, km), INTENT(INOUT) :: w
98  REAL, INTENT(INOUT) :: pe(is-1:ie+1, km+1, js-1:je+1)
99 ! ln(pe)
100  REAL :: peln(is:ie, km+1, js:je)
101  REAL, DIMENSION(isd:ied, jsd:jed, km+1) :: ppe
102  REAL :: delz(is-ng:ie+ng, js-ng:je+ng, km)
103  REAL :: pk(is:ie, js:je, km+1)
104  REAL :: pk3(isd:ied, jsd:jed, km+1)
105 ! Local:
106  REAL, DIMENSION(is:ie, km) :: dm, dz2, pm2, w2, gm2, cp2
107  REAL, DIMENSION(is:ie, km+1) :: pem, pe2, peln2, peg, pelng
108  REAL :: gama, rgrav, ptk, peln1
109  INTEGER :: i, j, k
110  INTRINSIC log
111  INTRINSIC exp
112  INTRINSIC abs
113  REAL :: abs0
114 
115  dm = 0.0
116  dz2 = 0.0
117  pm2 = 0.0
118  w2 = 0.0
119  gm2 = 0.0
120  cp2 = 0.0
121  pem = 0.0
122  pe2 = 0.0
123  peln2 = 0.0
124  peg = 0.0
125  pelng = 0.0
126  gama = 0.0
127  rgrav = 0.0
128  ptk = 0.0
129  peln1 = 0.0
130  abs0 = 0.0
131 
132  gama = 1./(1.-akap)
133  rgrav = 1./grav
134  peln1 = log(ptop)
135  ptk = exp(akap*peln1)
136 !$OMP parallel do default(none) shared(is,ie,js,je,km,delp,ptop,peln1,pk3,ptk,akap,rgrav,zh,pt, &
137 !$OMP w,a_imp,dt,gama,ws,p_fac,scale_m,ms,delz,last_call, &
138 !$OMP peln,pk,fp_out,ppe,use_logp,zs,pe,cappa,q_con ) &
139 !$OMP private(cp2, gm2, dm, dz2, pm2, pem, peg, pelng, pe2, peln2, w2)
140  DO j=js,je
141  DO k=1,km
142  DO i=is,ie
143  CALL pushrealarray(dm(i, k))
144  dm(i, k) = delp(i, j, k)
145  END DO
146  END DO
147  DO i=is,ie
148  CALL pushrealarray(pem(i, 1))
149  pem(i, 1) = ptop
150  CALL pushrealarray(peln2(i, 1))
151  peln2(i, 1) = peln1
152  CALL pushrealarray(pk3(i, j, 1))
153  pk3(i, j, 1) = ptk
154  END DO
155  DO k=2,km+1
156  DO i=is,ie
157  CALL pushrealarray(pem(i, k))
158  pem(i, k) = pem(i, k-1) + dm(i, k-1)
159  CALL pushrealarray(peln2(i, k))
160  peln2(i, k) = log(pem(i, k))
161  CALL pushrealarray(pk3(i, j, k))
162  pk3(i, j, k) = exp(akap*peln2(i, k))
163  END DO
164  END DO
165  DO k=1,km
166  DO i=is,ie
167  CALL pushrealarray(pm2(i, k))
168  pm2(i, k) = dm(i, k)/(peln2(i, k+1)-peln2(i, k))
169  CALL pushrealarray(dm(i, k))
170  dm(i, k) = dm(i, k)*rgrav
171  CALL pushrealarray(dz2(i, k))
172  dz2(i, k) = zh(i, j, k+1) - zh(i, j, k)
173  CALL pushrealarray(w2(i, k))
174  w2(i, k) = w(i, j, k)
175  END DO
176  END DO
177  IF (a_imp .LT. -0.999) THEN
178  CALL sim3p0_solver_fwd(dt, is, ie, km, rdgas, gama, akap, pe2, &
179 & dm, pem, w2, dz2, pt(is:ie, j, 1:km), ws(is:ie&
180 & , j), p_fac, scale_m)
181  CALL pushcontrol(3,4)
182  ELSE IF (a_imp .LT. -0.5) THEN
183  IF (a_imp .GE. 0.) THEN
184  abs0 = a_imp
185  ELSE
186  abs0 = -a_imp
187  END IF
188  CALL sim3_solver_fwd(dt, is, ie, km, rdgas, gama, akap, pe2, dm&
189 & , pem, w2, dz2, pt(is:ie, j, 1:km), ws(is:ie, j)&
190 & , abs0, p_fac, scale_m)
191  CALL pushcontrol(3,3)
192  ELSE IF (a_imp .LE. 0.5) THEN
193  CALL rim_2d_fwd(ms, dt, is, ie, km, rdgas, gama, gm2, pe2, dm, &
194 & pm2, w2, dz2, pt(is:ie, j, 1:km), ws(is:ie, j), &
195 & .false.)
196  CALL pushcontrol(3,2)
197  ELSE IF (a_imp .GT. 0.999) THEN
198  CALL sim1_solver_fwd(dt, is, ie, km, rdgas, gama, gm2, cp2, akap&
199 & , pe2, dm, pm2, pem, w2, dz2, pt(is:ie, j, 1:km)&
200 & , ws(is:ie, j), p_fac)
201  CALL pushcontrol(3,1)
202  ELSE
203  CALL sim_solver_fwd(dt, is, ie, km, rdgas, gama, gm2, cp2, akap&
204 & , pe2, dm, pm2, pem, w2, dz2, pt(is:ie, j, 1:km), &
205 & ws(is:ie, j), a_imp, p_fac, scale_m)
206  CALL pushcontrol(3,0)
207  END IF
208  DO k=1,km
209  DO i=is,ie
210  CALL pushrealarray(w(i, j, k))
211  w(i, j, k) = w2(i, k)
212  CALL pushrealarray(delz(i, j, k))
213  delz(i, j, k) = dz2(i, k)
214  END DO
215  END DO
216  IF (last_call) THEN
217  DO k=1,km+1
218  DO i=is,ie
219  CALL pushrealarray(peln(i, k, j))
220  peln(i, k, j) = peln2(i, k)
221  CALL pushrealarray(pk(i, j, k))
222  pk(i, j, k) = pk3(i, j, k)
223  CALL pushrealarray(pe(i, k, j))
224  pe(i, k, j) = pem(i, k)
225  END DO
226  END DO
227  CALL pushcontrol(1,0)
228  ELSE
229  CALL pushcontrol(1,1)
230  END IF
231  IF (fp_out) THEN
232  DO k=1,km+1
233  DO i=is,ie
234  CALL pushrealarray(ppe(i, j, k))
235  ppe(i, j, k) = pe2(i, k) + pem(i, k)
236  END DO
237  END DO
238  CALL pushcontrol(1,0)
239  ELSE
240  DO k=1,km+1
241  DO i=is,ie
242  CALL pushrealarray(ppe(i, j, k))
243  ppe(i, j, k) = pe2(i, k)
244  END DO
245  END DO
246  CALL pushcontrol(1,1)
247  END IF
248  IF (use_logp) THEN
249  DO k=2,km+1
250  DO i=is,ie
251  CALL pushrealarray(pk3(i, j, k))
252  pk3(i, j, k) = peln2(i, k)
253  END DO
254  END DO
255  CALL pushcontrol(1,1)
256  ELSE
257  CALL pushcontrol(1,0)
258  END IF
259  DO i=is,ie
260  CALL pushrealarray(zh(i, j, km+1))
261  zh(i, j, km+1) = zs(i, j)
262  END DO
263  DO k=km,1,-1
264  DO i=is,ie
265  CALL pushrealarray(zh(i, j, k))
266  zh(i, j, k) = zh(i, j, k+1) - dz2(i, k)
267  END DO
268  END DO
269  END DO
270  CALL pushrealarray(peln2, (ie-is+1)*(km+1))
271  CALL pushrealarray(pem, (ie-is+1)*(km+1))
272  CALL pushrealarray(gama)
273  CALL pushrealarray(pm2, (ie-is+1)*km)
274  CALL pushrealarray(rgrav)
275  CALL pushrealarray(w2, (ie-is+1)*km)
276  CALL pushrealarray(dz2, (ie-is+1)*km)
277  CALL pushrealarray(pe2, (ie-is+1)*(km+1))
278  CALL pushrealarray(dm, (ie-is+1)*km)
279  END SUBROUTINE riem_solver3_fwd
280 ! Differentiation of riem_solver3 in reverse (adjoint) mode, backward sweep (with options split(a2b_edge_mod.a2b_ord4 a2b_edg
281 !e_mod.a2b_ord2 dyn_core_mod.dyn_core dyn_core_mod.pk3_halo dyn_core_mod.pln_halo dyn_core_mod.pe_halo dyn_core_mod.adv_pe dyn_co
282 !re_mod.p_grad_c dyn_core_mod.nh_p_grad dyn_core_mod.split_p_grad dyn_core_mod.one_grad_p dyn_core_mod.grad1_p_update dyn_core_mo
283 !d.mix_dp dyn_core_mod.geopk dyn_core_mod.del2_cubed dyn_core_mod.Rayleigh_fast fv_dynamics_mod.fv_dynamics fv_dynamics_mod.Rayle
284 !igh_Super fv_dynamics_mod.Rayleigh_Friction fv_dynamics_mod.compute_aam fv_grid_utils_mod.cubed_to_latlon fv_grid_utils_mod.c2l_
285 !ord4 fv_grid_utils_mod.c2l_ord2 fv_mapz_mod.Lagrangian_to_Eulerian fv_mapz_mod.compute_total_energy fv_mapz_mod.pkez fv_mapz_mod
286 !.remap_z fv_mapz_mod.map_scalar fv_mapz_mod.map1_ppm fv_mapz_mod.mapn_tracer fv_mapz_mod.map1_q2 fv_mapz_mod.remap_2
287 !d fv_mapz_mod.scalar_profile fv_mapz_mod.cs_profile fv_mapz_mod.cs_limiters fv_mapz_mod.ppm_profile fv_mapz_mod.ppm_limite
288 !rs fv_mapz_mod.steepz fv_mapz_mod.rst_remap fv_mapz_mod.mappm fv_mapz_mod.moist_cv fv_mapz_mod.moist_cp fv_mapz_mod.map1_cubic f
289 !v_restart_mod.d2c_setup fv_tracer2d_mod.tracer_2d_1L fv_tracer2d_mod.tracer_2d fv_tracer2d_mod.tracer_2d_nested fv_sg_mod.fv_sub
290 !grid_z main_mod.compute_pressures main_mod.run nh_core_mod.Riem_Solver3 nh_utils_mod.update_dz_c nh_utils_mod.update_dz_d nh_uti
291 !ls_mod.Riem_Solver_c nh_utils_mod.Riem_Solver3test nh_utils_mod.imp_diff_w nh_utils_mod.RIM_2D nh_utils_mod.SIM3_solver nh_utils
292 !_mod.SIM3p0_solver nh_utils_mod.SIM1_solver nh_utils_mod.SIM_solver nh_utils_mod.edge_scalar nh_utils_mod.edge_profile nh_utils_
293 !mod.nest_halo_nh sw_core_mod.c_sw sw_core_mod.d_sw sw_core_mod.divergence_corner sw_core_mod.divergence_corner_nest sw_core_mod
294 !.d2a2c_vect sw_core_mod.fill3_4corners sw_core_mod.fill2_4corners sw_core_mod.fill_4corners sw_core_mod.xtp_u sw_core_mod.ytp
295 !_v_fb sw_core_mod.compute_divergence_damping sw_core_mod.smag_corner tp_core_mod.mp_ghost_ew tp_core_mod.fv_tp_2d tp_co
296 !re_mod.copy_corners tp_core_mod.xppm tp_core_mod.yppm tp_core_mod.deln_flux a2b_edge_mod.extrap_corner fv_grid_ut
297 !ils_mod.great_circle_dist sw_core_mod.edge_interpolate4)):
298 ! gradient of useful results: pk3 ws ppe peln w delp delz
299 ! pe pk zh pt
300 ! with respect to varying inputs: pk3 ws ppe peln w delp delz
301 ! pe pk zh pt
302  SUBROUTINE riem_solver3_bwd(ms, dt, is, ie, js, je, km, ng, isd, ied, &
303 & jsd, jed, akap, cappa, cp, ptop, zs, q_con, w, w_ad, delz, delz_ad, &
304 & pt, pt_ad, delp, delp_ad, zh, zh_ad, pe, pe_ad, ppe, ppe_ad, pk3, &
305 & pk3_ad, pk, pk_ad, peln, peln_ad, ws, ws_ad, scale_m, p_fac, a_imp, &
306 & use_logp, last_call, fp_out)
307  IMPLICIT NONE
308  INTEGER, INTENT(IN) :: ms, is, ie, js, je, km, ng
309  INTEGER, INTENT(IN) :: isd, ied, jsd, jed
310  REAL, INTENT(IN) :: dt
311  REAL, INTENT(IN) :: akap, cp, ptop, p_fac, a_imp, scale_m
312  REAL, INTENT(IN) :: zs(isd:ied, jsd:jed)
313  LOGICAL, INTENT(IN) :: last_call, use_logp, fp_out
314  REAL, INTENT(IN) :: ws(is:ie, js:je)
315  REAL :: ws_ad(is:ie, js:je)
316  REAL, DIMENSION(isd:, jsd:, :), INTENT(IN) :: q_con, cappa
317  REAL, DIMENSION(isd:ied, jsd:jed, km), INTENT(IN) :: delp, pt
318  REAL, DIMENSION(isd:ied, jsd:jed, km) :: delp_ad, pt_ad
319  REAL, DIMENSION(isd:ied, jsd:jed, km+1), INTENT(INOUT) :: zh
320  REAL, DIMENSION(isd:ied, jsd:jed, km+1), INTENT(INOUT) :: zh_ad
321  REAL, DIMENSION(isd:ied, jsd:jed, km), INTENT(INOUT) :: w
322  REAL, DIMENSION(isd:ied, jsd:jed, km), INTENT(INOUT) :: w_ad
323  REAL, INTENT(INOUT) :: pe(is-1:ie+1, km+1, js-1:je+1)
324  REAL, INTENT(INOUT) :: pe_ad(is-1:ie+1, km+1, js-1:je+1)
325  REAL :: peln(is:ie, km+1, js:je)
326  REAL :: peln_ad(is:ie, km+1, js:je)
327  REAL, DIMENSION(isd:ied, jsd:jed, km+1) :: ppe
328  REAL, DIMENSION(isd:ied, jsd:jed, km+1) :: ppe_ad
329  REAL :: delz(is-ng:ie+ng, js-ng:je+ng, km)
330  REAL :: delz_ad(is-ng:ie+ng, js-ng:je+ng, km)
331  REAL :: pk(is:ie, js:je, km+1)
332  REAL :: pk_ad(is:ie, js:je, km+1)
333  REAL :: pk3(isd:ied, jsd:jed, km+1)
334  REAL :: pk3_ad(isd:ied, jsd:jed, km+1)
335  REAL, DIMENSION(is:ie, km) :: dm, dz2, pm2, w2, gm2, cp2
336  REAL, DIMENSION(is:ie, km) :: dm_ad, dz2_ad, pm2_ad, w2_ad
337  REAL, DIMENSION(is:ie, km+1) :: pem, pe2, peln2, peg, pelng
338  REAL, DIMENSION(is:ie, km+1) :: pem_ad, pe2_ad, peln2_ad
339  REAL :: gama, rgrav, ptk, peln1
340  INTEGER :: i, j, k
341  INTRINSIC log
342  INTRINSIC exp
343  INTRINSIC abs
344  REAL :: abs0
345  REAL :: temp
346  REAL :: temp_ad
347  INTEGER :: branch
348 
349  dm = 0.0
350  dz2 = 0.0
351  pm2 = 0.0
352  w2 = 0.0
353  gm2 = 0.0
354  cp2 = 0.0
355  pem = 0.0
356  pe2 = 0.0
357  peln2 = 0.0
358  peg = 0.0
359  pelng = 0.0
360  gama = 0.0
361  rgrav = 0.0
362  ptk = 0.0
363  peln1 = 0.0
364  abs0 = 0.0
365  branch = 0
366 
367  CALL poprealarray(dm, (ie-is+1)*km)
368  CALL poprealarray(pe2, (ie-is+1)*(km+1))
369  CALL poprealarray(dz2, (ie-is+1)*km)
370  CALL poprealarray(w2, (ie-is+1)*km)
371  CALL poprealarray(rgrav)
372  CALL poprealarray(pm2, (ie-is+1)*km)
373  CALL poprealarray(gama)
374  CALL poprealarray(pem, (ie-is+1)*(km+1))
375  CALL poprealarray(peln2, (ie-is+1)*(km+1))
376  dm_ad = 0.0
377  pe2_ad = 0.0
378  dz2_ad = 0.0
379  w2_ad = 0.0
380  pm2_ad = 0.0
381  pem_ad = 0.0
382  peln2_ad = 0.0
383  DO j=je,js,-1
384  DO k=1,km,1
385  DO i=ie,is,-1
386  CALL poprealarray(zh(i, j, k))
387  zh_ad(i, j, k+1) = zh_ad(i, j, k+1) + zh_ad(i, j, k)
388  dz2_ad(i, k) = dz2_ad(i, k) - zh_ad(i, j, k)
389  zh_ad(i, j, k) = 0.0
390  END DO
391  END DO
392  DO i=ie,is,-1
393  CALL poprealarray(zh(i, j, km+1))
394  zh_ad(i, j, km+1) = 0.0
395  END DO
396  CALL popcontrol(1,branch)
397  IF (branch .NE. 0) THEN
398  DO k=km+1,2,-1
399  DO i=ie,is,-1
400  CALL poprealarray(pk3(i, j, k))
401  peln2_ad(i, k) = peln2_ad(i, k) + pk3_ad(i, j, k)
402  pk3_ad(i, j, k) = 0.0
403  END DO
404  END DO
405  END IF
406  CALL popcontrol(1,branch)
407  IF (branch .EQ. 0) THEN
408  DO k=km+1,1,-1
409  DO i=ie,is,-1
410  CALL poprealarray(ppe(i, j, k))
411  pe2_ad(i, k) = pe2_ad(i, k) + ppe_ad(i, j, k)
412  pem_ad(i, k) = pem_ad(i, k) + ppe_ad(i, j, k)
413  ppe_ad(i, j, k) = 0.0
414  END DO
415  END DO
416  ELSE
417  DO k=km+1,1,-1
418  DO i=ie,is,-1
419  CALL poprealarray(ppe(i, j, k))
420  pe2_ad(i, k) = pe2_ad(i, k) + ppe_ad(i, j, k)
421  ppe_ad(i, j, k) = 0.0
422  END DO
423  END DO
424  END IF
425  CALL popcontrol(1,branch)
426  IF (branch .EQ. 0) THEN
427  DO k=km+1,1,-1
428  DO i=ie,is,-1
429  CALL poprealarray(pe(i, k, j))
430  pem_ad(i, k) = pem_ad(i, k) + pe_ad(i, k, j)
431  pe_ad(i, k, j) = 0.0
432  CALL poprealarray(pk(i, j, k))
433  pk3_ad(i, j, k) = pk3_ad(i, j, k) + pk_ad(i, j, k)
434  pk_ad(i, j, k) = 0.0
435  CALL poprealarray(peln(i, k, j))
436  peln2_ad(i, k) = peln2_ad(i, k) + peln_ad(i, k, j)
437  peln_ad(i, k, j) = 0.0
438  END DO
439  END DO
440  END IF
441  DO k=km,1,-1
442  DO i=ie,is,-1
443  CALL poprealarray(delz(i, j, k))
444  dz2_ad(i, k) = dz2_ad(i, k) + delz_ad(i, j, k)
445  delz_ad(i, j, k) = 0.0
446  CALL poprealarray(w(i, j, k))
447  w2_ad(i, k) = w2_ad(i, k) + w_ad(i, j, k)
448  w_ad(i, j, k) = 0.0
449  END DO
450  END DO
451  CALL popcontrol(3,branch)
452  IF (branch .LT. 2) THEN
453  IF (branch .EQ. 0) THEN
454  CALL sim_solver_bwd(dt, is, ie, km, rdgas, gama, gm2, cp2, &
455 & akap, pe2, pe2_ad, dm, dm_ad, pm2, pm2_ad, pem, &
456 & pem_ad, w2, w2_ad, dz2, dz2_ad, pt(is:ie, j, 1:&
457 & km), pt_ad(is:ie, j, 1:km), ws(is:ie, j), ws_ad(&
458 & is:ie, j), a_imp, p_fac, scale_m)
459  ELSE
460  CALL sim1_solver_bwd(dt, is, ie, km, rdgas, gama, gm2, cp2, &
461 & akap, pe2, pe2_ad, dm, dm_ad, pm2, pm2_ad, pem&
462 & , pem_ad, w2, w2_ad, dz2, dz2_ad, pt(is:ie, j, &
463 & 1:km), pt_ad(is:ie, j, 1:km), ws(is:ie, j), &
464 & ws_ad(is:ie, j), p_fac)
465  END IF
466  ELSE IF (branch .EQ. 2) THEN
467  CALL rim_2d_bwd(ms, dt, is, ie, km, rdgas, gama, gm2, pe2, &
468 & pe2_ad, dm, dm_ad, pm2, pm2_ad, w2, w2_ad, dz2, dz2_ad&
469 & , pt(is:ie, j, 1:km), pt_ad(is:ie, j, 1:km), ws(is:ie&
470 & , j), ws_ad(is:ie, j), .false.)
471  ELSE IF (branch .EQ. 3) THEN
472  CALL sim3_solver_bwd(dt, is, ie, km, rdgas, gama, akap, pe2, &
473 & pe2_ad, dm, dm_ad, pem, pem_ad, w2, w2_ad, dz2, &
474 & dz2_ad, pt(is:ie, j, 1:km), pt_ad(is:ie, j, 1:km)&
475 & , ws(is:ie, j), ws_ad(is:ie, j), abs0, p_fac, &
476 & scale_m)
477  ELSE
478  CALL sim3p0_solver_bwd(dt, is, ie, km, rdgas, gama, akap, pe2, &
479 & pe2_ad, dm, dm_ad, pem, pem_ad, w2, w2_ad, dz2&
480 & , dz2_ad, pt(is:ie, j, 1:km), pt_ad(is:ie, j, 1&
481 & :km), ws(is:ie, j), ws_ad(is:ie, j), p_fac, &
482 & scale_m)
483  END IF
484  DO k=km,1,-1
485  DO i=ie,is,-1
486  temp = peln2(i, k+1) - peln2(i, k)
487  CALL poprealarray(w2(i, k))
488  w_ad(i, j, k) = w_ad(i, j, k) + w2_ad(i, k)
489  w2_ad(i, k) = 0.0
490  CALL poprealarray(dz2(i, k))
491  zh_ad(i, j, k+1) = zh_ad(i, j, k+1) + dz2_ad(i, k)
492  zh_ad(i, j, k) = zh_ad(i, j, k) - dz2_ad(i, k)
493  dz2_ad(i, k) = 0.0
494  CALL poprealarray(dm(i, k))
495  dm_ad(i, k) = pm2_ad(i, k)/temp + rgrav*dm_ad(i, k)
496  CALL poprealarray(pm2(i, k))
497  temp_ad = -(dm(i, k)*pm2_ad(i, k)/temp**2)
498  peln2_ad(i, k+1) = peln2_ad(i, k+1) + temp_ad
499  peln2_ad(i, k) = peln2_ad(i, k) - temp_ad
500  pm2_ad(i, k) = 0.0
501  END DO
502  END DO
503  DO k=km+1,2,-1
504  DO i=ie,is,-1
505  CALL poprealarray(pk3(i, j, k))
506  peln2_ad(i, k) = peln2_ad(i, k) + exp(akap*peln2(i, k))*akap*&
507 & pk3_ad(i, j, k)
508  pk3_ad(i, j, k) = 0.0
509  CALL poprealarray(peln2(i, k))
510  pem_ad(i, k) = pem_ad(i, k) + peln2_ad(i, k)/pem(i, k)
511  peln2_ad(i, k) = 0.0
512  CALL poprealarray(pem(i, k))
513  pem_ad(i, k-1) = pem_ad(i, k-1) + pem_ad(i, k)
514  dm_ad(i, k-1) = dm_ad(i, k-1) + pem_ad(i, k)
515  pem_ad(i, k) = 0.0
516  END DO
517  END DO
518  DO i=ie,is,-1
519  CALL poprealarray(pk3(i, j, 1))
520  pk3_ad(i, j, 1) = 0.0
521  CALL poprealarray(peln2(i, 1))
522  peln2_ad(i, 1) = 0.0
523  CALL poprealarray(pem(i, 1))
524  pem_ad(i, 1) = 0.0
525  END DO
526  DO k=km,1,-1
527  DO i=ie,is,-1
528  CALL poprealarray(dm(i, k))
529  delp_ad(i, j, k) = delp_ad(i, j, k) + dm_ad(i, k)
530  dm_ad(i, k) = 0.0
531  END DO
532  END DO
533  END DO
534  END SUBROUTINE riem_solver3_bwd
535  SUBROUTINE riem_solver3(ms, dt, is, ie, js, je, km, ng, isd, ied, jsd&
536 & , jed, akap, cappa, cp, ptop, zs, q_con, w, delz, pt, delp, zh, pe, &
537 & ppe, pk3, pk, peln, ws, scale_m, p_fac, a_imp, use_logp, last_call, &
538 & fp_out)
539  IMPLICIT NONE
540 !--------------------------------------------
541 ! !OUTPUT PARAMETERS
542 ! Ouput: gz: grav*height at edges
543 ! pe: full hydrostatic pressure
544 ! ppe: non-hydrostatic pressure perturbation
545 !--------------------------------------------
546  INTEGER, INTENT(IN) :: ms, is, ie, js, je, km, ng
547  INTEGER, INTENT(IN) :: isd, ied, jsd, jed
548 ! the BIG horizontal Lagrangian time step
549  REAL, INTENT(IN) :: dt
550  REAL, INTENT(IN) :: akap, cp, ptop, p_fac, a_imp, scale_m
551  REAL, INTENT(IN) :: zs(isd:ied, jsd:jed)
552  LOGICAL, INTENT(IN) :: last_call, use_logp, fp_out
553  REAL, INTENT(IN) :: ws(is:ie, js:je)
554  REAL, DIMENSION(isd:, jsd:, :), INTENT(IN) :: q_con, cappa
555  REAL, DIMENSION(isd:ied, jsd:jed, km), INTENT(IN) :: delp, pt
556  REAL, DIMENSION(isd:ied, jsd:jed, km+1), INTENT(INOUT) :: zh
557  REAL, DIMENSION(isd:ied, jsd:jed, km), INTENT(INOUT) :: w
558  REAL, INTENT(INOUT) :: pe(is-1:ie+1, km+1, js-1:je+1)
559 ! ln(pe)
560  REAL, INTENT(OUT) :: peln(is:ie, km+1, js:je)
561  REAL, DIMENSION(isd:ied, jsd:jed, km+1), INTENT(OUT) :: ppe
562  REAL, INTENT(OUT) :: delz(is-ng:ie+ng, js-ng:je+ng, km)
563  REAL, INTENT(OUT) :: pk(is:ie, js:je, km+1)
564  REAL, INTENT(OUT) :: pk3(isd:ied, jsd:jed, km+1)
565 ! Local:
566  REAL, DIMENSION(is:ie, km) :: dm, dz2, pm2, w2, gm2, cp2
567  REAL, DIMENSION(is:ie, km+1) :: pem, pe2, peln2, peg, pelng
568  REAL :: gama, rgrav, ptk, peln1
569  INTEGER :: i, j, k
570  INTRINSIC log
571  INTRINSIC exp
572  INTRINSIC abs
573  REAL :: abs0
574  gama = 1./(1.-akap)
575  rgrav = 1./grav
576  peln1 = log(ptop)
577  ptk = exp(akap*peln1)
578 !$OMP parallel do default(none) shared(is,ie,js,je,km,delp,ptop,peln1,pk3,ptk,akap,rgrav,zh,pt, &
579 !$OMP w,a_imp,dt,gama,ws,p_fac,scale_m,ms,delz,last_call, &
580 !$OMP peln,pk,fp_out,ppe,use_logp,zs,pe,cappa,q_con ) &
581 !$OMP private(cp2, gm2, dm, dz2, pm2, pem, peg, pelng, pe2, peln2, w2)
582  DO j=js,je
583  DO k=1,km
584  DO i=is,ie
585  dm(i, k) = delp(i, j, k)
586  END DO
587  END DO
588  DO i=is,ie
589  pem(i, 1) = ptop
590  peln2(i, 1) = peln1
591  pk3(i, j, 1) = ptk
592  END DO
593  DO k=2,km+1
594  DO i=is,ie
595  pem(i, k) = pem(i, k-1) + dm(i, k-1)
596  peln2(i, k) = log(pem(i, k))
597  pk3(i, j, k) = exp(akap*peln2(i, k))
598  END DO
599  END DO
600  DO k=1,km
601  DO i=is,ie
602  pm2(i, k) = dm(i, k)/(peln2(i, k+1)-peln2(i, k))
603  dm(i, k) = dm(i, k)*rgrav
604  dz2(i, k) = zh(i, j, k+1) - zh(i, j, k)
605  w2(i, k) = w(i, j, k)
606  END DO
607  END DO
608  IF (a_imp .LT. -0.999) THEN
609  CALL sim3p0_solver(dt, is, ie, km, rdgas, gama, akap, pe2, dm, &
610 & pem, w2, dz2, pt(is:ie, j, 1:km), ws(is:ie, j), &
611 & p_fac, scale_m)
612  ELSE IF (a_imp .LT. -0.5) THEN
613  IF (a_imp .GE. 0.) THEN
614  abs0 = a_imp
615  ELSE
616  abs0 = -a_imp
617  END IF
618  CALL sim3_solver(dt, is, ie, km, rdgas, gama, akap, pe2, dm, pem&
619 & , w2, dz2, pt(is:ie, j, 1:km), ws(is:ie, j), abs0, &
620 & p_fac, scale_m)
621  ELSE IF (a_imp .LE. 0.5) THEN
622  CALL rim_2d(ms, dt, is, ie, km, rdgas, gama, gm2, pe2, dm, pm2, &
623 & w2, dz2, pt(is:ie, j, 1:km), ws(is:ie, j), .false.)
624  ELSE IF (a_imp .GT. 0.999) THEN
625  CALL sim1_solver(dt, is, ie, km, rdgas, gama, gm2, cp2, akap, &
626 & pe2, dm, pm2, pem, w2, dz2, pt(is:ie, j, 1:km), ws(is&
627 & :ie, j), p_fac)
628  ELSE
629  CALL sim_solver(dt, is, ie, km, rdgas, gama, gm2, cp2, akap, pe2&
630 & , dm, pm2, pem, w2, dz2, pt(is:ie, j, 1:km), ws(is:ie&
631 & , j), a_imp, p_fac, scale_m)
632  END IF
633  DO k=1,km
634  DO i=is,ie
635  w(i, j, k) = w2(i, k)
636  delz(i, j, k) = dz2(i, k)
637  END DO
638  END DO
639  IF (last_call) THEN
640  DO k=1,km+1
641  DO i=is,ie
642  peln(i, k, j) = peln2(i, k)
643  pk(i, j, k) = pk3(i, j, k)
644  pe(i, k, j) = pem(i, k)
645  END DO
646  END DO
647  END IF
648  IF (fp_out) THEN
649  DO k=1,km+1
650  DO i=is,ie
651  ppe(i, j, k) = pe2(i, k) + pem(i, k)
652  END DO
653  END DO
654  ELSE
655  DO k=1,km+1
656  DO i=is,ie
657  ppe(i, j, k) = pe2(i, k)
658  END DO
659  END DO
660  END IF
661  IF (use_logp) THEN
662  DO k=2,km+1
663  DO i=is,ie
664  pk3(i, j, k) = peln2(i, k)
665  END DO
666  END DO
667  END IF
668  DO i=is,ie
669  zh(i, j, km+1) = zs(i, j)
670  END DO
671  DO k=km,1,-1
672  DO i=is,ie
673  zh(i, j, k) = zh(i, j, k+1) - dz2(i, k)
674  END DO
675  END DO
676  END DO
677  END SUBROUTINE riem_solver3
678 end module nh_core_adm_mod
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 sim1_solver_fwd(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe, dm2, pm2, pem, w2, dz2, pt2, ws, p_fac)
subroutine, public update_dz_d_fwd(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 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 rim_2d(ms, bdt, is, ie, km, rgas, gama, gm2, pe2, dm2, pm2, w2, dz2, pt2, ws, c_core)
subroutine, public pushcontrol(ctype, field)
subroutine, public rim_2d_fwd(ms, bdt, is, ie, km, rgas, gama, gm2, pe2, dm2, pm2, w2, dz2, pt2, ws, c_core)
real, parameter, public rdgas
Gas constant for dry air [J/kg/deg].
Definition: constants.F90:77
subroutine, public update_dz_d_bwd(ndif, damp, hord, is, ie, js, je, km, ng, npx, npy, area, rarea, dp0, zs, zh, zh_ad, crx, crx_ad, cry, cry_ad, xfx, xfx_ad, yfx, yfx_ad, delz, ws, ws_ad, rdt, gridstruct, bd, hord_pert)
subroutine, public fv_tp_2d_fwd(q, crx, cry, npx, npy, hord, fx, fy, xfx, yfx, gridstruct, bd, ra_x, ra_y, mfx, mfy, mass, nord, damp_c)
subroutine, public sim_solver_fwd(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe2, dm2, pm2, pem, w2, dz2, pt2, ws, alpha, p_fac, scale_m)
subroutine, public sim1_solver_bwd(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe, pe_ad, dm2, dm2_ad, pm2, pm2_ad, pem, pem_ad, w2, w2_ad, dz2, dz2_ad, pt2, pt2_ad, ws, ws_ad, p_fac)
subroutine, public riem_solver3(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, public sim3p0_solver_bwd(dt, is, ie, km, rgas, gama, kappa, pe2, pe2_ad, dm, dm_ad, pem, pem_ad, w2, w2_ad, dz2, dz2_ad, pt2, pt2_ad, ws, ws_ad, p_fac, scale_m)
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 sim3p0_solver(dt, is, ie, km, rgas, gama, kappa, pe2, dm, pem, w2, dz2, pt2, ws, p_fac, scale_m)
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)
subroutine, public update_dz_c_fwd(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 sim3p0_solver_fwd(dt, is, ie, km, rgas, gama, kappa, pe2, dm, pem, w2, dz2, pt2, ws, p_fac, scale_m)
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 riem_solver3_fwd(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)
Definition: nh_core_adm.F90:79
subroutine, public sim3_solver_bwd(dt, is, ie, km, rgas, gama, kappa, pe2, pe2_ad, dm, dm_ad, pem, pem_ad, w2, w2_ad, dz2, dz2_ad, pt2, pt2_ad, ws, ws_ad, alpha, p_fac, scale_m)
real, parameter, public cp_air
Specific heat capacity of dry air at constant pressure [J/kg/deg].
Definition: constants.F90:83
subroutine, public sim_solver_bwd(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe2, pe2_ad, dm2, dm2_ad, pm2, pm2_ad, pem, pem_ad, w2, w2_ad, dz2, dz2_ad, pt2, pt2_ad, ws, ws_ad, alpha, p_fac, scale_m)
subroutine, public sim1_solver(dt, is, ie, km, rgas, gama, gm2, cp2, kappa, pe, dm2, pm2, pem, w2, dz2, pt2, ws, p_fac)
subroutine, public riem_solver3_bwd(ms, dt, is, ie, js, je, km, ng, isd, ied, jsd, jed, akap, cappa, cp, ptop, zs, q_con, w, w_ad, delz, delz_ad, pt, pt_ad, delp, delp_ad, zh, zh_ad, pe, pe_ad, ppe, ppe_ad, pk3, pk3_ad, pk, pk_ad, peln, peln_ad, ws, ws_ad, scale_m, p_fac, a_imp, use_logp, last_call, fp_out)
subroutine, public fv_tp_2d_bwd(q, q_ad, crx, crx_ad, cry, cry_ad, npx, npy, hord, fx, fx_ad, fy, fy_ad, xfx, xfx_ad, yfx, yfx_ad, gridstruct, bd, ra_x, ra_x_ad, ra_y, ra_y_ad, mfx, mfx_ad, mfy, mfy_ad, mass, mass_ad, nord, damp_c)
subroutine, public nest_halo_nh_bwd(ptop, grav, kappa, cp, delp, delp_ad, delz, delz_ad, pt, pt_ad, phis, pkc, pkc_ad, gz, gz_ad, pk3, pk3_ad, npx, npy, npz, nested, pkc_pertn, computepk3, fullhalo, bd)
subroutine, public riem_solver_c_fwd(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)
real, parameter r3
Definition: nh_core_adm.F90:50
subroutine, public sim3_solver(dt, is, ie, km, rgas, gama, kappa, pe2, dm, pem, w2, dz2, pt2, ws, alpha, p_fac, scale_m)
subroutine, public riem_solver_c_bwd(ms, dt, is, ie, js, je, km, ng, akap, cappa, cp, ptop, hs, w3, w3_ad, pt, pt_ad, q_con, delp, delp_ad, gz, gz_ad, pef, pef_ad, ws, ws_ad, p_fac, a_imp, scale_m)
real, parameter, public grav
Acceleration due to gravity [m/s^2].
Definition: constants.F90:76
subroutine, public rim_2d_bwd(ms, bdt, is, ie, km, rgas, gama, gm2, pe2, pe2_ad, dm2, dm2_ad, pm2, pm2_ad, w2, w2_ad, dz2, dz2_ad, pt2, pt2_ad, ws, ws_ad, c_core)
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 sim3_solver_fwd(dt, is, ie, km, rgas, gama, kappa, pe2, dm, pem, w2, dz2, pt2, ws, alpha, p_fac, scale_m)
subroutine, public nest_halo_nh_fwd(ptop, grav, kappa, cp, delp, delz, pt, phis, pkc, gz, pk3, npx, npy, npz, nested, pkc_pertn, computepk3, fullhalo, bd)
subroutine, public update_dz_c_bwd(is, ie, js, je, km, ng, dt, dp0, zs, area, ut, ut_ad, vt, vt_ad, gz, gz_ad, ws, ws_ad, npx, npy, sw_corner, se_corner, ne_corner, nw_corner, bd, grid_type)
subroutine, public popcontrol(ctype, field)