Mesh Refinement
ERF allows both static and dynamic mesh refinement.
Note that any tagged region will be covered by one or more boxes. The user may specify the refinement criteria and/or region to be covered, but not the decomposition of the region into individual grids.
See the Gridding section of the AMReX documentation for details of how individual grids are created.
Static Mesh Refinement
For static refinement, we control the placement of grids by specifying the low and high extents (in physical space) of each box in the lateral directions. ERF enforces that all refinement spans the entire vertical direction.
The following example demonstrates how to tag regions for static refinement. In this first example, all cells in the region ((.15,.25,prob_lo_z)(.35,.45,prob_hi_z)) and in the region ((.65,.75,prob_lo_z)(.85,.95,prob_hi_z)) are tagged for one level of refinement, where prob_lo_z and prob_hi_z are the vertical extents of the domain:
amr.max_level = 1
amr.ref_ratio = 2
erf.refinement_indicators = box1 box2
erf.box1.in_box_lo = .15 .25
erf.box1.in_box_hi = .35 .45
erf.box2.in_box_lo = .65 .75
erf.box2.in_box_hi = .85 .95
In the example below, we refine the region ((.15,.25,prob_lo_z)(.35,.45,prob_hi_z)) by two levels of factor 3 refinement. In this case, the refined region at level 1 will be sufficient to enclose the refined region at level 2.
amr.max_level = 2
amr.ref_ratio = 3 3
erf.refinement_indicators = box1
erf.box1.in_box_lo = .15 .25
erf.box1.in_box_hi = .35 .45
And in this final example, the region ((.15,.25,prob_lo_z)(.35,.45,prob_hi_z)) will be refined by two levels of factor 3, but the larger region, ((.05,.05,prob_lo_z)(.75,.75,prob_hi_z)) will be refined by a single factor 3 refinement.
amr.max_level = 2
amr.ref_ratio = 3 3
erf.refinement_indicators = box1 box2
erf.box1.in_box_lo = .15 .25
erf.box1.in_box_hi = .35 .45
erf.box2.in_box_lo = .05 .05
erf.box2.in_box_hi = .75 .75
erf.box2.max_level = 1
Dynamic Mesh Refinement
Dynamically created tagging functions are based on runtime data specified in the inputs file. These dynamically generated functions test on either state variables or derived variables defined in ERF_derive.cpp and included in the derive_lst in Setup.cpp.
Available tests include
“greater_than”: \(field >= threshold\)
“less_than”: \(field <= threshold\)
“adjacent_difference_greater”: \(max( | \text{difference between any nearest-neighbor cell} | ) >= threshold\)
This example adds three user-named criteria – hi_rho: cells with density greater than 1 on level 0, and greater than 2 on level 1 and higher; lo_theta: cells with theta less than 300 that are inside the region ((.25,.25,.25)(.75,.75,.75)); and adv_diff: cells having a difference in the scalar of 0.01 or more from that of any immediate neighbor. The first will trigger up to AMR level 3, the second only to level 1, and the third to level 2. The third will be active only when the problem time is between 0.001 and 0.002 seconds.
Note that density and rhoadv_0 are the names of state variables, whereas theta is the name of a derived variable, computed by dividing the variable named rhotheta by the variable named density.
erf.refinement_indicators = hi_rho lo_theta advdiff
erf.hi_rho.max_level = 3
erf.hi_rho.value_greater = 1. 2.
erf.hi_rho.field_name = density
erf.lo_theta.max_level = 1
erf.lo_theta.value_less = 300
erf.lo_theta.field_name = rhotheta
erf.lo_theta.in_box_lo = .25 .25 .25
erf.lo_theta.in_box_hi = .75 .75 .75
erf.advdiff.max_level = 2
erf.advdiff.adjacent_difference_greater = 0.01
erf.advdiff.field_name = rhoadv_0
erf.advdiff.start_time = 0.001
erf.advdiff.end_time = 0.002
Coupling Types
ERF supports both one-way and two-coupling; this is a run-time input
erf.coupling_type = "OneWay" or "TwoWay"
By one-way coupling, we mean that between each pair of refinement levels,
only the coarse mesh communicates data to the fine mesh. For cell-centered quantities,
and face-baced normal momenta on the coarse-fine interface, the coarse data is conservatively
interpolated to the fine mesh. The interpolated data is utilized to specify ghost cell data
(outside of the valid fine region) as well as specify and relax data inside the lateral boundaries
of the fine region. More specifically, a user may specify the total width of the interior
Dirichlet and relaxation region with erf.cf_width = <Int>
(yellow + blue)
and analogously the width of the interior Dirichlet region may be specified with
erf.cf_set_width = <Int>
(yellow).
Image taken from Skamarock et al. (2021) |
Within the interior Dirichlet region (yellow), the RHS is exactly 0. However, within the relaxation region (blue), the RHS (\(F\)) is given by the following:
where \(G\) is the RHS of the NS equations, \(\psi^{\prime}\) is the predicted update without
relaxation, \(\psi^{FP}\) is the fine patch data obtained from space-time interpolation of the
coarse mesh, and \(n\) is the minimum number of grid point from a lateral boundary. The set and
relaxation regions are applied to all dycore variables \(\left[\rho \; \rho\Theta \; U\; V\; W \right]\)
on the fine mesh. Finally, we note that time dependent Dirichlet data, provided via an external boundary file,
may be enforced on the lateral boundary conditions of the domain (coarsest mesh). For such cases,
the relaxation region width at the domain edges may be specified with erf.wrfbdy_width = <Int>
(yellow + blue) while the interior Dirichlet region may be specified with erf.wrfbdy_set_width = <Int>
(yellow). With the boundary file approach, all dycore variables are set and relaxed but
moisture is only set in the yellow region if it is present within the boundary file.
By two-way coupling, we mean that in additional to specifying ghost cell data (outside of the valid fine region), the fine mesh communicates data back to the coarse mesh in two ways:
The fine cell-centered data is conservatively averaged onto the coarse mesh covered by fine mesh.
A “reflux” operation is performed for all cell-centered data.
Because the normal momentum at the fine level is itself interpolated from the coarse, the difference between fluxes – along the coarse-fine interfaces – used to update the coarse data and fluxes used to update the fine data is due to the difference in the averaging of the advected quantity to the face where the flux is defined.
We note that both coupling schemes are conservative for mass because the fluxes for the continuity equation are the momenta themselves, which are interpolated on faces at the coarse-fine interface. Other advected quantities which are advanced in conservation form will lose conservation with one-way coupling. Two-way coupling is conservative for these scalars as long as the refluxing operation is included with the averaging down.