The ROMS algorithms where updated to include the final Phase III of multiple-grid nesting (svn trunk revision 658). It includes the nesting calls to ROMS main time-stepping routines main2d and main3d. All the nesting routines are located in module ROMS/Nonlinear/nesting.F. This is the main driver for a nesting application with composite and/or refinement grids. This driver has a coarse grained parallel design and works in serial with tile partitions, shared-memory (OpenMP), and distributed-memory (MPI). We get identical solutions in our test cases.

Phase III was particularly difficult and it took long time to finish. I know that some of you have been patiently waiting for it. I think that the wait was worth it and ROMS nesting has tremendous capabilities and potential. I rewrote nesting.F several times because I was looking for a very elegant and generic algorithm for nesting in ROMS. The most difficult part was the Nested Grid Connectivity (NGC) for any generic application. This is all done outside of ROMS and provided as in a new input NetCDF file (NGCname).

The nesting algorithms took long to be developed in this version ROMS. Many thanks to John Warner for helping us to develop and test this capability.

The idea for nesting evolved with time and we became more ambitious as you can see in the technical documentation in WikiROMS. Notice that we have now several nested grid classes. Diagrams for each class is presented with additional figures for the contact areas and contact points.

The nesting in ROMS is always two-way. There is a duality for each nested grid: data donor in one contact region and data receiver in its conjugate contact region. Thus, we prefer to use the donor and receiver categories instead of the usual parent and child descriptions found in the literature.

This structure is used to store all the connectivity information between nested grids. It is used extensible when processing contact region points between data donor and data receiver grids. This information is processed outside of ROMS and read from input NGCname NetCDF file for functionality and efficiency. In nested grids, the points in the contact region are interpolated from the data donor grid cell containing the contact point using the following conventions at the horizontal location in the receiver grid (Irg, Jrg) and donor grid cell (Idg, Jdg):

Here, the suffixes dg and rg are for the donor and receiver grid, respectively. The horizontal interpolation weights Hweight(1:4,m) for contact point m are computed outside of ROMS and read from the NGCname NetCDF file. If coincident contact points between data donor and data receiver grids, p = q = 0. Then, Hweight(1,m)=1 and Hweight(2:3,m)=0.

This structure is allocated as [4,Ncontact]. Currently, it is used in refinement grids where the coarser (donor) and finer (receiver) grids have coincident physical boundaries but with different I- and J-indices. The variable C2Bindex (Coarse to Boundary index) is used to tell us which contact points in the Ucontact and Vcontact structures are located at the physical boundary of the relevant nested grid. For example at the boundary edge of a grid with contact regioncr, we can get the mapping between contact pointm and grid physical boundary edge index i or j as:

In some nesting configurations, there are contact points outside of the regular (physical) nested grid domain. That is, such contact points are located in the extended numerical regions. These metrics values need to be computed when designing and generating the applications grids. In such cases, it is recommended to build an intermediary fine resolution grid encompassing the study area firsts and extract/sample all the ROMS application nested grids (composite and refinement) from it. This would give a better handle on volume conservation, bathymetry representation, land/sea masking and other grid topology issues. These metrics are read from NGCname NetCDF and packed in this structure. It is very tricky to load these values directly into the global grid metrics arrays because of parallelization.

It contains the coarser grid data at the finer grid contact points. The finer grid data is extracted for the cell containing the contact point: 4 horizontal values and 2 time records (t1:t2) to facilitate the space-time linear interpolation.

All the nested data is packed in a long vector dimensioned Ndatum. Several indices (NstrR, NendR, NstrU, NendU, NstrV, and NendV) are available to unpack the data in the Rcontact, Ucontact, and Vcontact NGC-type structures for contact point information at RHO-, U-, and V-points. Although NetCDF-4 supports derived type structures via the HDF5 library, a simpler Metadata model is chosen for interoperability. Notice that the NGCname NetCDF file also contains the values for the various grid metrics needed in ROMS numerical kernel. Only the horizontal interpolation weights (Hweight)are provided here since they are always the same (time independent) for a particular configuration. The vertical interpolation weights are computed internally in ROMS at each time step because of the time dependency of the vertical coordinates to the evolution of the free-surface. This NetCDF file is created using the Matlab script contact.m. The routine set_contact is called in inp_par after reading the standard input parameters.

Added new module nesting.F to process nesting capabilities in ROMS. It contains several public and private routines:

CALL nesting(ng, model, isection), public interface to ROMS time-stepping kernel. This routine is the main driver for nesting. It performs the various nesting operations according to the isection flag with the following values:

CALL bry_fluxes(dg, rg, cr, model, tile, ...), this public routine extracts tracer horizontal advective fluxes (Hz*u*T/n, Hz*v*T/m) at the grid contact boundary (physical domain perimeter). The data source is either the coarse or finer grid and it is call from tracer stepping routine step3d_t. These fluxes are used for in two-way nesting.

CALL fill_contact(rg, model, tile, cr, ...), this public routine is used during initialization to fill the contact points of a specified grid metric array. We need to have metric data in all the extended computational points of the grid. No attempt is done here to interpolate such values since the are read in set_contact from input contact points NGCname NetCDF file. This routine just unpack data into global arrays and check if all needed values are filled. Notice that during allocation these special metric grid arrays are initialized to spval to avoid resetting those values processed already from the regular Grid NetCDF file. That is, only those contact points outside the physical grid are processed here. This is a good way to check if all the extra numerical points have been processed.

CALL fine2coarse(ng, model, vtype, tile), this private replaces interior coarser grid data with the refined averaged values: two-way nesting. It is called separated for 2D and 3D state-variables using the vtype flag.

CALL get_composite(ng, model, isection, tile), this private routine gets the donor grid data required to process the contact points of the current composite grid, ng. It extracts the donor cell points containing each contact point. In composite grids, it is possible to have more than one contact region.

CALL get_contact2d(dg, model, tile, gtype, svname, ...), this private low level generic routine gets the donor grid data necessary to process the contact points for a 2D state variable. It extracts the donor cell points containing each contact point. It is called repetitively from get_composite and get_refined.

CALL get_contact3d(dg, model, tile, gtype, svname, ...), this private low level generic routine gets the donor grid data necessary to process the contact points for a 3D state variable. It extracts the donor cell points containing each contact point. It is called repetitively from get_composite and get_refined.

CALL get_refine(ng, model, tile), this private routine gets the donor grid data required to process the contact points of the current refinement grid. It extracts the donor cell points containing each contact point. The extracted data is stored in two-time rolling records which to allow the temporal interpolation in put_refine.

put_refine2d(ng, dg, cr, model, tile, ...), this private routine performs a spatial and temporal linear interpolates of the refinement grid, ng, 2D state variables contact points using data from the donor grid. It imposes mass flux from the coarser grid at the finer grid physical boundaries. It is called from routine put_refine.

put_refine3d(ng, dg, cr, model, tile, ...), this private routine performs a spatial and temporal linear interpolates of the refinement grid, ng, 3D state variables contact points using data from the donor grid. It is called from routine put_refine.

CALL z_weights(ng, model, tile), this private routine determines the vertical indices (Kdg) and vertical interpolation weights (Vweight) associated with the time-evolving depths, which are needed to process 3D fields in the contact region.

Who is online

Users browsing this forum: No registered users and 1 guest

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum