ROMS
Loading...
Searching...
No Matches
mod_nesting.F
Go to the documentation of this file.
1#include "cppdefs.h"
3
4#ifdef NESTING
5!
6!git $Id$
7!================================================== Hernan G. Arango ===
8! Copyright (c) 2002-2025 The ROMS Group !
9! Licensed under a MIT/X style license !
10! See License_ROMS.md !
11!=======================================================================
12! !
13! This module defines structures for composite and refinement grids. !
14! !
15! Composite Grids Structure: Donor grid data at contact points !
16! ========================= !
17! !
18! bustr Kinematic bottom momentum flux (bottom stress) in the !
19! XI-direction (m2/s2) at U-points. !
20! bvstr Kinematic bottom momentum flux (bottom stress) in the !
21! ETA-direction (m2/s2) at V-points. !
22! rzeta Right-hand-side of free surface equation (m3/s). !
23! ubar Vertically integrated U-momentum component (m/s). !
24! vbar Vertically integrated V-momentum component (m/s). !
25! zeta Free surface (m). !
26# ifdef SOLVE3D
27! !
28! DU_avg1 Time averaged U-flux for 2D equations (m3/s). !
29! DV_avg1 Time averaged V-flux for 2D equations (m3/s). !
30! Huon Total U-momentum flux term, Hz*u/pn. !
31! Hvom Total V-momentum flux term, Hz*v/pm. !
32! Zt_avg1 Free-surface averaged over all short time-steps (m). !
33! t Tracer type variables (active and passive). !
34! u 3D U-momentum component (m/s). !
35! v 3D U-momentum component (m/s). !
36# endif
37! !
38! REFINED Grids Structure: Donor grid data at contact points !
39! ======================= (two-time rolling snapshots) !
40! !
41! ubar Vertically integrated U-momentum component (m/s). !
42! vbar Vertically integrated V-momentum component (m/s). !
43! zeta Free surface (m). !
44# ifndef SOLVE3D
45! U2d_flux U-flux for 2D equations transport (m3/s). !
46! V2d_flux V-flux for 2D equations transport (m3/s). !
47# else
48! !
49! U2d_flux Time averaged U-flux for 3D equations coupling (m3/s). !
50! V2d_flux Time averaged V-flux for 3D equations coupling (m3/s). !
51! t Tracer type variables (active and passive). !
52! u 3D U-momentum component (m/s). !
53! v 3D U-momentum component (m/s). !
54# endif
55! !
56!=======================================================================
57!
58 USE mod_kinds
59!
60 implicit none
61!
62 PUBLIC :: allocate_nesting
63 PUBLIC :: deallocate_nesting
64 PUBLIC :: initialize_nesting
65!
66!-----------------------------------------------------------------------
67! Nesting identification index of variables to process.
68!-----------------------------------------------------------------------
69!
70! The following identification indices are used in "initial" or
71! "main2d/main3d" to specify the variables that are processed in
72! each sub-timestep section. Negative indices are used in grid
73! refinement whereas positive indices are used in composite grids.
74!
75 integer, parameter :: nmflx = -6 ! check mass flux conservation
76 integer, parameter :: ndxdy = -5 ! extract on_u and om_v
77 integer, parameter :: ngetd = -4 ! extract donor grid data
78 integer, parameter :: nmask = -3 ! scale interpolation weights
79 integer, parameter :: nputd = -2 ! fill contact points
80 integer, parameter :: n2way = -1 ! fine to course coupling
81!
82 integer, parameter :: nfsic = 1 ! free surface initialization
83 integer, parameter :: n2dic = 2 ! 2D momentum initialization
84 integer, parameter :: n3dic = 3 ! 3D momentum initialization
85 integer, parameter :: ntvic = 4 ! tracers initialization
86 integer, parameter :: nbstr = 5 ! bottom stress (bustr,bvstr)
87 integer, parameter :: nrhst = 6 ! RHS terms (tracers)
88 integer, parameter :: nzeta = 7 ! 3D kernel free-surface
89 integer, parameter :: nzwgt = 8 ! 3D vertical weights
90 integer, parameter :: n2dps = 9 ! 2D engine Predictor Step
91 integer, parameter :: n2dcs = 10 ! 2D engine Corrector Step
92 integer, parameter :: n2dfx = 11 ! time-averaged 2D fluxes
93 integer, parameter :: n3duv = 12 ! 3D momentum and fluxes
94 integer, parameter :: n3dtv = 13 ! 3D tracer variables
95!
96!-----------------------------------------------------------------------
97! Nesting parameters.
98!-----------------------------------------------------------------------
99!
100! Nested grid connectivity switches. It is used to determine the
101! dimensions of the numerical kernel allocatable arrays. The arrays
102! have extra points due to the contact regions in any of sides
103! of the physical grid (1=iwest, 2=isouth, 3=ieast, 4=inorth).
104!
105 logical, allocatable :: contactregion(:,:) ! [4,Ngrids]
106!
107! Logical switch indicating which coarser grid is a donor to a
108! finer receiver grid (RefineScale(rg) > 0) external contact points.
109! This switch is in terms of the donor coarser grid.
110!
111 logical, allocatable :: donortofiner(:) ! {Ngrids]
112!$OMP THREADPRIVATE (DonorToFiner)
113!
114! Switch indicating which refined grid(s), with RefineScale(ng) > 0,
115! include finer refined grids inside: telescoping refinement.
116!
117 logical, allocatable :: telescoping(:) ! [Ngrids]
118!$OMP THREADPRIVATE (Telescoping)
119!
120! Switch to compute depth-dependent, vertical interpolation weights.
121! Currently, vertical weights are used in composite grids because
122! their grids are not coincident. They are not needed in refinement
123! grids because the donor and receiver grids have the same number of
124! vertical levels and have matching bathymetry. However, in the
125! future, it is possible to have configurations that require vertical
126! weights in refinement. The switch "get_Vweights" controls if such
127! weights are computed or not. If false, it will accelerate the
128! computations because of less distributed-memory communications.
129!
130 logical :: get_vweights
131!$OMP THREADPRIVATE (get_Vweights)
132!
133! If refinement, it contains the coarser donor grid number to finer
134! receiver grid external contact points. The donor grid is always
135! coarser that receiver grid. This variable is in terms of the
136! finer receiver grid.
137!
138 integer, allocatable :: coarserdonor(:) ! [Ngrids]
139!$OMP THREADPRIVATE (CoarserDonor)
140!
141! If refinement and two-way exchange, it contains the donor finer
142! grid number to a coarser receiver grid. This variable is in
143! terms of the coarser donor grid.
144!
145 integer, allocatable :: finerdonor(:) ! [Ngrids]
146!$OMP THREADPRIVATE (FinerDonor)
147!
148! Number of refined time-steps. In most cases, the number of refined
149! time-step is the same as the refinement scale ratio for numerical
150! stability. However, the user is allowed to take larger divisible
151! time-step with respect to the donor grid. The variable below is
152! computed donor and receiver time-step ratio from standard input.
153! It is up to the user to determine the appropiate time-step for
154! stability.
155!
156 integer, allocatable :: refinesteps(:) ! [Ngrids]
157!$OMP THREADPRIVATE (RefineSteps)
158!
159! Refined time-steps counter with respect the coarse grid (ng=1)
160! single time-step.
161!
162 integer, allocatable :: refinestepscounter(:) ! [Ngrids]
163!
164! Interval used in the two-way exchange between fine and coarse
165! grids.
166!
167 real(r8), allocatable :: twowayinterval(:) ! [Ngrids]
168!
169! Donor and reciver grids for each contact region. These paremeters
170! are also duplicated in the T_NGC structure.
171!
172 integer, allocatable :: donor_grid(:) ! [Ncontact]
173 integer, allocatable :: receiver_grid(:) ! [Ncontact]
174!
175! Rolling index and time (seconds) used in the temporal interpolation
176! of contact point data.
177!
178 integer, allocatable :: rollingindex(:) ! [Ncontact]
179 real(dp), allocatable :: rollingtime(:,:) ! [Ncontact]
180!$OMP THREADPRIVATE (RollingIndex, RollingTime)
181!
182! If refinement, donor grid (I,J) indices at PSI points used to extract
183! refined grid. Values are set to -999 if not applicable.
184!
185! +---------+ J_top
186! | |
187! | Refined |
188! | grid |
189! | |
190! +---------+ J_bottom
191! I_left I_right
192!
193 integer, allocatable :: i_left(:) ! [Ngrids]
194 integer, allocatable :: i_right(:) ! [Ngrids]
195 integer, allocatable :: j_bottom(:) ! [Ngrids]
196 integer, allocatable :: j_top(:) ! [Ngrids]
197!
198! Compact arrays used to unpack data from nested grids contact points
199! NetCDF file. They are allocated to the size "datum" dimension in
200! routine "set_contact". The start and end indices for each C-type
201! variable are used to unpack from compact vector.
202!
203 integer :: ncdatum
204 integer, allocatable :: ncpoints(:) ! [Ncontact]
205 integer, allocatable :: nstrr(:), nendr(:) ! [Ncontact]
206 integer, allocatable :: nstru(:), nendu(:) ! [Ncontact]
207 integer, allocatable :: nstrv(:), nendv(:) ! [Ncontact]
208!
209 integer, allocatable :: contact_region(:) ! [NCdatum]
210 integer, allocatable :: on_boundary(:) ! [NCdatum]
211 integer, allocatable :: idg_cp(:) ! [NCdatum]
212 integer, allocatable :: jdg_cp(:) ! [NCdatum]
213 integer, allocatable :: irg_cp(:) ! [NCdatum]
214 integer, allocatable :: jrg_cp(:) ! [NCdatum]
215!
216!-----------------------------------------------------------------------
217! Nested grid connectivity (NGC) structure.
218!-----------------------------------------------------------------------
219!
220! This structure is used to store all the connectivity information
221! between nested grids. It will be used extensively when processing
222! contact region points between data donor and data receiver grids.
223! The nested grid contact region information is processed outside of
224! ROMS and read from a NetCDF file for functionality and efficiency.
225!
226! In nested grids, the value in the contact region are interpolated
227! from the data donor grid cell using the following conventions at
228! the horizontal location in receiver grid (Irg,Jrg) and donor grid
229! cell (Idg,Jdg):
230!
231! suffix 'dg' = donor grid
232! 'rg' = receiver grid
233!
234! 4---------------3 (Idg+1,Jdg+1) weight(1) = (1-p) * (1-q)
235! | . | weight(2) = p * (1-q)
236! | 1-q . | weight(3) = p * q
237! | . | weight(4) = (1-p) * q
238! | . p |
239! Jrg |....... x .....| Linear interpolation:
240! | 1-p . |
241! | . q | V(Irg,Jrg) = weight(1) * F(Idg ,Jdg )+
242! | . | weight(2) * F(Idg+1,Jdg )+
243! (Idg,Jdg) 1---------------2 weight(3) * F(Idg+1,Jdg+1)+
244! Irg weight(4) * F(Idg ,Jdg+1)
245!
246! Notice that if p=0 and q=0 at all contact points, the donor and
247! receiver grids are coincident since weight(1)=1.0 and weight(2:3)=0.
248! Therefore, the above formula is generic for any nested grid
249! configuration.
250!
251! If Land/Sea masking, the interpolation weights are rescaled in
252! "mask_weights" during initialization to account masked points in
253! the contact regions. If wetting and drying, the rescaling is done
254! at every time step since the land/sea masking is time dependent.
255!
256 integer :: ncontact ! total number of contact regions
257!
258 TYPE t_ngc
259 logical :: coincident ! coincident donor/receiver, p=q=0
260 logical :: interpolate ! perform vertical interpolation
261 integer :: donor_grid ! data donor grid number
262 integer :: receiver_grid ! data receiver grid number
263 integer :: npoints ! number of points in contact region
264 integer, pointer :: irg(:) ! receiver grid, I-contact point
265 integer, pointer :: jrg(:) ! receiver grid, J-contact point
266 integer, pointer :: idg(:) ! donor grid, cell I-left index
267 integer, pointer :: jdg(:) ! donor grid, cell J-bottom index
268# ifdef SOLVE3D
269 integer, pointer :: kdg(:,:) ! donor grid, cell K-index
270# endif
271 real(r8), pointer :: lweight(:,:) ! linear weights
272# ifdef WET_DRY
273 real(r8), pointer :: lweightunmasked(:,:) ! Unmasked Lweight
274# endif
275# ifdef QUADRATIC_WEIGHTS
276 real(r8), pointer :: qweight(:,:) ! quadratic weights
277# ifdef WET_DRY
278 real(r8), pointer :: qweightunmasked(:,:) ! Unmasked Qweight
279# endif
280# endif
281# ifdef SOLVE3D
282 real(r8), pointer :: vweight(:,:,:) ! vertical weights
283# endif
284 END TYPE t_ngc
285!
286 TYPE (t_ngc), allocatable :: rcontact(:) ! RHO-points, [Ncontact]
287 TYPE (t_ngc), allocatable :: ucontact(:) ! U-points, [Ncontact]
288 TYPE (t_ngc), allocatable :: vcontact(:) ! V-points, [Ncontact]
289!
290!-----------------------------------------------------------------------
291! Boundary Contact Points (BCP) structure, allocated as (4,Ncontact).
292! The first dimension is for domain edge (1=iwest,2=isouth, 3=ieast,
293! 4=inorth).
294!-----------------------------------------------------------------------
295!
296! Currently, this structure is only used in refinement grids where the
297! coarser (donor) and finer (receiver) grids have coincident boundaries
298! but with different I- and J-indices. However, it can be used in the
299! future for composite grids with coincient boundaries.
300!
301! The variable "C2Bindex" is used to tell us which contact points in
302! the "Ucontact" and "Vcontact" structure are located at the physical
303! boundary of the relevant nested grid. For example at the boundary
304! edge of a grid with contact region "cr", we can get the mapping
305! between contact point "m" and grid physical boundary edge index
306! "i" or "j" as:
307!
308! m = BRY_CONTACT(iwest, cr) % C2Bindex(j)
309! m = BRY_CONTACT(isouth,cr) % C2Bindex(i)
310! m = BRY_CONTACT(ieast, cr) % C2Bindex(j)
311! m = BRY_CONTACT(inorth,cr) % C2Bindex(i)
312!
313! This mapping is set during intialization and facilitates efficient
314! processing of nesting contact data.
315!
316 TYPE t_bcp
317 integer :: spv ! fill value, unwanted index
318 integer :: ibmin ! viable minimum Ib
319 integer :: ibmax ! viable maximum Ib
320 integer :: jbmin ! viable minimum Jb
321 integer :: jbmax ! viable maximum Jb
322 integer, pointer :: ib(:) ! I-boundary index
323 integer, pointer :: jb(:) ! J-boundary index
324
325 integer, pointer :: c2bindex(:) ! contact to boundary index
326
327# ifdef NESTING_DEBUG
328 real(r8), pointer :: mflux(:) ! perimeter mass flux
329# endif
330# ifdef SOLVE3D
331 real(r8), pointer :: tflux(:,:,:) ! perimeter tracer flux
332# endif
333 END TYPE t_bcp
334!
335 TYPE (t_bcp), allocatable :: bry_contact(:,:) ! [4,Ncontact]
336!
337!-----------------------------------------------------------------------
338! Nested Grid Metrics (NGM) structure for contact regions. Usually,
339! there are contact points outside of the regular (physical) nested
340! grid domain. That is, such contact points are located in the
341! extended (numerical) regions. These metrics values are computed
342! when designing and generating the application grids.
343!
344! It is recommended to build an intermediary fine resolution grid
345! encompassing the study area first and extract/sample all the ROMS
346! application nested grids from it. This would give a better handle
347! on volume conservation, bathymetry, land/sea masking and other
348! issues.
349!-----------------------------------------------------------------------
350!
351! These metrics are written the contact points NetCDF file and save
352! separated here. It is very tricky to load these values directly
353! to global grid metrics because of parallelization.
354!
355 TYPE t_ngm
356 real(r8), pointer :: angler(:) ! angle between XI and EAST
357 real(r8), pointer :: dndx(:) ! d(1/pn)/d(XI)
358 real(r8), pointer :: dmde(:) ! d(1/pm)/d(ETA)
359 real(r8), pointer :: f(:) ! Coriolis parameter
360 real(r8), pointer :: h(:) ! bathymetry
361 real(r8), pointer :: rmask(:) ! land/sea RHO-mask
362 real(r8), pointer :: umask(:) ! land/sea U-mask
363 real(r8), pointer :: vmask(:) ! land/sea V-mask
364 real(r8), pointer :: pm(:) ! XI-coordinate metric
365 real(r8), pointer :: pn(:) ! ETA-coordinate metric
366 real(r8), pointer :: xr(:) ! X RHO-coordinate (m or deg)
367 real(r8), pointer :: yr(:) ! Y RHO-coordinate (m or deg)
368 real(r8), pointer :: xu(:) ! X U-coordinate (m or deg)
369 real(r8), pointer :: yu(:) ! Y U-coordinate (m or deg)
370 real(r8), pointer :: xv(:) ! X V-coordinate (m or deg)
371 real(r8), pointer :: yv(:) ! Y V-coordinate (m or deg)
372 END TYPE t_ngm
373!
374 TYPE (t_ngm), allocatable :: contact_metric(:) ! [Ncontact]
375!
376!-----------------------------------------------------------------------
377! Composite grids structure. It contains the donor grid data at the
378! receiver grid contact points. The donor grid data is extracted for
379! the cell containing the contact point: 4 horizontal values to
380! facilitate spatial interpolation.
381!-----------------------------------------------------------------------
382!
384 real(r8), pointer :: bustr(:,:) ! [4,Npoints]
385 real(r8), pointer :: bvstr(:,:) ! [4,Npoints)
386
387 real(r8), pointer :: ubar(:,:,:) ! [4,Npoints,2]
388 real(r8), pointer :: vbar(:,:,:) ! [4,Npoints,2]
389 real(r8), pointer :: zeta(:,:,:) ! [4,Npoints,2]
390
391 real(r8), pointer :: rzeta(:,:) ! [4,Npoints]
392
393# ifdef SOLVE3D
394 real(r8), pointer :: du_avg1(:,:) ! [4,Npoints]
395 real(r8), pointer :: dv_avg1(:,:) ! [4,Npoints]
396 real(r8), pointer :: zt_avg1(:,:) ! [4,Npoints]
397
398 real(r8), pointer :: u(:,:,:) ! [4,k,Npoints]
399 real(r8), pointer :: v(:,:,:) ! [4,k,Npoints]
400
401 real(r8), pointer :: huon(:,:,:) ! [4,k,Npoints]
402 real(r8), pointer :: hvom(:,:,:) ! [4,k,Npoints]
403
404 real(r8), pointer :: t(:,:,:,:) ! [4,k,Npoints,itrc]
405# endif
406
407 END TYPE t_composite
408!
409 TYPE (t_composite), allocatable :: composite(:) ! [Ncontact]
410!
411!-----------------------------------------------------------------------
412! Refinement grids structure: It contains the coarser grid data at the
413! finer grid contact points. The finer grid data is extracted for the
414! cell containing the contact point: 4 horizontal values and 2 time
415! records (t1:t2) to facilitate the space-time interpolation.
416!-----------------------------------------------------------------------
417!
419 real(r8), pointer :: ubar(:,:,:) ! [4,Npoints,t1:t2]
420 real(r8), pointer :: vbar(:,:,:) ! [4,Npoints,t1:t2]
421 real(r8), pointer :: zeta(:,:,:) ! [4,Npoints,t1:t2]
422
423 real(r8), pointer :: u2d_flux(:,:,:) ! [4,Npoints,t1:t2]
424 real(r8), pointer :: v2d_flux(:,:,:) ! [4,Npoints,t1:t2]
425
426 real(r8), pointer :: on_u(:) ! [Npoints]
427 real(r8), pointer :: om_v(:) ! [Npoints]
428
429# ifdef SOLVE3D
430 real(r8), pointer :: u(:,:,:,:) ! [4,k,Npoints,t1:t2]
431 real(r8), pointer :: v(:,:,:,:) ! [4,k,Npoints,t1:t2]
432
433 real(r8), pointer :: t(:,:,:,:,:) ! [4,k,Npoints,t1:t2,itrc]
434# endif
435 END TYPE t_refined
436!
437 TYPE (t_refined), allocatable :: refined(:) ! [Ncontact]
438!
439 CONTAINS
440!
442!
443!=======================================================================
444! !
445! This routine allocates and initializes nesting structure for 2D !
446! state variables. !
447! !
448!=======================================================================
449!
450 USE mod_param
451 USE mod_boundary
452 USE mod_scalars
453!
454! Local variable declarations.
455!
456 integer :: lbi, ubi, lbj, ubj
457 integer :: imin, imax, jmin, jmax
458 integer :: ccr, cr, dg, ng, rg
459 integer :: i, ibry, ic, id, ir, j, jd, jr, m, my_tile
460 integer :: ispval
461
462 integer, allocatable :: ibmin(:,:), ibmax(:,:)
463 integer, allocatable :: jbmin(:,:), jbmax(:,:)
464!
465!-----------------------------------------------------------------------
466! Unpack Boundary Contact Points structure (type T_BCP).
467!-----------------------------------------------------------------------
468!
469! Allocate boundary connectivity (type T_BCP) structure.
470!
471 allocate ( bry_contact(4,ncontact) )
472!
473! Allocate arrays in boundary connectivity structure.
474!
475 my_tile=-1 ! for global values
476 DO cr=1,ncontact
477 rg=receiver_grid(cr)
478 lbi=bounds(rg)%LBi(my_tile)
479 ubi=bounds(rg)%UBi(my_tile)
480 lbj=bounds(rg)%LBj(my_tile)
481 ubj=bounds(rg)%UBj(my_tile)
482 DO ibry=1,4
483 SELECT CASE (ibry)
484 CASE (iwest, ieast)
485 allocate ( bry_contact(ibry,cr) % Ib(lbj:ubj) )
486 dmem(rg)=dmem(rg)+real(ubj-lbj,r8)
487
488 allocate ( bry_contact(ibry,cr) % Jb(lbj:ubj) )
489 dmem(rg)=dmem(rg)+real(ubj-lbj,r8)
490
491 allocate ( bry_contact(ibry,cr) % C2Bindex(lbj:ubj) )
492 dmem(rg)=dmem(rg)+real(ubj-lbj,r8)
493
494# ifdef NESTING_DEBUG
495 allocate ( bry_contact(ibry,cr) % Mflux(lbj:ubj) )
496 dmem(rg)=dmem(rg)+real(ubj-lbj,r8)
497# endif
498
499# ifdef SOLVE3D
500 allocate ( bry_contact(ibry,cr) % Tflux(lbj:ubj, &
501 & n(rg),nt(rg)) )
502 dmem(rg)=dmem(rg)+real((ubj-lbj)*n(rg)*nt(rg),r8)
503# endif
504 CASE (isouth, inorth)
505 allocate ( bry_contact(ibry,cr) % Ib(lbi:ubi) )
506 dmem(rg)=dmem(rg)+real(ubi-lbi,r8)
507
508 allocate ( bry_contact(ibry,cr) % Jb(lbi:ubi) )
509 dmem(rg)=dmem(rg)+real(ubi-lbi,r8)
510
511 allocate ( bry_contact(ibry,cr) % C2Bindex(lbi:ubi) )
512 dmem(rg)=dmem(rg)+real(ubi-lbi,r8)
513
514# ifdef NESTING_DEBUG
515 allocate ( bry_contact(ibry,cr) % Mflux(lbi:ubi) )
516 dmem(rg)=dmem(rg)+real(ubi-lbi,r8)
517# endif
518
519# ifdef SOLVE3D
520 allocate ( bry_contact(ibry,cr) % Tflux(lbi:ubi, &
521 & n(rg),nt(rg)) )
522 dmem(rg)=dmem(rg)+real((ubi-lbi)*n(rg)*nt(rg),r8)
523# endif
524 END SELECT
525 END DO
526 END DO
527!
528! Initialize boundary connectivity structure: Boundary indices array
529! are initialized to its special value.
530!
531 ispval=-999
532!
533 IF (.not.allocated(ibmin)) THEN
534 allocate ( ibmin(4,ncontact) )
535 DO ng=1,ngrids
536 dmem(ng)=dmem(ng)+4.0_r8*real(ncontact,r8)
537 END DO
538 ibmin = -ispval
539 END IF
540 IF (.not.allocated(ibmax)) THEN
541 allocate ( ibmax(4,ncontact) )
542 DO ng=1,ngrids
543 dmem(ng)=dmem(ng)+4.0_r8*real(ncontact,r8)
544 END DO
545 ibmax = ispval
546 END IF
547 IF (.not.allocated(jbmin)) THEN
548 allocate ( jbmin(4,ncontact) )
549 DO ng=1,ngrids
550 dmem(ng)=dmem(ng)+4.0_r8*real(ncontact,r8)
551 END DO
552 jbmin = -ispval
553 END IF
554 IF (.not.allocated(jbmax)) THEN
555 allocate ( jbmax(4,ncontact) )
556 DO ng=1,ngrids
557 dmem(ng)=dmem(ng)+4.0_r8*real(ncontact,r8)
558 END DO
559 jbmax = ispval
560 END IF
561!
562 DO cr=1,ncontact
563 DO ibry=1,4
564 bry_contact(ibry,cr) % spv = ispval
565 bry_contact(ibry,cr) % Ib = ispval
566 bry_contact(ibry,cr) % Jb = ispval
567 bry_contact(ibry,cr) % C2Bindex = ispval
568# ifdef NESTING_DEBUG
569 bry_contact(ibry,cr) % Mflux = 0.0_r8
570# endif
571# ifdef SOLVE3D
572 bry_contact(ibry,cr) % Tflux = 0.0_r8
573# endif
574 END DO
575 END DO
576!
577! Identify contact points located on the grid boundary. Notice that
578! the conjugate contact region (CCR) is also processed but it is not
579! yet used. Also, the CCR indices (Ib,Jb) are in refinement overwriten
580! in the m-loop below because several finer grid contact points
581! (RefineScale) are contained in the coarser grid cell. The C2Bindex
582! in this case has the value for the last processed contact point
583! with contact region "cr".
584!
585 DO m=1,ncdatum
586 cr=contact_region(m)
587 dg=donor_grid(cr)
588 rg=receiver_grid(cr)
589 ibry=on_boundary(m)
590 DO ic=1,ncontact
591 IF ((dg.eq.receiver_grid(ic)).and. &
592 & (rg.eq.donor_grid(ic))) THEN
593 ccr=ic ! conjugate contact region
594 EXIT
595 END IF
596 END DO
597 IF ((ibry.eq.iwest ).or.(ibry.eq.ieast )) THEN
598 ir=irg_cp(m)
599 jr=jrg_cp(m)
600 ibmin(ibry,cr )=min(ir,ibmin(ibry,cr ))
601 ibmax(ibry,cr )=max(ir,ibmax(ibry,cr ))
602 jbmin(ibry,cr )=min(jr,jbmin(ibry,cr ))
603 jbmax(ibry,cr )=max(jr,jbmax(ibry,cr ))
604 bry_contact(ibry,cr ) % Ib(jr) = ir
605 bry_contact(ibry,cr ) % Jb(jr) = jr
606 bry_contact(ibry,cr ) % C2Bindex(jr) = m-nstru(cr)+1
607!
608 id=idg_cp(m)
609 jd=jdg_cp(m)
610 ibmin(ibry,ccr)=min(id,ibmin(ibry,ccr))
611 ibmax(ibry,ccr)=max(id,ibmax(ibry,ccr))
612 jbmin(ibry,ccr)=min(jd,jbmin(ibry,ccr))
613 jbmax(ibry,ccr)=max(jd,jbmax(ibry,ccr))
614 bry_contact(ibry,ccr) % Ib(jd) = id
615 bry_contact(ibry,ccr) % Jb(jd) = jd
616 bry_contact(ibry,ccr) % C2Bindex(jd) = m-nstru(cr)+1 ! same
617 ELSE IF ((ibry.eq.isouth).or.(ibry.eq.inorth)) THEN
618 ir=irg_cp(m)
619 jr=jrg_cp(m)
620 ibmin(ibry,cr )=min(ir,ibmin(ibry,cr))
621 ibmax(ibry,cr )=max(ir,ibmax(ibry,cr))
622 jbmin(ibry,cr )=min(jr,jbmin(ibry,cr))
623 jbmax(ibry,cr )=max(jr,jbmax(ibry,cr))
624 bry_contact(ibry,cr ) % Ib(ir) = ir
625 bry_contact(ibry,cr ) % Jb(ir) = jr
626 bry_contact(ibry,cr ) % C2Bindex(ir) = m-nstrv(cr)+1
627!
628 id=idg_cp(m)
629 jd=jdg_cp(m)
630 ibmin(ibry,ccr)=min(id,ibmin(ibry,ccr))
631 ibmax(ibry,ccr)=max(id,ibmax(ibry,ccr))
632 jbmin(ibry,ccr)=min(jd,jbmin(ibry,ccr))
633 jbmax(ibry,ccr)=max(jd,jbmax(ibry,ccr))
634 bry_contact(ibry,ccr) % Ib(id) = id
635 bry_contact(ibry,ccr) % Jb(id) = jd
636 bry_contact(ibry,ccr) % C2Bindex(id) = m-nstrv(cr)+1 ! same
637 END IF
638 END DO
639!
640! Set minimum and maximum indices to process at each boundary.
641!
642 DO cr=1,ncontact
643 DO ibry=1,4
644 IF (abs(ibmin(ibry,cr)).eq.abs(ispval)) THEN
645 bry_contact(ibry,cr) % Ibmin = ispval
646 ELSE
647 bry_contact(ibry,cr) % Ibmin = ibmin(ibry,cr)
648 END IF
649
650 IF (abs(ibmax(ibry,cr)).eq.abs(ispval)) THEN
651 bry_contact(ibry,cr) % Ibmax = ispval
652 ELSE
653 bry_contact(ibry,cr) % Ibmax = ibmax(ibry,cr)
654 END IF
655
656 IF (abs(jbmin(ibry,cr)).eq.abs(ispval)) THEN
657 bry_contact(ibry,cr) % Jbmin = ispval
658 ELSE
659 bry_contact(ibry,cr) % Jbmin = jbmin(ibry,cr)
660 END IF
661
662 IF (abs(jbmax(ibry,cr)).eq.abs(ispval)) THEN
663 bry_contact(ibry,cr) % Jbmax = ispval
664 ELSE
665 bry_contact(ibry,cr) % Jbmax = jbmax(ibry,cr)
666 END IF
667 END DO
668 END DO
669!
670!-----------------------------------------------------------------------
671! Deactivate boundary condition switches if contact point lay on the
672! physical nested grid boundary.
673!-----------------------------------------------------------------------
674!
675 DO cr=1,ncontact
676 rg=receiver_grid(cr)
677 IF (refinedgrid(rg)) THEN
678 IF (refinescale(rg).gt.0) THEN
679 lbc_apply(rg) % west = .false. ! This is a refinement
680 lbc_apply(rg) % south = .false. ! grid, so we need to
681 lbc_apply(rg) % east = .false. ! avoid applying lateral
682 lbc_apply(rg) % north = .false. ! boundary conditions
683 END IF
684 ELSE
685 DO ibry=1,4
686 imin=bry_contact(ibry,cr) % Ibmin ! Deactivate full or
687 imax=bry_contact(ibry,cr) % Ibmax ! partial lateral
688 jmin=bry_contact(ibry,cr) % Jbmin ! boundary conditions
689 jmax=bry_contact(ibry,cr) % Jbmax
690 SELECT CASE (ibry)
691 CASE (iwest)
692 IF ((jmin.ne.ispval).and.(jmax.ne.ispval)) THEN
693 DO j=jmin,jmax
694 lbc_apply(rg) % west (j) = .false.
695 END DO
696 END IF
697 CASE (isouth)
698 IF ((imin.ne.ispval).and.(imax.ne.ispval)) THEN
699 DO i=imin,imax
700 lbc_apply(rg) % south(i) = .false.
701 END DO
702 END IF
703 CASE (ieast)
704 IF ((jmin.ne.ispval).and.(jmax.ne.ispval)) THEN
705 DO j=jmin,jmax
706 lbc_apply(rg) % east (j) = .false.
707 END DO
708 END IF
709 CASE (inorth)
710 IF ((imin.ne.ispval).and.(imax.ne.ispval)) THEN
711 DO i=imin,imax
712 lbc_apply(rg) % north(i) = .false.
713 END DO
714 END IF
715 END SELECT
716 END DO
717 END IF
718 END DO
719!
720 RETURN
721 END SUBROUTINE allocate_nesting
722!
724!
725!=======================================================================
726! !
727! This routine allocates and initializes nesting structure for 2D !
728! state variables. !
729! !
730!=======================================================================
731
732# ifdef SUBOBJECT_DEALLOCATION
733!
734 USE destroy_mod, ONLY : destroy
735# endif
736!
737! Local variable declarations.
738!
739 integer :: cr, ibry
740!
741 character (len=*), parameter :: myfile = &
742 & __FILE__//", deallocate_nesting"
743
744# ifdef SUBOBJECT_DEALLOCATION
745!
746!-----------------------------------------------------------------------
747! Deallocate each variable in the derived-type T_BCP boundary
748! connectivity structure separately.
749!-----------------------------------------------------------------------
750!
751 DO cr=1,ncontact
752 DO ibry=1,4
753 IF (.not.destroy(ng, bry_contact(ibry,cr)%Ib, myfile, &
754 & __line__, 'BRY_CONTACT(ibry,cr)%Ib')) RETURN
755
756 IF (.not.destroy(ng, bry_contact(ibry,cr)%Jb, myfile, &
757 & __line__, 'BRY_CONTACT(ibry,cr)%Jb')) RETURN
758
759 IF (.not.destroy(ng, bry_contact(ibry,cr)%C2Bindex, myfile, &
760 & __line__, 'BRY_CONTACT(ibry,cr)%C2Bindex')) RETURN
761
762# ifdef NESTING_DEBUG
763 IF (.not.destroy(ng, bry_contact(ibry,cr)%Mflux, myfile, &
764 & __line__, 'BRY_CONTACT(ibry,cr)%Mflux')) RETURN
765# endif
766
767# ifdef SOLVE3D
768 IF (.not.destroy(ng, bry_contact(ibry,cr)%Tflux, myfile, &
769 & __line__, 'BRY_CONTACT(ibry,cr)%Tflux')) RETURN
770# endif
771 END DO
772 END DO
773!
774!-----------------------------------------------------------------------
775! Deallocate each variable in the derived-type T_NGC grid connectivity
776! structure separately.
777!-----------------------------------------------------------------------
778!
779 DO cr=1,ncontact
780 IF (.not.destroy(ng, rcontact(cr)%Irg, myfile, &
781 & __line__, 'Rcontact(cr)%Irg')) RETURN
782 IF (.not.destroy(ng, ucontact(cr)%Irg, myfile, &
783 & __line__, 'Ucontact(cr)%Irg')) RETURN
784 IF (.not.destroy(ng, vcontact(cr)%Irg, myfile, &
785 & __line__, 'Vcontact(cr)%Irg')) RETURN
786!
787 IF (.not.destroy(ng, rcontact(cr)%Jrg, myfile, &
788 & __line__, 'Rcontact(cr)%Jrg')) RETURN
789 IF (.not.destroy(ng, ucontact(cr)%Jrg, myfile, &
790 & __line__, 'Ucontact(cr)%Jrg')) RETURN
791 IF (.not.destroy(ng, vcontact(cr)%Jrg, myfile, &
792 & __line__, 'Vcontact(cr)%Jrg')) RETURN
793!
794 IF (.not.destroy(ng, rcontact(cr)%Idg, myfile, &
795 & __line__, 'Rcontact(cr)%Idg')) RETURN
796 IF (.not.destroy(ng, ucontact(cr)%Idg, myfile, &
797 & __line__, 'Ucontact(cr)%Idg')) RETURN
798 IF (.not.destroy(ng, vcontact(cr)%Idg, myfile, &
799 & __line__, 'Vcontact(cr)%Idg')) RETURN
800!
801 IF (.not.destroy(ng, rcontact(cr)%Jdg, myfile, &
802 & __line__, 'Rcontact(cr)%Jdg')) RETURN
803 IF (.not.destroy(ng, ucontact(cr)%Jdg, myfile, &
804 & __line__, 'Ucontact(cr)%Jdg')) RETURN
805 IF (.not.destroy(ng, vcontact(cr)%Jdg, myfile, &
806 & __line__, 'Vcontact(cr)%Jdg')) RETURN
807
808# ifdef SOLVE3D
809!
810 IF (.not.destroy(ng, rcontact(cr)%Kdg, myfile, &
811 & __line__, 'Rcontact(cr)%Kdg')) RETURN
812 IF (.not.destroy(ng, ucontact(cr)%Kdg, myfile, &
813 & __line__, 'Ucontact(cr)%Kdg')) RETURN
814 IF (.not.destroy(ng, vcontact(cr)%Kdg, myfile, &
815 & __line__, 'Vcontact(cr)%Kdg')) RETURN
816# endif
817!
818 IF (.not.destroy(ng, rcontact(cr)%Lweight, myfile, &
819 & __line__, 'Rcontact(cr)%Lweight')) RETURN
820 IF (.not.destroy(ng, ucontact(cr)%Lweight, myfile, &
821 & __line__, 'Ucontact(cr)%Lweight')) RETURN
822 IF (.not.destroy(ng, vcontact(cr)%Lweight, myfile, &
823 & __line__, 'Vcontact(cr)%Lweight')) RETURN
824!
825# ifdef WET_DRY
826 IF (.not.destroy(ng, rcontact(cr)%LweightUnmasked, myfile, &
827 & __line__, 'Rcontact(cr)%LweightUnmasked')) RETURN
828 IF (.not.destroy(ng, ucontact(cr)%LweightUnmasked, myfile, &
829 & __line__, 'Ucontact(cr)%LweightUnmasked')) RETURN
830 IF (.not.destroy(ng, vcontact(cr)%LweightUnmasked, myfile, &
831 & __line__, 'Vcontact(cr)%LweightUnmasked')) RETURN
832# endif
833
834# ifdef QUADRATIC_WEIGHTS
835!
836 IF (.not.destroy(ng, rcontact(cr)%Qweight, myfile, &
837 & __line__, 'Rcontact(cr)%Qweight')) RETURN
838 IF (.not.destroy(ng, ucontact(cr)%Qweight, myfile, &
839 & __line__, 'Ucontact(cr)%Qweight')) RETURN
840 IF (.not.destroy(ng, vcontact(cr)%Qweight, myfile, &
841 & __line__, 'Vcontact(cr)%Qweight')) RETURN
842
843# ifdef WET_DRY
844!
845 IF (.not.destroy(ng, rcontact(cr)%QweightUnmasked, myfile, &
846 & __line__, 'Rcontact(cr)%QweightUnmasked')) RETURN
847 IF (.not.destroy(ng, ucontact(cr)%QweightUnmasked, myfile, &
848 & __line__, 'Ucontact(cr)%QweightUnmasked')) RETURN
849 IF (.not.destroy(ng, vcontact(cr)%QweightUnmasked, myfile, &
850 & __line__, 'Vcontact(cr)%QweightUnmasked')) RETURN
851# endif
852# endif
853
854# ifdef SOLVE3D
855!
856 IF (.not.destroy(ng, rcontact(cr)%Vweight, myfile, &
857 & __line__, 'Rcontact(cr)%Vweight')) RETURN
858 IF (.not.destroy(ng, ucontact(cr)%Vweight, myfile, &
859 & __line__, 'Ucontact(cr)%Vweight')) RETURN
860 IF (.not.destroy(ng, vcontact(cr)%Vweight, myfile, &
861 & __line__, 'Vcontact(cr)%Vweight')) RETURN
862
863# if defined TANGENT || defined TL_IOMS
864!
865 IF (.not.destroy(ng, rcontact(cr)%tl_Vweight, myfile, &
866 & __line__, 'Rcontact(cr)%tl_Vweight')) RETURN
867 IF (.not.destroy(ng, ucontact(cr)%tl_Vweight, myfile, &
868 & __line__, 'Ucontact(cr)%tl_Vweight')) RETURN
869 IF (.not.destroy(ng, vcontact(cr)%tl_Vweight, myfile, &
870 & __line__, 'Vcontact(cr)%tl_Vweight')) RETURN
871# endif
872
873# ifdef ADJOINT
874!
875 IF (.not.destroy(ng, rcontact(cr)%ad_Vweight, myfile, &
876 & __line__, 'Rcontact(cr)%ad_Vweight')) RETURN
877 IF (.not.destroy(ng, ucontact(cr)%ad_Vweight, myfile, &
878 & __line__, 'Ucontact(cr)%ad_Vweight')) RETURN
879 IF (.not.destroy(ng, vcontact(cr)%ad_Vweight, myfile, &
880 & __line__, 'Vcontact(cr)%ad_Vweight')) RETURN
881# endif
882# endif
883 END DO
884!
885!-----------------------------------------------------------------------
886! Deallocate each variable in the derived-type T_NGC contact region
887! metrics structure separately.
888!-----------------------------------------------------------------------
889!
890 DO cr=1,ncontact
891 IF (.not.destroy(ng, contact_metric(cr)%angler, myfile, &
892 & __line__, 'CONTACT_METRIC(cr)%angler')) RETURN
893
894 IF (.not.destroy(ng, contact_metric(cr)%dndx, myfile, &
895 & __line__, 'CONTACT_METRIC(cr)%dndx')) RETURN
896
897 IF (.not.destroy(ng, contact_metric(cr)%dmde, myfile, &
898 & __line__, 'CONTACT_METRIC(cr)%dmde')) RETURN
899
900 IF (.not.destroy(ng, contact_metric(cr)%f, myfile, &
901 & __line__, 'CONTACT_METRIC(cr)%f')) RETURN
902
903 IF (.not.destroy(ng, contact_metric(cr)%h, myfile, &
904 & __line__, 'CONTACT_METRIC(cr)%h')) RETURN
905
906 IF (.not.destroy(ng, contact_metric(cr)%rmask, myfile, &
907 & __line__, 'CONTACT_METRIC(cr)%rmask')) RETURN
908
909 IF (.not.destroy(ng, contact_metric(cr)%umask, myfile, &
910 & __line__, 'CONTACT_METRIC(cr)%umask')) RETURN
911
912 IF (.not.destroy(ng, contact_metric(cr)%vmask, myfile, &
913 & __line__, 'CONTACT_METRIC(cr)%vmask')) RETURN
914
915 IF (.not.destroy(ng, contact_metric(cr)%pm, myfile, &
916 & __line__, 'CONTACT_METRIC(cr)%pm')) RETURN
917
918 IF (.not.destroy(ng, contact_metric(cr)%pn, myfile, &
919 & __line__, 'CONTACT_METRIC(cr)%pn')) RETURN
920
921 IF (.not.destroy(ng, contact_metric(cr)%Xr, myfile, &
922 & __line__, 'CONTACT_METRIC(cr)%Xr')) RETURN
923
924 IF (.not.destroy(ng, contact_metric(cr)%Yr, myfile, &
925 & __line__, 'CONTACT_METRIC(cr)%Yr')) RETURN
926
927 IF (.not.destroy(ng, contact_metric(cr)%Xu, myfile, &
928 & __line__, 'CONTACT_METRIC(cr)%Xu')) RETURN
929
930 IF (.not.destroy(ng, contact_metric(cr)%Yu, myfile, &
931 & __line__, 'CONTACT_METRIC(cr)%Yu')) RETURN
932
933 IF (.not.destroy(ng, contact_metric(cr)%Xv, myfile, &
934 & __line__, 'CONTACT_METRIC(cr)%Xv')) RETURN
935
936 IF (.not.destroy(ng, contact_metric(cr)%Yv, myfile, &
937 & __line__, 'CONTACT_METRIC(cr)%Yv')) RETURN
938 END DO
939!
940!-----------------------------------------------------------------------
941! Deallocate each variable in the derived-type T_COMPOSITE for
942! composite grids contact region structure separately.
943!-----------------------------------------------------------------------
944!
945 DO cr=1,ncontact
946 IF (.not.destroy(ng, composite(cr)%bustr, myfile, &
947 & __line__, 'COMPOSITE(cr)%bustr')) RETURN
948 IF (.not.destroy(ng, composite(cr)%bvstr, myfile, &
949 & __line__, 'COMPOSITE(cr)%bvstr')) RETURN
950
951 IF (.not.destroy(ng, composite(cr)%ubar, myfile, &
952 & __line__, 'COMPOSITE(cr)%ubar')) RETURN
953 IF (.not.destroy(ng, composite(cr)%vbar, myfile, &
954 & __line__, 'COMPOSITE(cr)%vbar')) RETURN
955 IF (.not.destroy(ng, composite(cr)%zeta, myfile, &
956 & __line__, 'COMPOSITE(cr)%zeta')) RETURN
957
958 IF (.not.destroy(ng, composite(cr)%rzeta, myfile, &
959 & __line__, 'COMPOSITE(cr)%rzeta')) RETURN
960
961# if defined TANGENT || defined TL_IOMS
962 IF (.not.destroy(ng, composite(cr)%tl_bustr, myfile, &
963 & __line__, 'COMPOSITE(cr)%tl_bustr')) RETURN
964 IF (.not.destroy(ng, composite(cr)%tl_bvstr, myfile, &
965 & __line__, 'COMPOSITE(cr)%tl_bvstr')) RETURN
966
967 IF (.not.destroy(ng, composite(cr)%tl_ubar, myfile, &
968 & __line__, 'COMPOSITE(cr)%tl_ubar')) RETURN
969 IF (.not.destroy(ng, composite(cr)%tl_vbar, myfile, &
970 & __line__, 'COMPOSITE(cr)%tl_vbar')) RETURN
971 IF (.not.destroy(ng, composite(cr)%tl_zeta, myfile, &
972 & __line__, 'COMPOSITE(cr)%tl_zeta')) RETURN
973
974 IF (.not.destroy(ng, composite(cr)%tl_rzeta, myfile, &
975 & __line__, 'COMPOSITE(cr)%tl_rzeta')) RETURN
976# endif
977
978# ifdef ADJOINT
979 IF (.not.destroy(ng, composite(cr)%ad_bustr, myfile, &
980 & __line__, 'COMPOSITE(cr)%ad_bustr')) RETURN
981 IF (.not.destroy(ng, composite(cr)%ad_bvstr, myfile, &
982 & __line__, 'COMPOSITE(cr)%ad_bvstr')) RETURN
983
984 IF (.not.destroy(ng, composite(cr)%ad_ubar, myfile, &
985 & __line__, 'COMPOSITE(cr)%ad_ubar')) RETURN
986 IF (.not.destroy(ng, composite(cr)%ad_vbar, myfile, &
987 & __line__, 'COMPOSITE(cr)%ad_vbar')) RETURN
988 IF (.not.destroy(ng, composite(cr)%ad_zeta, myfile, &
989 & __line__, 'COMPOSITE(cr)%ad_zeta')) RETURN
990
991 IF (.not.destroy(ng, composite(cr)%ad_rzeta, myfile, &
992 & __line__, 'COMPOSITE(cr)%ad_rzeta')) RETURN
993# endif
994
995# ifdef SOLVE3D
996 IF (.not.destroy(ng, composite(cr)%DU_avg1, myfile, &
997 & __line__, 'COMPOSITE(cr)%DU_avg1')) RETURN
998 IF (.not.destroy(ng, composite(cr)%DV_avg1, myfile, &
999 & __line__, 'COMPOSITE(cr)%DV_avg1')) RETURN
1000 IF (.not.destroy(ng, composite(cr)%Zt_avg1, myfile, &
1001 & __line__, 'COMPOSITE(cr)%Zt_avg1')) RETURN
1002
1003 IF (.not.destroy(ng, composite(cr)%u, myfile, &
1004 & __line__, 'COMPOSITE(cr)%u')) RETURN
1005 IF (.not.destroy(ng, composite(cr)%v, myfile, &
1006 & __line__, 'COMPOSITE(cr)%v')) RETURN
1007
1008 IF (.not.destroy(ng, composite(cr)%Huon, myfile, &
1009 & __line__, 'COMPOSITE(cr)%Huon')) RETURN
1010 IF (.not.destroy(ng, composite(cr)%Hvom, myfile, &
1011 & __line__, 'COMPOSITE(cr)%Hvom')) RETURN
1012
1013 IF (.not.destroy(ng, composite(cr)%t, myfile, &
1014 & __line__, 'COMPOSITE(cr)%t')) RETURN
1015
1016# if defined TANGENT || defined TL_IOMS
1017 IF (.not.destroy(ng, composite(cr)%tl_DU_avg1, myfile, &
1018 & __line__, 'COMPOSITE(cr)%tl_DU_avg1')) RETURN
1019 IF (.not.destroy(ng, composite(cr)%tl_DV_avg1, myfile, &
1020 & __line__, 'COMPOSITE(cr)%tl_DV_avg1')) RETURN
1021 IF (.not.destroy(ng, composite(cr)%tl_Zt_avg1, myfile, &
1022 & __line__, 'COMPOSITE(cr)%tl_Zt_avg1')) RETURN
1023
1024 IF (.not.destroy(ng, composite(cr)%tl_u, myfile, &
1025 & __line__, 'COMPOSITE(cr)%tl_u')) RETURN
1026 IF (.not.destroy(ng, composite(cr)%tl_v, myfile, &
1027 & __line__, 'COMPOSITE(cr)%tl_v')) RETURN
1028
1029 IF (.not.destroy(ng, composite(cr)%tl_Huon, myfile, &
1030 & __line__, 'COMPOSITE(cr)%tl_Huon')) RETURN
1031 IF (.not.destroy(ng, composite(cr)%tl_Hvom, myfile, &
1032 & __line__, 'COMPOSITE(cr)%tl_Hvom')) RETURN
1033
1034 IF (.not.destroy(ng, composite(cr)%tl_t, myfile, &
1035 & __line__, 'COMPOSITE(cr)%tl_t')) RETURN
1036# endif
1037
1038# ifdef ADJOINT
1039 IF (.not.destroy(ng, composite(cr)%ad_DU_avg1, myfile, &
1040 & __line__, 'COMPOSITE(cr)%ad_DU_avg1')) RETURN
1041 IF (.not.destroy(ng, composite(cr)%ad_DV_avg1, myfile, &
1042 & __line__, 'COMPOSITE(cr)%ad_DV_avg1')) RETURN
1043 IF (.not.destroy(ng, composite(cr)%ad_Zt_avg1, myfile, &
1044 & __line__, 'COMPOSITE(cr)%ad_Zt_avg1')) RETURN
1045
1046 IF (.not.destroy(ng, composite(cr)%ad_u, myfile, &
1047 & __line__, 'COMPOSITE(cr)%ad_u')) RETURN
1048 IF (.not.destroy(ng, composite(cr)%ad_v, myfile, &
1049 & __line__, 'COMPOSITE(cr)%ad_v')) RETURN
1050
1051 IF (.not.destroy(ng, composite(cr)%ad_Huon, myfile, &
1052 & __line__, 'COMPOSITE(cr)%ad_Huon')) RETURN
1053 IF (.not.destroy(ng, composite(cr)%ad_Hvom, myfile, &
1054 & __line__, 'COMPOSITE(cr)%ad_Hvom')) RETURN
1055
1056 IF (.not.destroy(ng, composite(cr)%ad_t, myfile, &
1057 & __line__, 'COMPOSITE(cr)%ad_t')) RETURN
1058# endif
1059# endif
1060 END DO
1061!
1062!-----------------------------------------------------------------------
1063! Deallocate each variable in the derived-type T_REFINED for
1064! refinement grids contact region structure separately.
1065!-----------------------------------------------------------------------
1066!
1067 DO cr=1,ncontact
1068 IF (.not.destroy(ng, refined(cr)%ubar, myfile, &
1069 & __line__, 'REFINED(cr)%ubar')) RETURN
1070 IF (.not.destroy(ng, refined(cr)%vbar, myfile, &
1071 & __line__, 'REFINED(cr)%vbar')) RETURN
1072 IF (.not.destroy(ng, refined(cr)%zeta, myfile, &
1073 & __line__, 'REFINED(cr)%zeta')) RETURN
1074
1075 IF (.not.destroy(ng, refined(cr)%U2d_flux, myfile, &
1076 & __line__, 'REFINED(cr)%U2d_flux')) RETURN
1077 IF (.not.destroy(ng, refined(cr)%V2d_flux, myfile, &
1078 & __line__, 'REFINED(cr)%V2d_flux')) RETURN
1079
1080 IF (.not.destroy(ng, refined(cr)%on_u, myfile, &
1081 & __line__, 'REFINED(cr)%on_u')) RETURN
1082 IF (.not.destroy(ng, refined(cr)%om_v, myfile, &
1083 & __line__, 'REFINED(cr)%om_v')) RETURN
1084
1085# if defined TANGENT || defined TL_IOMS
1086 IF (.not.destroy(ng, refined(cr)%tl_ubar, myfile, &
1087 & __line__, 'REFINED(cr)%tl_ubar')) RETURN
1088 IF (.not.destroy(ng, refined(cr)%tl_vbar, myfile, &
1089 & __line__, 'REFINED(cr)%tl_vbar')) RETURN
1090 IF (.not.destroy(ng, refined(cr)%tl_zeta, myfile, &
1091 & __line__, 'REFINED(cr)%tl_zeta')) RETURN
1092
1093 IF (.not.destroy(ng, refined(cr)%tl_U2d_flux, myfile, &
1094 & __line__, 'REFINED(cr)%tl_U2d_flux')) RETURN
1095 IF (.not.destroy(ng, refined(cr)%tl_V2d_flux, myfile, &
1096 & __line__, 'REFINED(cr)%tl_V2d_flux')) RETURN
1097# endif
1098
1099# ifdef ADJOINT
1100 IF (.not.destroy(ng, refined(cr)%ad_ubar, myfile, &
1101 & __line__, 'REFINED(cr)%ad_ubar')) RETURN
1102 IF (.not.destroy(ng, refined(cr)%ad_vbar, myfile, &
1103 & __line__, 'REFINED(cr)%ad_vbar')) RETURN
1104 IF (.not.destroy(ng, refined(cr)%ad_zeta, myfile, &
1105 & __line__, 'REFINED(cr)%ad_zeta')) RETURN
1106
1107 IF (.not.destroy(ng, refined(cr)%ad_U2d_flux, myfile, &
1108 & __line__, 'REFINED(cr)%ad_U2d_flux')) RETURN
1109 IF (.not.destroy(ng, refined(cr)%ad_V2d_flux, myfile, &
1110 & __line__, 'REFINED(cr)%ad_V2d_flux')) RETURN
1111# endif
1112
1113# ifdef SOLVE3D
1114 IF (.not.destroy(ng, refined(cr)%u, myfile, &
1115 & __line__, 'REFINED(cr)%u')) RETURN
1116 IF (.not.destroy(ng, refined(cr)%v, myfile, &
1117 & __line__, 'REFINED(cr)%v')) RETURN
1118
1119 IF (.not.destroy(ng, refined(cr)%t, myfile, &
1120 & __line__, 'REFINED(cr)%t')) RETURN
1121
1122# if defined TANGENT || defined TL_IOMS
1123 IF (.not.destroy(ng, refined(cr)%tl_u, myfile, &
1124 & __line__, 'REFINED(cr)%tl_u')) RETURN
1125 IF (.not.destroy(ng, refined(cr)%tl_v, myfile, &
1126 & __line__, 'REFINED(cr)%tl_v')) RETURN
1127
1128 IF (.not.destroy(ng, refined(cr)%tl_t, myfile, &
1129 & __line__, 'REFINED(cr)%tl_t')) RETURN
1130# endif
1131
1132# ifdef ADJOINT
1133 IF (.not.destroy(ng, refined(cr)%ad_u, myfile, &
1134 & __line__, 'REFINED(cr)%ad_u')) RETURN
1135 IF (.not.destroy(ng, refined(cr)%ad_v, myfile, &
1136 & __line__, 'REFINED(cr)%ad_v')) RETURN
1137
1138 IF (.not.destroy(ng, refined(cr)%ad_t, myfile, &
1139 & __line__, 'REFINED(cr)%ad_t')) RETURN
1140# endif
1141# endif
1142 END DO
1143# endif
1144!
1145!-----------------------------------------------------------------------
1146! Deallocate derived-type structures:
1147!-----------------------------------------------------------------------
1148!
1149! Boundary connectivity.
1150
1151 IF (allocated(bry_contact)) deallocate ( bry_contact )
1152!
1153! Grid connectivity.
1154!
1155 IF (allocated(rcontact)) deallocate ( rcontact )
1156 IF (allocated(ucontact)) deallocate ( ucontact )
1157 IF (allocated(vcontact)) deallocate ( vcontact )
1158!
1159! Contact region metrics.
1160!
1161 IF (allocated(contact_metric)) deallocate ( contact_metric )
1162!
1163! Composite grid contact regions.
1164!
1165 IF (allocated(composite)) deallocate ( composite )
1166!
1167! Deallocate refinement grids contact regions structure.
1168!
1169 IF (allocated(refined)) deallocate ( refined )
1170!
1171!-----------------------------------------------------------------------
1172! Deallocate other variables in module.
1173!-----------------------------------------------------------------------
1174!
1175 IF (allocated(contactregion)) THEN
1176 deallocate ( coarserdonor )
1177 END IF
1178
1179 IF (allocated(finerdonor)) THEN
1180 deallocate ( finerdonor )
1181 END IF
1182
1183 IF (allocated(donortofiner)) THEN
1184 deallocate ( donortofiner )
1185 END IF
1186
1187 IF (allocated(refinesteps)) THEN
1188 deallocate ( refinesteps )
1189 END IF
1190
1191 IF (allocated(refinestepscounter)) THEN
1192 deallocate ( refinestepscounter )
1193 END IF
1194
1195 IF (allocated(twowayinterval)) THEN
1196 deallocate ( twowayinterval )
1197 END IF
1198
1199 IF (allocated(telescoping)) THEN
1200 deallocate ( telescoping )
1201 END IF
1202
1203 IF (allocated(rollingindex)) THEN
1204 deallocate ( rollingindex )
1205 END IF
1206
1207 IF (allocated(rollingtime)) THEN
1208 deallocate ( rollingtime )
1209 END IF
1210!
1211 RETURN
1212 END SUBROUTINE deallocate_nesting
1213!
1215!
1216!=======================================================================
1217! !
1218! This routine initializes time varying nesting structures. !
1219! !
1220!=======================================================================
1221!
1222 USE mod_param
1223 USE mod_scalars
1224!
1225! Local variable declarations.
1226!
1227 integer :: cr
1228
1229 real(r8), parameter :: inival = 0.0_r8
1230!
1231!-----------------------------------------------------------------------
1232! Initialize time-varying contact regions structures. They are used
1233! to process values from contact regions to global kernel arrays and
1234! vice versa.
1235!-----------------------------------------------------------------------
1236!
1237! Composite grids contact region structure.
1238!
1239 IF (any(compositegrid)) THEN
1240 DO cr=1,ncontact
1241 composite(cr) % bustr = inival
1242 composite(cr) % bvstr = inival
1243
1244 composite(cr) % ubar = inival
1245 composite(cr) % vbar = inival
1246 composite(cr) % zeta = inival
1247
1248 composite(cr) % rzeta = inival
1249
1250# ifdef SOLVE3D
1251 composite(cr) % DU_avg1 = inival
1252 composite(cr) % DV_avg1 = inival
1253 composite(cr) % Zt_avg1 = inival
1254
1255 composite(cr) % u = inival
1256 composite(cr) % v = inival
1257
1258 composite(cr) % Huon = inival
1259 composite(cr) % Hvom = inival
1260
1261 composite(cr) % t = inival
1262# endif
1263 END DO
1264 END IF
1265!
1266! Refinement grids contact region structure.
1267!
1268 IF (any(refinedgrid(:))) THEN
1269 DO cr=1,ncontact
1270 refined(cr) % ubar = inival
1271 refined(cr) % vbar = inival
1272 refined(cr) % zeta = inival
1273
1274 refined(cr) % U2d_flux = inival
1275 refined(cr) % V2d_flux = inival
1276
1277 refined(cr) % on_u = inival
1278 refined(cr) % om_v = inival
1279
1280# ifdef SOLVE3D
1281 refined(cr) % u = inival
1282 refined(cr) % v = inival
1283
1284 refined(cr) % t = inival
1285# endif
1286 END DO
1287 END IF
1288
1289 RETURN
1290 END SUBROUTINE initialize_nesting
1291#endif
1292 END MODULE mod_nesting
type(t_apply), dimension(:), allocatable lbc_apply
integer, parameter r8
Definition mod_kinds.F:28
integer, parameter dp
Definition mod_kinds.F:25
integer, parameter nrhst
Definition mod_nesting.F:87
integer, parameter ngetd
Definition mod_nesting.F:77
subroutine, public deallocate_nesting
integer, parameter n2dfx
Definition mod_nesting.F:92
integer, parameter nputd
Definition mod_nesting.F:79
integer, parameter nzeta
Definition mod_nesting.F:88
type(t_ngc), dimension(:), allocatable vcontact
type(t_bcp), dimension(:,:), allocatable bry_contact
integer, dimension(:), allocatable refinestepscounter
integer, parameter ntvic
Definition mod_nesting.F:85
integer, dimension(:), allocatable refinesteps
integer, dimension(:), allocatable rollingindex
real(r8), dimension(:), allocatable twowayinterval
integer, dimension(:), allocatable nstrv
integer, parameter nzwgt
Definition mod_nesting.F:89
integer, dimension(:), allocatable on_boundary
integer, parameter ndxdy
Definition mod_nesting.F:76
integer, dimension(:), allocatable i_right
integer, parameter nfsic
Definition mod_nesting.F:82
integer, dimension(:), allocatable i_left
integer, dimension(:), allocatable nstru
integer, dimension(:), allocatable nendr
type(t_ngm), dimension(:), allocatable contact_metric
logical, dimension(:), allocatable telescoping
integer, parameter n3dic
Definition mod_nesting.F:84
integer, parameter nmask
Definition mod_nesting.F:78
logical, dimension(:), allocatable donortofiner
integer, parameter n2way
Definition mod_nesting.F:80
integer, dimension(:), allocatable receiver_grid
subroutine, public initialize_nesting
integer, dimension(:), allocatable irg_cp
integer, dimension(:), allocatable coarserdonor
integer, parameter n3duv
Definition mod_nesting.F:93
integer, dimension(:), allocatable finerdonor
integer, dimension(:), allocatable jrg_cp
integer, dimension(:), allocatable donor_grid
subroutine, public allocate_nesting
integer, dimension(:), allocatable j_bottom
integer, parameter n2dps
Definition mod_nesting.F:90
integer, dimension(:), allocatable ncpoints
type(t_refined), dimension(:), allocatable refined
integer, dimension(:), allocatable contact_region
integer ncdatum
integer, dimension(:), allocatable j_top
type(t_composite), dimension(:), allocatable composite
integer, parameter n2dic
Definition mod_nesting.F:83
integer, parameter n3dtv
Definition mod_nesting.F:94
type(t_ngc), dimension(:), allocatable rcontact
integer, dimension(:), allocatable nendu
integer, dimension(:), allocatable idg_cp
integer, parameter nbstr
Definition mod_nesting.F:86
real(dp), dimension(:,:), allocatable rollingtime
integer, dimension(:), allocatable jdg_cp
integer, dimension(:), allocatable nstrr
logical get_vweights
type(t_ngc), dimension(:), allocatable ucontact
integer, parameter nmflx
Definition mod_nesting.F:75
integer ncontact
integer, dimension(:), allocatable nendv
logical, dimension(:,:), allocatable contactregion
integer, parameter n2dcs
Definition mod_nesting.F:91
integer, dimension(:), allocatable n
Definition mod_param.F:479
type(t_bounds), dimension(:), allocatable bounds
Definition mod_param.F:232
real(r8), dimension(:), allocatable dmem
Definition mod_param.F:137
integer ngrids
Definition mod_param.F:113
integer, dimension(:), allocatable nt
Definition mod_param.F:489
integer, parameter iwest
logical, dimension(:,:), allocatable compositegrid
integer, parameter isouth
integer, parameter ieast
logical, dimension(:), allocatable refinedgrid
integer, dimension(:), allocatable refinescale
integer, parameter inorth