FV3 Bundle
fv_dynamics_nlm.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 !***********************************************************************
26  use fv_fill_nlm_mod, only: fill2d
27  use fv_mp_nlm_mod, only: is_master
28  use fv_mp_nlm_mod, only: group_halo_update_type
29  use fv_mp_nlm_mod, only: start_group_halo_update, complete_group_halo_update
31  use diag_manager_mod, only: send_data
33  use mpp_domains_mod, only: dgrid_ne, cgrid_ne, mpp_update_domains, domain2d
34  use mpp_mod, only: mpp_pe
37  use fv_sg_nlm_mod, only: neg_adj3
42 !#ifdef MAPL_MODE
43 ! use fv_control_nlm_mod, only: dyn_timer, comm_timer
44 !#endif
45 
46 implicit none
47 
48 !#ifdef MAPL_MODE
49 ! ! Include the MPI library definitons:
50 ! include 'mpif.h'
51 !#endif
52 
53  logical :: rf_initialized = .false.
54  logical :: bad_range = .false.
55  real, allocatable :: rf(:)
56  integer :: kmax=1
57  real :: agrav
58 #ifdef HIWPP
59  real, allocatable:: u00(:,:,:), v00(:,:,:)
60 #endif
61 private
62 public :: fv_dynamics
63 
64 contains
65 
66 !-----------------------------------------------------------------------
67 ! fv_dynamics :: FV dynamical core driver
68 !-----------------------------------------------------------------------
69 
70  subroutine fv_dynamics(npx, npy, npz, nq_tot, ng, bdt, consv_te, fill, &
71  reproduce_sum, kappa, cp_air, zvir, ptop, ks, ncnst, n_split, &
72  q_split, u, v, w, delz, hydrostatic, pt, delp, q, &
73  ps, pe, pk, peln, pkz, phis, q_con, omga, ua, va, uc, vc, &
74  ak, bk, mfx, mfy, cx, cy, ze0, hybrid_z, &
75  gridstruct, flagstruct, neststruct, idiag, bd, &
76  parent_grid, domain, time_total)
77 
78  real, intent(IN) :: bdt ! Large time-step
79  real, intent(IN) :: consv_te
80  real, intent(IN) :: kappa, cp_air
81  real, intent(IN) :: zvir, ptop
82  real, intent(IN), optional :: time_total
83 
84  integer, intent(IN) :: npx
85  integer, intent(IN) :: npy
86  integer, intent(IN) :: npz
87  integer, intent(IN) :: nq_tot ! transported tracers
88  integer, intent(IN) :: ng
89  integer, intent(IN) :: ks
90  integer, intent(IN) :: ncnst
91  integer, intent(IN) :: n_split ! small-step horizontal dynamics
92  integer, intent(IN) :: q_split ! tracer
93  logical, intent(IN) :: fill
94  logical, intent(IN) :: reproduce_sum
95  logical, intent(IN) :: hydrostatic
96  logical, intent(IN) :: hybrid_z ! Using hybrid_z for remapping
97 
98  type(fv_grid_bounds_type), intent(IN) :: bd
99  real, intent(inout), dimension(bd%isd:bd%ied ,bd%jsd:bd%jed+1,npz) :: u ! D grid zonal wind (m/s)
100  real, intent(inout), dimension(bd%isd:bd%ied+1,bd%jsd:bd%jed ,npz) :: v ! D grid meridional wind (m/s)
101  real, intent(inout) :: w( bd%isd: ,bd%jsd: ,1:) ! W (m/s)
102  real, intent(inout) :: pt( bd%isd:bd%ied ,bd%jsd:bd%jed ,npz) ! temperature (K)
103  real, intent(inout) :: delp(bd%isd:bd%ied ,bd%jsd:bd%jed ,npz) ! pressure thickness (pascal)
104  real, intent(inout) :: q( bd%isd:bd%ied ,bd%jsd:bd%jed ,npz, ncnst) ! specific humidity and constituents
105  real, intent(inout) :: delz(bd%isd:,bd%jsd:,1:) ! delta-height (m); non-hydrostatic only
106  real, intent(inout) :: ze0(bd%is:, bd%js: ,1:) ! height at edges (m); non-hydrostatic
107 ! ze0 no longer used
108 
109 !-----------------------------------------------------------------------
110 ! Auxilliary pressure arrays:
111 ! The 5 vars below can be re-computed from delp and ptop.
112 !-----------------------------------------------------------------------
113 ! dyn_aux:
114  real, intent(inout) :: ps (bd%isd:bd%ied ,bd%jsd:bd%jed) ! Surface pressure (pascal)
115  real, intent(inout) :: pe (bd%is-1:bd%ie+1, npz+1,bd%js-1:bd%je+1) ! edge pressure (pascal)
116  real, intent(inout) :: pk (bd%is:bd%ie,bd%js:bd%je, npz+1) ! pe**kappa
117  real, intent(inout) :: peln(bd%is:bd%ie,npz+1,bd%js:bd%je) ! ln(pe)
118  real, intent(inout) :: pkz (bd%is:bd%ie,bd%js:bd%je,npz) ! finite-volume mean pk
119  real, intent(inout):: q_con(bd%isd:, bd%jsd:, 1:)
120 
121 !-----------------------------------------------------------------------
122 ! Others:
123 !-----------------------------------------------------------------------
124  real, intent(inout) :: phis(bd%isd:bd%ied,bd%jsd:bd%jed) ! Surface geopotential (g*Z_surf)
125  real, intent(inout) :: omga(bd%isd:bd%ied,bd%jsd:bd%jed,npz) ! Vertical pressure velocity (pa/s)
126  real, intent(inout) :: uc(bd%isd:bd%ied+1,bd%jsd:bd%jed ,npz) ! (uc,vc) mostly used as the C grid winds
127  real, intent(inout) :: vc(bd%isd:bd%ied ,bd%jsd:bd%jed+1,npz)
128 
129  real, intent(inout), dimension(bd%isd:bd%ied ,bd%jsd:bd%jed ,npz):: ua, va
130  real, intent(in), dimension(npz+1):: ak, bk
131 
132 ! Accumulated Mass flux arrays: the "Flux Capacitor"
133  real, intent(inout) :: mfx(bd%is:bd%ie+1, bd%js:bd%je, npz)
134  real, intent(inout) :: mfy(bd%is:bd%ie , bd%js:bd%je+1, npz)
135 ! Accumulated Courant number arrays
136  real, intent(inout) :: cx(bd%is:bd%ie+1, bd%jsd:bd%jed, npz)
137  real, intent(inout) :: cy(bd%isd:bd%ied ,bd%js:bd%je+1, npz)
138 
139  type(fv_grid_type), intent(inout), target :: gridstruct
140  type(fv_flags_type), intent(INOUT) :: flagstruct
141  type(fv_nest_type), intent(INOUT) :: neststruct
142  type(domain2d), intent(INOUT) :: domain
143  type(fv_atmos_type), intent(INOUT) :: parent_grid
144  type(fv_diag_type), intent(IN) :: idiag
145 
146 ! Local Arrays
147  real:: ws(bd%is:bd%ie,bd%js:bd%je)
148  real:: te_2d(bd%is:bd%ie,bd%js:bd%je)
149  real:: teq(bd%is:bd%ie,bd%js:bd%je)
150  real:: ps2(bd%isd:bd%ied,bd%jsd:bd%jed)
151  real:: m_fac(bd%is:bd%ie,bd%js:bd%je)
152  real:: pfull(npz)
153  real, dimension(bd%is:bd%ie):: cvm
154  real, allocatable :: dp1(:,:,:), dtdt_m(:,:,:), cappa(:,:,:)
155  real(kind=8), allocatable :: psx(:,:)
156  real(kind=8), allocatable :: dpx(:,:)
157  real:: akap, rdg, ph1, ph2, mdt, gam, amdt, u0
158  integer:: kord_tracer(ncnst)
159  integer :: i,j,k, n, iq, n_map, nq, nwat, k_split
160  integer :: sphum, liq_wat = -999, ice_wat = -999 ! GFDL physics
161  integer :: rainwat = -999, snowwat = -999, graupel = -999, cld_amt = -999
162  integer :: theta_d = -999
163  logical used, last_step, do_omega
164  integer, parameter :: max_packs=12
165  type(group_halo_update_type), save :: i_pack(max_packs)
166  integer :: is, ie, js, je
167  integer :: isd, ied, jsd, jed
168  real :: dt2
169  real(kind=8) :: t1, t2
170  integer :: status
171 
172  is = bd%is
173  ie = bd%ie
174  js = bd%js
175  je = bd%je
176  isd = bd%isd
177  ied = bd%ied
178  jsd = bd%jsd
179  jed = bd%jed
180 
181 ! dyn_timer = 0
182 ! comm_timer = 0
183 
184 ! cv_air = cp_air - rdgas
185  agrav = 1. / grav
186  dt2 = 0.5*bdt
187  k_split = flagstruct%k_split
188  nwat = flagstruct%nwat
189  nq = nq_tot - flagstruct%dnats
190  rdg = -rdgas * agrav
191  allocate ( dp1(isd:ied, jsd:jed, 1:npz) )
192 
193 !#ifdef MAPL_MODE
194 !! Begin Dynamics timer for GEOS history processing
195 ! t1 = MPI_Wtime(status)
196 !#endif
197 #ifdef MOIST_CAPPA
198  allocate ( cappa(isd:ied,jsd:jed,npz) )
199  call init_ijk_mem(isd,ied, jsd,jed, npz, cappa, 0.)
200 #else
201  allocate ( cappa(isd:isd,jsd:jsd,1) )
202  cappa = 0.
203 #endif
204  !We call this BEFORE converting pt to virtual potential temperature,
205  !since we interpolate on (regular) temperature rather than theta.
206  if (gridstruct%nested .or. any(neststruct%child_grids)) then
207  call timing_on('NEST_BCs')
208  call setup_nested_grid_bcs(npx, npy, npz, zvir, ncnst, &
209  u, v, w, pt, delp, delz, q, uc, vc, pkz, &
210  neststruct%nested, flagstruct%inline_q, flagstruct%make_nh, ng, &
211  gridstruct, flagstruct, neststruct, &
212  neststruct%nest_timestep, neststruct%tracer_nest_timestep, &
213  domain, bd, nwat)
214 
215 #ifndef SW_DYNAMICS
216  if (gridstruct%nested) then
217  !Correct halo values have now been set up for BCs; we can go ahead and apply them too...
218  call nested_grid_bc_apply_intt(pt, &
219  0, 0, npx, npy, npz, bd, 1., 1., &
220  neststruct%pt_BC, bctype=neststruct%nestbctype )
221 #ifdef USE_COND
222  call nested_grid_bc_apply_intt(q_con, &
223  0, 0, npx, npy, npz, bd, 1., 1., &
224  neststruct%q_con_BC, bctype=neststruct%nestbctype )
225 #ifdef MOIST_CAPPA
226  call nested_grid_bc_apply_intt(cappa, &
227  0, 0, npx, npy, npz, bd, 1., 1., &
228  neststruct%cappa_BC, bctype=neststruct%nestbctype )
229 #endif
230 #endif
231  endif
232 #endif
233  call timing_off('NEST_BCs')
234  endif
235 
236 
237  if ( flagstruct%no_dycore ) then
238  if ( nwat.eq.2 .and. (.not.hydrostatic) ) then
239  sphum = get_tracer_index(model_atmos, 'sphum')
240  endif
241  goto 911
242  endif
243 
244 #ifdef MAPL_MODE
245  select case (nwat)
246  case (0)
247  sphum = 1
248  cld_amt = -1 ! to cause trouble if (mis)used
249  case (1)
250  sphum = 1
251  liq_wat = -1 ! to cause trouble if (mis)used
252  ice_wat = -1 ! to cause trouble if (mis)used
253  rainwat = -1 ! to cause trouble if (mis)used
254  snowwat = -1 ! to cause trouble if (mis)used
255  graupel = -1 ! to cause trouble if (mis)used
256  cld_amt = -1 ! to cause trouble if (mis)used
257  theta_d = -1 ! to cause trouble if (mis)used
258  case (3)
259  sphum = 1
260  liq_wat = 2
261  ice_wat = 3
262  rainwat = -1 ! to cause trouble if (mis)used
263  snowwat = -1 ! to cause trouble if (mis)used
264  graupel = -1 ! to cause trouble if (mis)used
265  cld_amt = -1 ! to cause trouble if (mis)used
266  theta_d = -1 ! to cause trouble if (mis)used
267  end select
268 #else
269  if ( nwat==0 ) then
270  sphum = 1
271  cld_amt = -1 ! to cause trouble if (mis)used
272  else
273  sphum = get_tracer_index(model_atmos, 'sphum')
274  liq_wat = get_tracer_index(model_atmos, 'liq_wat')
275  ice_wat = get_tracer_index(model_atmos, 'ice_wat')
276  rainwat = get_tracer_index(model_atmos, 'rainwat')
277  snowwat = get_tracer_index(model_atmos, 'snowwat')
278  graupel = get_tracer_index(model_atmos, 'graupel')
279  cld_amt = get_tracer_index(model_atmos, 'cld_amt')
280  endif
281  theta_d = get_tracer_index(model_atmos, 'theta_d')
282 #endif
283 
284 #ifdef SW_DYNAMICS
285  akap = 1.
286  pfull(1) = 0.5*flagstruct%p_ref
287 #else
288  akap = kappa
289 
290 !$OMP parallel do default(none) shared(npz,ak,bk,flagstruct,pfull) &
291 !$OMP private(ph1, ph2)
292  do k=1,npz
293  ph1 = ak(k ) + bk(k )*flagstruct%p_ref
294  ph2 = ak(k+1) + bk(k+1)*flagstruct%p_ref
295  pfull(k) = (ph2 - ph1) / log(ph2/ph1)
296  enddo
297 
298  if ( hydrostatic ) then
299 !$OMP parallel do default(none) shared(is,ie,js,je,isd,ied,jsd,jed,npz,dp1,zvir,nwat,q,q_con,sphum,liq_wat, &
300 !$OMP rainwat,ice_wat,snowwat,graupel) private(cvm)
301  do k=1,npz
302  do j=js,je
303 #ifdef USE_COND
304  call moist_cp(is,ie,isd,ied,jsd,jed, npz, j, k, nwat, sphum, liq_wat, rainwat, &
305  ice_wat, snowwat, graupel, q, q_con(is:ie,j,k), cvm)
306 #endif
307  do i=is,ie
308  dp1(i,j,k) = zvir*q(i,j,k,sphum)
309  enddo
310  enddo
311  enddo
312  else
313 !$OMP parallel do default(none) shared(is,ie,js,je,isd,ied,jsd,jed,npz,dp1,zvir,q,q_con,sphum,liq_wat, &
314 !$OMP rainwat,ice_wat,snowwat,graupel,pkz,flagstruct, &
315 !$OMP cappa,kappa,rdg,delp,pt,delz,nwat) &
316 !$OMP private(cvm)
317  do k=1,npz
318  if ( flagstruct%moist_phys ) then
319  do j=js,je
320 #ifdef MOIST_CAPPA
321  call moist_cv(is,ie,isd,ied,jsd,jed, npz, j, k, nwat, sphum, liq_wat, rainwat, &
322  ice_wat, snowwat, graupel, q, q_con(is:ie,j,k), cvm)
323 #endif
324  do i=is,ie
325  dp1(i,j,k) = zvir*q(i,j,k,sphum)
326 #ifdef MOIST_CAPPA
327  cappa(i,j,k) = rdgas/(rdgas + cvm(i)/(1.+dp1(i,j,k)))
328  pkz(i,j,k) = exp(cappa(i,j,k)*log(rdg*delp(i,j,k)*pt(i,j,k)* &
329  (1.+dp1(i,j,k))*(1.-q_con(i,j,k))/delz(i,j,k)) )
330 #else
331  pkz(i,j,k) = exp( kappa*log(rdg*delp(i,j,k)*pt(i,j,k)* &
332  (1.+dp1(i,j,k))/delz(i,j,k)) )
333 ! Using dry pressure for the definition of the virtual potential temperature
334 ! pkz(i,j,k) = exp( kappa*log(rdg*delp(i,j,k)*pt(i,j,k)* &
335 ! (1.-q(i,j,k,sphum))/delz(i,j,k)) )
336 #endif
337  enddo
338  enddo
339  else
340  do j=js,je
341  do i=is,ie
342  dp1(i,j,k) = 0.
343  pkz(i,j,k) = exp(kappa*log(rdg*delp(i,j,k)*pt(i,j,k)/delz(i,j,k)))
344  enddo
345  enddo
346  endif
347  enddo
348  endif
349 
350  if ( flagstruct%fv_debug ) then
351 #ifdef MOIST_CAPPA
352  call prt_mxm('cappa', cappa, is, ie, js, je, ng, npz, 1., gridstruct%area_64, domain)
353 #endif
354  call prt_mxm('PS', ps, is, ie, js, je, ng, 1, 0.01, gridstruct%area_64, domain)
355  call prt_mxm('T_dyn_b', pt, is, ie, js, je, ng, npz, 1., gridstruct%area_64, domain)
356  if ( .not. hydrostatic) call prt_mxm('delz', delz, is, ie, js, je, ng, npz, 1., gridstruct%area_64, domain)
357  call prt_mxm('delp_b ', delp, is, ie, js, je, ng, npz, 0.01, gridstruct%area_64, domain)
358  call prt_mxm('pk_b', pk, is, ie, js, je, 0, npz+1, 1.,gridstruct%area_64, domain)
359  call prt_mxm('pkz_b', pkz,is, ie, js, je, 0, npz, 1.,gridstruct%area_64, domain)
360  endif
361 
362 !---------------------
363 ! Compute Total Energy
364 !---------------------
365  if ( consv_te > 0. .and. (.not.do_adiabatic_init) ) then
366  call compute_total_energy(is, ie, js, je, isd, ied, jsd, jed, npz, &
367  u, v, w, delz, pt, delp, q, dp1, pe, peln, phis, &
368  gridstruct%rsin2, gridstruct%cosa_s, &
369  zvir, cp_air, rdgas, hlv, te_2d, ua, va, teq, &
370  flagstruct%moist_phys, nwat, sphum, liq_wat, rainwat, &
371  ice_wat, snowwat, graupel, hydrostatic, idiag%id_te)
372  if( idiag%id_te>0 ) then
373  used = send_data(idiag%id_te, teq, fv_time)
374 ! te_den=1.E-9*g_sum(teq, is, ie, js, je, ng, area, 0)/(grav*4.*pi*radius**2)
375 ! if(is_master()) write(*,*) 'Total Energy Density (Giga J/m**2)=',te_den
376  endif
377  endif
378 
379  if( (flagstruct%consv_am.or.idiag%id_amdt>0) .and. (.not.do_adiabatic_init) ) then
380  call compute_aam(npz, is, ie, js, je, isd, ied, jsd, jed, gridstruct, bd, &
381  ptop, ua, va, u, v, delp, teq, ps2, m_fac)
382  endif
383 
384  if( flagstruct%tau > 0. ) then
385  if ( gridstruct%grid_type<4 ) then
386  call rayleigh_super(abs(bdt), npx, npy, npz, ks, pfull, phis, flagstruct%tau, u, v, w, pt, &
387  ua, va, delz, gridstruct%agrid, cp_air, rdgas, ptop, hydrostatic, (.not. neststruct%nested), flagstruct%rf_cutoff, gridstruct, domain, bd)
388  else
389  call rayleigh_friction(abs(bdt), npx, npy, npz, ks, pfull, flagstruct%tau, u, v, w, pt, &
390  ua, va, delz, cp_air, rdgas, ptop, hydrostatic, .true., flagstruct%rf_cutoff, gridstruct, domain, bd)
391  endif
392  endif
393 
394 #endif
395 
396 #ifndef SW_DYNAMICS
397 ! Convert pt to virtual potential temperature on the first timestep
398  if ( flagstruct%adiabatic ) then
399 !$OMP parallel do default(none) shared(theta_d,is,ie,js,je,npz,pt,pkz,q)
400  do k=1,npz
401  do j=js,je
402  do i=is,ie
403  pt(i,j,k) = pt(i,j,k)/pkz(i,j,k)
404  enddo
405  enddo
406  if ( theta_d>0 ) then
407  do j=js,je
408  do i=is,ie
409  q(i,j,k,theta_d) = pt(i,j,k)
410  enddo
411  enddo
412  endif
413  enddo
414  else
415 !$OMP parallel do default(none) shared(is,ie,js,je,npz,pt,dp1,pkz,q_con)
416  do k=1,npz
417  do j=js,je
418  do i=is,ie
419 #ifdef USE_COND
420  pt(i,j,k) = pt(i,j,k)*(1.+dp1(i,j,k))*(1.-q_con(i,j,k))/pkz(i,j,k)
421 #else
422  pt(i,j,k) = pt(i,j,k)*(1.+dp1(i,j,k))/pkz(i,j,k)
423 #endif
424  enddo
425  enddo
426  enddo
427  endif
428 #endif
429 
430  last_step = .false.
431  mdt = bdt / real(k_split)
432 
433  if ( idiag%id_mdt > 0 .and. (.not. do_adiabatic_init) ) then
434  allocate ( dtdt_m(is:ie,js:je,npz) )
435 !$OMP parallel do default(none) shared(is,ie,js,je,npz,dtdt_m)
436  do k=1,npz
437  do j=js,je
438  do i=is,ie
439  dtdt_m(i,j,k) = 0.
440  enddo
441  enddo
442  enddo
443  endif
444 
445 !DryMassRoundoffControl
446  allocate(psx(isd:ied,jsd:jed),dpx(is:ie,js:je))
447 #ifdef OVERLOAD_R4
448  do j=js,je
449  do i=is,ie
450  psx(i,j) = pe(i,npz+1,j)
451  dpx(i,j) = 0.0
452  enddo
453  enddo
454 #endif
455  call timing_on('FV_DYN_LOOP')
456  do n_map=1, k_split ! first level of time-split
457  call timing_on('COMM_TOTAL')
458 #ifdef USE_COND
459  call start_group_halo_update(i_pack(11), q_con, domain)
460 #ifdef MOIST_CAPPA
461  call start_group_halo_update(i_pack(12), cappa, domain)
462 #endif
463 #endif
464  call start_group_halo_update(i_pack(1), delp, domain, complete=.false.)
465  call start_group_halo_update(i_pack(1), pt, domain, complete=.true.)
466 #ifndef ROT3
467  call start_group_halo_update(i_pack(8), u, v, domain, gridtype=dgrid_ne)
468 #endif
469  call timing_off('COMM_TOTAL')
470 !$OMP parallel do default(none) shared(isd,ied,jsd,jed,npz,dp1,delp)
471  do k=1,npz
472  do j=jsd,jed
473  do i=isd,ied
474  dp1(i,j,k) = delp(i,j,k)
475  enddo
476  enddo
477  enddo
478 
479  if ( n_map==k_split ) last_step = .true.
480 
481 #ifdef USE_COND
482  call timing_on('COMM_TOTAL')
483  call complete_group_halo_update(i_pack(11), domain)
484 #ifdef MOIST_CAPPA
485  call complete_group_halo_update(i_pack(12), domain)
486 #endif
487  call timing_off('COMM_TOTAL')
488 #endif
489 
490  call timing_on('DYN_CORE')
491  call dyn_core(npx, npy, npz, ng, sphum, nq, mdt, n_split, zvir, cp_air, akap, cappa, grav, hydrostatic, &
492  u, v, w, delz, pt, q, delp, pe, pk, phis, ws, omga, ptop, pfull, ua, va, &
493  uc, vc, mfx, mfy, cx, cy, pkz, peln, q_con, ak, bk, dpx, ks, &
494  gridstruct, flagstruct, neststruct, idiag, bd, &
495  domain, n_map==1, i_pack, last_step, time_total)
496  call timing_off('DYN_CORE')
497 
498 
499 !DryMassRoundoffControl
500  if(last_step) then
501 #ifdef OVERLOAD_R4
502  do j=js,je
503  do i=is,ie
504  psx(i,j) = psx(i,j) + dpx(i,j)
505  enddo
506  enddo
507  call timing_on('COMM_TOTAL')
508  call mpp_update_domains(psx, domain)
509  call timing_off('COMM_TOTAL')
510  do j=js-1,je+1
511  do i=is-1,ie+1
512  pe(i,npz+1,j) = psx(i,j)
513  enddo
514  enddo
515 #endif
516  deallocate(psx,dpx)
517  end if
518 
519 #ifdef SW_DYNAMICS
520 !$OMP parallel do default(none) shared(is,ie,js,je,delp,agrav)
521  do j=js,je
522  do i=is,ie
523  ps(i,j) = delp(i,j,1) * agrav
524  enddo
525  enddo
526 #else
527  if( .not. flagstruct%inline_q .and. nq /= 0 ) then
528 !--------------------------------------------------------
529 ! Perform large-time-step scalar transport using the accumulated CFL and
530 ! mass fluxes
531  call timing_on('tracer_2d')
532  !!! CLEANUP: merge these two calls?
533  if (gridstruct%nested) then
534  call tracer_2d_nested(q, dp1, mfx, mfy, cx, cy, gridstruct, bd, domain, npx, npy, npz, nq, &
535  flagstruct%hord_tr, q_split, mdt, idiag%id_divg, i_pack(10), &
536  flagstruct%nord_tr, flagstruct%trdm2, &
537  k_split, neststruct, parent_grid)
538  else
539  if ( flagstruct%z_tracer ) then
540  call tracer_2d_1l(q, dp1, mfx, mfy, cx, cy, gridstruct, bd, domain, npx, npy, npz, nq, &
541  flagstruct%hord_tr, q_split, mdt, idiag%id_divg, i_pack(10), &
542  flagstruct%nord_tr, flagstruct%trdm2)
543  else
544  call tracer_2d(q, dp1, mfx, mfy, cx, cy, gridstruct, bd, domain, npx, npy, npz, nq, &
545  flagstruct%hord_tr, q_split, mdt, idiag%id_divg, i_pack(10), &
546  flagstruct%nord_tr, flagstruct%trdm2)
547  endif
548  endif
549  call timing_off('tracer_2d')
550 
551  if ( flagstruct%hord_tr<8 .and. flagstruct%moist_phys ) then
552  call timing_on('Fill2D')
553  if ( liq_wat > 0 ) &
554  call fill2d(is, ie, js, je, ng, npz, q(isd,jsd,1,liq_wat), delp, gridstruct%area, domain, neststruct%nested, npx, npy)
555  if ( rainwat > 0 ) &
556  call fill2d(is, ie, js, je, ng, npz, q(isd,jsd,1,rainwat), delp, gridstruct%area, domain, neststruct%nested, npx, npy)
557  if ( ice_wat > 0 ) &
558  call fill2d(is, ie, js, je, ng, npz, q(isd,jsd,1,ice_wat), delp, gridstruct%area, domain, neststruct%nested, npx, npy)
559  if ( snowwat > 0 ) &
560  call fill2d(is, ie, js, je, ng, npz, q(isd,jsd,1,snowwat), delp, gridstruct%area, domain, neststruct%nested, npx, npy)
561  if ( graupel > 0 ) &
562  call fill2d(is, ie, js, je, ng, npz, q(isd,jsd,1,graupel), delp, gridstruct%area, domain, neststruct%nested, npx, npy)
563  call timing_off('Fill2D')
564  endif
565 
566  if( last_step .and. idiag%id_divg>0 ) then
567  used = send_data(idiag%id_divg, dp1, fv_time)
568  if(flagstruct%fv_debug) call prt_mxm('divg', dp1, is, ie, js, je, 0, npz, 1.,gridstruct%area_64, domain)
569  endif
570  endif
571 
572  if ( npz > 4 ) then
573 !------------------------------------------------------------------------
574 ! Perform vertical remapping from Lagrangian control-volume to
575 ! the Eulerian coordinate as specified by the routine set_eta.
576 ! Note that this finite-volume dycore is otherwise independent of the vertical
577 ! Eulerian coordinate.
578 !------------------------------------------------------------------------
579 
580  do iq=1,nq
581  kord_tracer(iq) = flagstruct%kord_tr
582  if ( iq==cld_amt ) kord_tracer(iq) = 9 ! monotonic
583  enddo
584 
585  do_omega = hydrostatic .and. last_step
586  call timing_on('Remapping')
587 #ifdef AVEC_TIMERS
588  call avec_timer_start(6)
589 #endif
590 
591  call lagrangian_to_eulerian(last_step, consv_te, ps, pe, delp, &
592  pkz, pk, mdt, bdt, npz, is,ie,js,je, isd,ied,jsd,jed, &
593  nq, nwat, sphum, q_con, u, v, w, delz, pt, q, phis, &
594  zvir, cp_air, akap, cappa, flagstruct%kord_mt, flagstruct%kord_wz, &
595  kord_tracer, flagstruct%kord_tm, peln, te_2d, &
596  ng, ua, va, omga, dp1, ws, fill, reproduce_sum, &
597  idiag%id_mdt>0, dtdt_m, ptop, ak, bk, pfull, flagstruct, gridstruct, domain, &
598  flagstruct%do_sat_adj, hydrostatic, hybrid_z, do_omega, &
599  flagstruct%adiabatic, do_adiabatic_init, &
600  mfx, mfy, flagstruct%remap_option)
601 
602 #ifdef AVEC_TIMERS
603  call avec_timer_stop(6)
604 #endif
605  call timing_off('Remapping')
606 #ifdef MOIST_CAPPA
607  if ( neststruct%nested .and. .not. last_step) then
608  call nested_grid_bc_apply_intt(cappa, &
609  0, 0, npx, npy, npz, bd, real(n_map+1), real(k_split), &
610  neststruct%cappa_bc, bctype=neststruct%nestbctype )
611  endif
612 #endif
613 
614  if( last_step ) then
615  if( .not. hydrostatic ) then
616 !$OMP parallel do default(none) shared(is,ie,js,je,npz,omga,delp,delz,w)
617  do k=1,npz
618  do j=js,je
619  do i=is,ie
620  omga(i,j,k) = delp(i,j,k)/delz(i,j,k)*w(i,j,k)
621  enddo
622  enddo
623  enddo
624  endif
625 !--------------------------
626 ! Filter omega for physics:
627 !--------------------------
628  if(flagstruct%nf_omega>0) &
629  call del2_cubed(omga, 0.18*gridstruct%da_min, gridstruct, domain, npx, npy, npz, flagstruct%nf_omega, bd)
630  endif
631  end if
632 #endif
633  enddo ! n_map loop
634  call timing_off('FV_DYN_LOOP')
635  if ( idiag%id_mdt > 0 .and. (.not.do_adiabatic_init) ) then
636 ! Output temperature tendency due to inline moist physics:
637 !$OMP parallel do default(none) shared(is,ie,js,je,npz,dtdt_m,bdt)
638  do k=1,npz
639  do j=js,je
640  do i=is,ie
641  dtdt_m(i,j,k) = dtdt_m(i,j,k) / bdt * 86400.
642  enddo
643  enddo
644  enddo
645 ! call prt_mxm('Fast DTDT (deg/Day)', dtdt_m, is, ie, js, je, 0, npz, 1., gridstruct%area_64, domain)
646  used = send_data(idiag%id_mdt, dtdt_m, fv_time)
647  deallocate ( dtdt_m )
648  endif
649 
650  if( nwat==6 ) then
651  if (cld_amt > 0) then
652  call neg_adj3(is, ie, js, je, ng, npz, &
653  flagstruct%hydrostatic, &
654  peln, delz, &
655  pt, delp, q(isd,jsd,1,sphum), &
656  q(isd,jsd,1,liq_wat), &
657  q(isd,jsd,1,rainwat), &
658  q(isd,jsd,1,ice_wat), &
659  q(isd,jsd,1,snowwat), &
660  q(isd,jsd,1,graupel), &
661  q(isd,jsd,1,cld_amt), flagstruct%check_negative)
662  else
663  call neg_adj3(is, ie, js, je, ng, npz, &
664  flagstruct%hydrostatic, &
665  peln, delz, &
666  pt, delp, q(isd,jsd,1,sphum), &
667  q(isd,jsd,1,liq_wat), &
668  q(isd,jsd,1,rainwat), &
669  q(isd,jsd,1,ice_wat), &
670  q(isd,jsd,1,snowwat), &
671  q(isd,jsd,1,graupel), check_negative=flagstruct%check_negative)
672  endif
673  if ( flagstruct%fv_debug ) then
674  call prt_mxm('T_dyn_a3', pt, is, ie, js, je, ng, npz, 1., gridstruct%area_64, domain)
675  call prt_mxm('SPHUM_dyn', q(isd,jsd,1,sphum ), is, ie, js, je, ng, npz, 1.,gridstruct%area_64, domain)
676  call prt_mxm('liq_wat_dyn', q(isd,jsd,1,liq_wat), is, ie, js, je, ng, npz, 1.,gridstruct%area_64, domain)
677  call prt_mxm('rainwat_dyn', q(isd,jsd,1,rainwat), is, ie, js, je, ng, npz, 1.,gridstruct%area_64, domain)
678  call prt_mxm('ice_wat_dyn', q(isd,jsd,1,ice_wat), is, ie, js, je, ng, npz, 1.,gridstruct%area_64, domain)
679  call prt_mxm('snowwat_dyn', q(isd,jsd,1,snowwat), is, ie, js, je, ng, npz, 1.,gridstruct%area_64, domain)
680  call prt_mxm('graupel_dyn', q(isd,jsd,1,graupel), is, ie, js, je, ng, npz, 1.,gridstruct%area_64, domain)
681  endif
682  endif
683 
684  if( (flagstruct%consv_am.or.idiag%id_amdt>0.or.idiag%id_aam>0) .and. (.not.do_adiabatic_init) ) then
685  call compute_aam(npz, is, ie, js, je, isd, ied, jsd, jed, gridstruct, bd, &
686  ptop, ua, va, u, v, delp, te_2d, ps, m_fac)
687  if( idiag%id_aam>0 ) then
688  used = send_data(idiag%id_aam, te_2d, fv_time)
689  if ( prt_minmax ) then
690  gam = g_sum( domain, te_2d, is, ie, js, je, ng, gridstruct%area_64, 0)
691  if( is_master() ) write(6,*) 'Total AAM =', gam
692  endif
693  endif
694  endif
695 
696  if( (flagstruct%consv_am.or.idiag%id_amdt>0) .and. (.not.do_adiabatic_init) ) then
697 !$OMP parallel do default(none) shared(is,ie,js,je,te_2d,teq,dt2,ps2,ps,idiag)
698  do j=js,je
699  do i=is,ie
700 ! Note: the mountain torque computation contains also numerical error
701 ! The numerical error is mostly from the zonal gradient of the terrain (zxg)
702  te_2d(i,j) = te_2d(i,j)-teq(i,j) + dt2*(ps2(i,j)+ps(i,j))*idiag%zxg(i,j)
703  enddo
704  enddo
705  if( idiag%id_amdt>0 ) used = send_data(idiag%id_amdt, te_2d/bdt, fv_time)
706 
707  if ( flagstruct%consv_am .or. prt_minmax ) then
708  amdt = g_sum( domain, te_2d, is, ie, js, je, ng, gridstruct%area_64, 0, reproduce=.true.)
709  u0 = -radius*amdt/g_sum( domain, m_fac, is, ie, js, je, ng, gridstruct%area_64, 0,reproduce=.true.)
710  if(is_master() .and. prt_minmax) &
711  write(6,*) 'Dynamic AM tendency (Hadleys)=', amdt/(bdt*1.e18), 'del-u (per day)=', u0*86400./bdt
712  endif
713 
714  if( flagstruct%consv_am ) then
715 !$OMP parallel do default(none) shared(is,ie,js,je,m_fac,u0,gridstruct)
716  do j=js,je
717  do i=is,ie
718  m_fac(i,j) = u0*cos(gridstruct%agrid(i,j,2))
719  enddo
720  enddo
721 !$OMP parallel do default(none) shared(is,ie,js,je,npz,hydrostatic,pt,m_fac,ua,cp_air, &
722 !$OMP u,u0,gridstruct,v )
723  do k=1,npz
724  do j=js,je+1
725  do i=is,ie
726  u(i,j,k) = u(i,j,k) + u0*gridstruct%l2c_u(i,j)
727  enddo
728  enddo
729  do j=js,je
730  do i=is,ie+1
731  v(i,j,k) = v(i,j,k) + u0*gridstruct%l2c_v(i,j)
732  enddo
733  enddo
734  enddo
735  endif ! consv_am
736  endif
737 
738 911 call cubed_to_latlon(u, v, ua, va, gridstruct, &
739  npx, npy, npz, 1, gridstruct%grid_type, domain, gridstruct%nested, flagstruct%c2l_ord, bd)
740 
741  deallocate(dp1)
742  deallocate(cappa)
743 
744  if ( flagstruct%fv_debug ) then
745  call prt_mxm('UA', ua, is, ie, js, je, ng, npz, 1., gridstruct%area_64, domain)
746  call prt_mxm('VA', va, is, ie, js, je, ng, npz, 1., gridstruct%area_64, domain)
747  call prt_mxm('TA', pt, is, ie, js, je, ng, npz, 1., gridstruct%area_64, domain)
748  if (.not. hydrostatic) call prt_mxm('W ', w, is, ie, js, je, ng, npz, 1., gridstruct%area_64, domain)
749  endif
750 
751  if ( flagstruct%range_warn ) then
752  call range_check('UA_dyn', ua, is, ie, js, je, ng, npz, gridstruct%agrid, &
753  -280., 280., bad_range)
754  call range_check('VA_dyn', ua, is, ie, js, je, ng, npz, gridstruct%agrid, &
755  -280., 280., bad_range)
756  call range_check('TA_dyn', pt, is, ie, js, je, ng, npz, gridstruct%agrid, &
757  150., 335., bad_range)
758  if ( .not. hydrostatic ) &
759  call range_check('W_dyn', w, is, ie, js, je, ng, npz, gridstruct%agrid, &
760  -50., 100., bad_range)
761  endif
762 
763 !#ifdef MAPL_MODE
764 ! t2 = MPI_Wtime(status)
765 ! dyn_timer = dyn_timer + (t2-t1)
766 !#endif
767  end subroutine fv_dynamics
768 
769 
770  subroutine rayleigh_super(dt, npx, npy, npz, ks, pm, phis, tau, u, v, w, pt, &
771  ua, va, delz, agrid, cp, rg, ptop, hydrostatic, conserve, rf_cutoff, gridstruct, domain, bd)
772  real, intent(in):: dt
773  real, intent(in):: tau ! time scale (days)
774  real, intent(in):: cp, rg, ptop, rf_cutoff
775  real, intent(in), dimension(npz):: pm
776  integer, intent(in):: npx, npy, npz, ks
777  logical, intent(in):: hydrostatic
778  logical, intent(in):: conserve
779  type(fv_grid_bounds_type), intent(IN) :: bd
780  real, intent(inout):: u(bd%isd:bd%ied ,bd%jsd:bd%jed+1,npz) ! D grid zonal wind (m/s)
781  real, intent(inout):: v(bd%isd:bd%ied+1,bd%jsd:bd%jed,npz) ! D grid meridional wind (m/s)
782  real, intent(inout):: w(bd%isd: ,bd%jsd: ,1: ) ! cell center vertical wind (m/s)
783  real, intent(inout):: pt(bd%isd:bd%ied,bd%jsd:bd%jed,npz) ! temp
784  real, intent(inout):: ua(bd%isd:bd%ied,bd%jsd:bd%jed,npz) !
785  real, intent(inout):: va(bd%isd:bd%ied,bd%jsd:bd%jed,npz) !
786  real, intent(inout):: delz(bd%isd: ,bd%jsd: ,1: ) ! delta-height (m); non-hydrostatic only
787  real, intent(in) :: agrid(bd%isd:bd%ied, bd%jsd:bd%jed,2)
788  real, intent(in) :: phis(bd%isd:bd%ied,bd%jsd:bd%jed) ! Surface geopotential (g*Z_surf)
789  type(fv_grid_type), intent(IN) :: gridstruct
790  type(domain2d), intent(INOUT) :: domain
791 !
792  real, allocatable :: u2f(:,:,:)
793  real, parameter:: u0 = 60. ! scaling velocity
794  real, parameter:: sday = 86400.
795  real rcv, tau0
796  integer i, j, k
797 
798  integer :: is, ie, js, je
799  integer :: isd, ied, jsd, jed
800 
801  is = bd%is
802  ie = bd%ie
803  js = bd%js
804  je = bd%je
805  isd = bd%isd
806  ied = bd%ied
807  jsd = bd%jsd
808  jed = bd%jed
809 
810  rcv = 1. / (cp - rg)
811 
812  if ( .not. rf_initialized ) then
813 #ifdef HIWPP
814  allocate ( u00(is:ie, js:je+1,npz) )
815  allocate ( v00(is:ie+1,js:je ,npz) )
816 !$OMP parallel do default(none) shared(is,ie,js,je,npz,u00,u,v00,v)
817  do k=1,npz
818  do j=js,je+1
819  do i=is,ie
820  u00(i,j,k) = u(i,j,k)
821  enddo
822  enddo
823  do j=js,je
824  do i=is,ie+1
825  v00(i,j,k) = v(i,j,k)
826  enddo
827  enddo
828  enddo
829 #endif
830 #ifdef SMALL_EARTH
831  tau0 = tau
832 #else
833  tau0 = tau * sday
834 #endif
835  allocate( rf(npz) )
836  rf(:) = 0.
837 
838  do k=1, ks+1
839  if( is_master() ) write(6,*) k, 0.01*pm(k)
840  enddo
841  if( is_master() ) write(6,*) 'Rayleigh friction E-folding time (days):'
842  do k=1, npz
843  if ( pm(k) < rf_cutoff ) then
844  rf(k) = dt/tau0*sin(0.5*pi*log(rf_cutoff/pm(k))/log(rf_cutoff/ptop))**2
845  if( is_master() ) write(6,*) k, 0.01*pm(k), dt/(rf(k)*sday)
846  kmax = k
847  else
848  exit
849  endif
850  enddo
851  rf_initialized = .true.
852  endif
853 
854  call c2l_ord2(u, v, ua, va, gridstruct, npz, gridstruct%grid_type, bd, gridstruct%nested)
855 
856  allocate( u2f(isd:ied,jsd:jed,kmax) )
857 
858 !$OMP parallel do default(none) shared(is,ie,js,je,kmax,pm,rf_cutoff,hydrostatic,ua,va,agrid, &
859 !$OMP u2f,rf,w)
860  do k=1,kmax
861  if ( pm(k) < rf_cutoff ) then
862  u2f(:,:,k) = 1. / (1.+rf(k))
863  else
864  u2f(:,:,k) = 1.
865  endif
866  enddo
867  call timing_on('COMM_TOTAL')
868  call mpp_update_domains(u2f, domain)
869  call timing_off('COMM_TOTAL')
870 
871 !$OMP parallel do default(none) shared(is,ie,js,je,kmax,pm,rf_cutoff,w,rf,u,v, &
872 #ifdef HIWPP
873 !$OMP u00,v00, &
874 #endif
875 !$OMP conserve,hydrostatic,pt,ua,va,u2f,cp,rg,ptop,rcv)
876  do k=1,kmax
877  if ( pm(k) < rf_cutoff ) then
878 #ifdef HIWPP
879  if (.not. hydrostatic) then
880  do j=js,je
881  do i=is,ie
882  w(i,j,k) = w(i,j,k)/(1.+rf(k))
883  enddo
884  enddo
885  endif
886  do j=js,je+1
887  do i=is,ie
888  u(i,j,k) = (u(i,j,k)+rf(k)*u00(i,j,k))/(1.+rf(k))
889  enddo
890  enddo
891  do j=js,je
892  do i=is,ie+1
893  v(i,j,k) = (v(i,j,k)+rf(k)*v00(i,j,k))/(1.+rf(k))
894  enddo
895  enddo
896 #else
897 ! Add heat so as to conserve TE
898  if ( conserve ) then
899  if ( hydrostatic ) then
900  do j=js,je
901  do i=is,ie
902  pt(i,j,k) = pt(i,j,k) + 0.5*(ua(i,j,k)**2+va(i,j,k)**2)*(1.-u2f(i,j,k)**2)/(cp-rg*ptop/pm(k))
903  enddo
904  enddo
905  else
906  do j=js,je
907  do i=is,ie
908  pt(i,j,k) = pt(i,j,k) + 0.5*(ua(i,j,k)**2+va(i,j,k)**2+w(i,j,k)**2)*(1.-u2f(i,j,k)**2)*rcv
909  enddo
910  enddo
911  endif
912  endif
913 
914  do j=js,je+1
915  do i=is,ie
916  u(i,j,k) = 0.5*(u2f(i,j-1,k)+u2f(i,j,k))*u(i,j,k)
917  enddo
918  enddo
919  do j=js,je
920  do i=is,ie+1
921  v(i,j,k) = 0.5*(u2f(i-1,j,k)+u2f(i,j,k))*v(i,j,k)
922  enddo
923  enddo
924  if ( .not. hydrostatic ) then
925  do j=js,je
926  do i=is,ie
927  w(i,j,k) = u2f(i,j,k)*w(i,j,k)
928  enddo
929  enddo
930  endif
931 #endif
932  endif
933  enddo
934 
935  deallocate ( u2f )
936 
937  end subroutine rayleigh_super
938 
939 
940  subroutine rayleigh_friction(dt, npx, npy, npz, ks, pm, tau, u, v, w, pt, &
941  ua, va, delz, cp, rg, ptop, hydrostatic, conserve, &
942  rf_cutoff, gridstruct, domain, bd)
943  real, intent(in):: dt
944  real, intent(in):: tau ! time scale (days)
945  real, intent(in):: cp, rg, ptop, rf_cutoff
946  real, intent(in), dimension(npz):: pm
947  integer, intent(in):: npx, npy, npz, ks
948  logical, intent(in):: hydrostatic
949  logical, intent(in):: conserve
950  type(fv_grid_bounds_type), intent(IN) :: bd
951  real, intent(inout):: u(bd%isd:bd%ied ,bd%jsd:bd%jed+1,npz) ! D grid zonal wind (m/s)
952  real, intent(inout):: v(bd%isd:bd%ied+1,bd%jsd:bd%jed,npz) ! D grid meridional wind (m/s)
953  real, intent(inout):: w(bd%isd: ,bd%jsd: ,1: ) ! cell center vertical wind (m/s)
954  real, intent(inout):: pt(bd%isd:bd%ied,bd%jsd:bd%jed,npz) ! temp
955  real, intent(inout):: ua(bd%isd:bd%ied,bd%jsd:bd%jed,npz) !
956  real, intent(inout):: va(bd%isd:bd%ied,bd%jsd:bd%jed,npz) !
957  real, intent(inout):: delz(bd%isd: ,bd%jsd: ,1: ) ! delta-height (m); non-hydrostatic only
958  type(fv_grid_type), intent(IN) :: gridstruct
959  type(domain2d), intent(INOUT) :: domain
960 ! local:
961  real, allocatable :: u2f(:,:,:)
962  real, parameter:: sday = 86400.
963  real, parameter:: u000 = 4900. ! scaling velocity **2
964  real rcv
965  integer i, j, k
966 
967  integer :: is, ie, js, je
968  integer :: isd, ied, jsd, jed
969 
970 
971  is = bd%is
972  ie = bd%ie
973  js = bd%js
974  je = bd%je
975  isd = bd%isd
976  ied = bd%ied
977  jsd = bd%jsd
978  jed = bd%jed
979 
980 
981  rcv = 1. / (cp - rg)
982 
983  if ( .not. rf_initialized ) then
984  allocate( rf(npz) )
985  if( is_master() ) write(6,*) 'Rayleigh friction E-folding time (days):'
986  do k=1, npz
987  if ( pm(k) < rf_cutoff ) then
988  rf(k) = dt/(tau*sday)*sin(0.5*pi*log(rf_cutoff/pm(k))/log(rf_cutoff/ptop))**2
989  if( is_master() ) write(6,*) k, 0.01*pm(k), dt/(rf(k)*sday)
990  kmax = k
991  else
992  exit
993  endif
994  enddo
995  rf_initialized = .true.
996  endif
997 
998  allocate( u2f(isd:ied,jsd:jed,kmax) )
999 
1000  call c2l_ord2(u, v, ua, va, gridstruct, npz, gridstruct%grid_type, bd, gridstruct%nested)
1001 
1002 !$OMP parallel do default(none) shared(is,ie,js,je,kmax,u2f,hydrostatic,ua,va,w)
1003  do k=1,kmax
1004  if ( hydrostatic ) then
1005  do j=js,je
1006  do i=is,ie
1007  u2f(i,j,k) = ua(i,j,k)**2 + va(i,j,k)**2
1008  enddo
1009  enddo
1010  else
1011  do j=js,je
1012  do i=is,ie
1013  u2f(i,j,k) = ua(i,j,k)**2 + va(i,j,k)**2 + w(i,j,k)**2
1014  enddo
1015  enddo
1016  endif
1017  enddo
1018 
1019  call timing_on('COMM_TOTAL')
1020  call mpp_update_domains(u2f, domain)
1021  call timing_off('COMM_TOTAL')
1022 
1023 !$OMP parallel do default(none) shared(is,ie,js,je,kmax,conserve,hydrostatic,pt,u2f,cp,rg, &
1024 !$OMP ptop,pm,rf,delz,rcv,u,v,w)
1025  do k=1,kmax
1026 
1027  if ( conserve ) then
1028  if ( hydrostatic ) then
1029  do j=js,je
1030  do i=is,ie
1031  pt(i,j,k) = pt(i,j,k) + 0.5*u2f(i,j,k)/(cp-rg*ptop/pm(k)) &
1032  * ( 1. - 1./(1.+rf(k)*sqrt(u2f(i,j,k)/u000))**2 )
1033  enddo
1034  enddo
1035  else
1036  do j=js,je
1037  do i=is,ie
1038  delz(i,j,k) = delz(i,j,k) / pt(i,j,k)
1039  pt(i,j,k) = pt(i,j,k) + 0.5*u2f(i,j,k) * rcv &
1040  * ( 1. - 1./(1.+rf(k)*sqrt(u2f(i,j,k)/u000))**2 )
1041  delz(i,j,k) = delz(i,j,k) * pt(i,j,k)
1042  enddo
1043  enddo
1044  endif
1045  endif
1046 
1047  do j=js-1,je+1
1048  do i=is-1,ie+1
1049  u2f(i,j,k) = rf(k)*sqrt(u2f(i,j,k)/u000)
1050  enddo
1051  enddo
1052 
1053  do j=js,je+1
1054  do i=is,ie
1055  u(i,j,k) = u(i,j,k) / (1.+0.5*(u2f(i,j-1,k)+u2f(i,j,k)))
1056  enddo
1057  enddo
1058  do j=js,je
1059  do i=is,ie+1
1060  v(i,j,k) = v(i,j,k) / (1.+0.5*(u2f(i-1,j,k)+u2f(i,j,k)))
1061  enddo
1062  enddo
1063 
1064  if ( .not. hydrostatic ) then
1065  do j=js,je
1066  do i=is,ie
1067  w(i,j,k) = w(i,j,k) / (1.+u2f(i,j,k))
1068  enddo
1069  enddo
1070  endif
1071 
1072  enddo
1073 
1074  deallocate ( u2f )
1075 
1076  end subroutine rayleigh_friction
1077 
1078  subroutine compute_aam(npz, is, ie, js, je, isd, ied, jsd, jed, gridstruct, bd, &
1079  ptop, ua, va, u, v, delp, aam, ps, m_fac)
1080 ! Compute vertically (mass) integrated Atmospheric Angular Momentum
1081  integer, intent(in):: npz
1082  integer, intent(in):: is, ie, js, je
1083  integer, intent(in):: isd, ied, jsd, jed
1084  real, intent(in):: ptop
1085  real, intent(inout):: u(isd:ied ,jsd:jed+1,npz) ! D grid zonal wind (m/s)
1086  real, intent(inout):: v(isd:ied+1,jsd:jed,npz) ! D grid meridional wind (m/s)
1087  real, intent(inout):: delp(isd:ied,jsd:jed,npz)
1088  real, intent(inout), dimension(isd:ied,jsd:jed, npz):: ua, va
1089  real, intent(out):: aam(is:ie,js:je)
1090  real, intent(out):: m_fac(is:ie,js:je)
1091  real, intent(out):: ps(isd:ied,jsd:jed)
1092  type(fv_grid_bounds_type), intent(IN) :: bd
1093  type(fv_grid_type), intent(IN) :: gridstruct
1094 ! local:
1095  real, dimension(is:ie):: r1, r2, dm
1096  integer i, j, k
1097 
1098  call c2l_ord2(u, v, ua, va, gridstruct, npz, gridstruct%grid_type, bd, gridstruct%nested)
1099 
1100 !$OMP parallel do default(none) shared(is,ie,js,je,npz,gridstruct,aam,m_fac,ps,ptop,delp,agrav,ua) &
1101 !$OMP private(r1, r2, dm)
1102  do j=js,je
1103  do i=is,ie
1104  r1(i) = radius*cos(gridstruct%agrid(i,j,2))
1105  r2(i) = r1(i)*r1(i)
1106  aam(i,j) = 0.
1107  m_fac(i,j) = 0.
1108  ps(i,j) = ptop
1109  enddo
1110  do k=1,npz
1111  do i=is,ie
1112  dm(i) = delp(i,j,k)
1113  ps(i,j) = ps(i,j) + dm(i)
1114  dm(i) = dm(i)*agrav
1115  aam(i,j) = aam(i,j) + (r2(i)*omega + r1(i)*ua(i,j,k)) * dm(i)
1116  m_fac(i,j) = m_fac(i,j) + dm(i)*r2(i)
1117  enddo
1118  enddo
1119  enddo
1120 
1121  end subroutine compute_aam
1122 
1123 end module fv_dynamics_nlm_mod
subroutine, public del2_cubed(q, cd, gridstruct, domain, npx, npy, km, nmax, bd)
real, parameter, public radius
Radius of the Earth [m].
Definition: constants.F90:72
integer, parameter, public model_atmos
real, parameter, public omega
Rotation rate of the Earth [1/s].
Definition: constants.F90:75
subroutine, public moist_cv(is, ie, isd, ied, jsd, jed, km, j, k, nwat, sphum, liq_wat, rainwat, ice_wat, snowwat, graupel, q, qd, cvm, t1)
subroutine, public setup_nested_grid_bcs(npx, npy, npz, zvir, ncnst, u, v, w, pt, delp, delz, q, uc, vc, pkz, nested, inline_q, make_nh, ng, gridstruct, flagstruct, neststruct, nest_timestep, tracer_nest_timestep, domain, bd, nwat)
subroutine, public nested_grid_bc_apply_intt(var_nest, istag, jstag, npx, npy, npz, bd, step, split, BC, bctype)
real(kind=8), parameter, public pi_8
Ratio of circle circumference to diameter [N/A].
Definition: constants.F90:73
subroutine rayleigh_friction(dt, npx, npy, npz, ks, pm, tau, u, v, w, pt, ua, va, delz, cp, rg, ptop, hydrostatic, conserve, rf_cutoff, gridstruct, domain, bd)
real, parameter, public hlv
Latent heat of evaporation [J/kg].
Definition: constants.F90:80
subroutine, public tracer_2d_1l(q, dp1, mfx, mfy, cx, cy, gridstruct, bd, domain, npx, npy, npz, nq, hord, q_split, dt, id_divg, q_pack, nord_tr, trdm, dpA)
subroutine, public lagrangian_to_eulerian(last_step, consv, ps, pe, delp, pkz, pk, mdt, pdt, km, is, ie, js, je, isd, ied, jsd, jed, nq, nwat, sphum, q_con, u, v, w, delz, pt, q, hs, r_vir, cp, akap, cappa, kord_mt, kord_wz, kord_tr, kord_tm, peln, te0_2d, ng, ua, va, omga, te, ws, fill, reproduce_sum, out_dt, dtdt, ptop, ak, bk, pfull, flagstruct, gridstruct, domain, do_sat_adj, hydrostatic, hybrid_z, do_omega, adiabatic, do_adiabatic_init, mfx, mfy, remap_option)
Definition: fv_mapz_nlm.F90:68
real, parameter, public rdgas
Gas constant for dry air [J/kg/deg].
Definition: constants.F90:77
real, parameter, public cp_vapor
Specific heat capacity of water vapor at constant pressure [J/kg/deg].
Definition: constants.F90:89
subroutine, public cubed_to_latlon(u, v, ua, va, gridstruct, npx, npy, km, mode, grid_type, domain, nested, c2l_ord, bd)
Definition: mpp.F90:39
real, dimension(:), allocatable rf
subroutine, public c2l_ord2(u, v, ua, va, gridstruct, km, grid_type, bd, do_halo)
real, parameter, public rvgas
Gas constant for water vapor [J/kg/deg].
Definition: constants.F90:78
subroutine, public moist_cp(is, ie, isd, ied, jsd, jed, km, j, k, nwat, sphum, liq_wat, rainwat, ice_wat, snowwat, graupel, q, qd, cpm, t1)
subroutine timing_on(blk_name)
subroutine compute_aam(npz, is, ie, js, je, isd, ied, jsd, jed, gridstruct, bd, ptop, ua, va, u, v, delp, aam, ps, m_fac)
subroutine, public compute_total_energy(is, ie, js, je, isd, ied, jsd, jed, km, u, v, w, delz, pt, delp, q, qc, pe, peln, hs, rsin2_l, cosa_s_l, r_vir, cp, rg, hlv, te_2d, ua, va, teq, moist_phys, nwat, sphum, liq_wat, rainwat, ice_wat, snowwat, graupel, hydrostatic, id_te)
logical, public do_adiabatic_init
subroutine, public dyn_core(npx, npy, npz, ng, sphum, nq, bdt, n_split, zvir, cp, akap, cappa, grav, hydrostatic, u, v, w, delz, pt, q, delp, pe, pk, phis, ws, omga, ptop, pfull, ua, va, uc, vc, mfx, mfy, cx, cy, pkz, peln, q_con, ak, bk, dpx, ks, gridstruct, flagstruct, neststruct, idiag, bd, domain, init_step, i_pack, end_step, time_total)
subroutine, public fv_dynamics(npx, npy, npz, nq_tot, ng, bdt, consv_te, fill, reproduce_sum, kappa, cp_air, zvir, ptop, ks, ncnst, n_split, q_split, u, v, w, delz, hydrostatic, pt, delp, q, ps, pe, pk, peln, pkz, phis, q_con, omga, ua, va, uc, vc, ak, bk, mfx, mfy, cx, cy, ze0, hybrid_z, gridstruct, flagstruct, neststruct, idiag, bd, parent_grid, domain, time_total)
real, parameter, public grav
Acceleration due to gravity [m/s^2].
Definition: constants.F90:76
real function, public g_sum(domain, p, ifirst, ilast, jfirst, jlast, ngc, area, mode, reproduce)
subroutine, public neg_adj3(is, ie, js, je, ng, kbot, hydrostatic, peln, delz, pt, dp, qv, ql, qr, qi, qs, qg, qa, check_negative)
Definition: fv_sg_nlm.F90:1132
subroutine, public prt_mxm(qname, q, is, ie, js, je, n_g, km, fac, area, domain)
subroutine rayleigh_super(dt, npx, npy, npz, ks, pm, phis, tau, u, v, w, pt, ua, va, delz, agrid, cp, rg, ptop, hydrostatic, conserve, rf_cutoff, gridstruct, domain, bd)
subroutine, public init_ijk_mem(i1, i2, j1, j2, km, array, var)
subroutine, public tracer_2d(q, dp1, mfx, mfy, cx, cy, gridstruct, bd, domain, npx, npy, npz, nq, hord, q_split, dt, id_divg, q_pack, nord_tr, trdm, dpA)
subroutine, public fill2d(is, ie, js, je, ng, km, q, delp, area, domain, nested, npx, npy)
subroutine, public range_check(qname, q, is, ie, js, je, n_g, km, pos, q_low, q_hi, bad_range)
type(time_type), public fv_time
real(fp), parameter, public pi
subroutine timing_off(blk_name)
subroutine, public tracer_2d_nested(q, dp1, mfx, mfy, cx, cy, gridstruct, bd, domain, npx, npy, npz, nq, hord, q_split, dt, id_divg, q_pack, nord_tr, trdm, k_split, neststruct, parent_grid)