REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_ErrorTag.H
Go to the documentation of this file.
1#ifndef _REMORA_ErrorTag_H_
2#define _REMORA_ErrorTag_H_
3
4#include <AMReX_ErrorList.H>
5#include <AMReX_MultiFab.H>
6#include <AMReX_TagBox.H>
7
8#include <limits>
9
10/**
11 * An amrex::AMRErrorTag that does not let the coastline drive refinement.
12 *
13 * AMReX writes each data-dependent test twice: a plain form, and an embedded-boundary form
14 * that skips a covered cell and differences only across a face EBCellFlag reports as open.
15 * REMORA's land/sea mask plays the part of that connectivity -- tracers on the land side are
16 * zeroed every step, so a difference taken across a coast measures the coast, not the flow.
17 * This class is that EB form with mskr in place of the flags.
18 *
19 * Guarding each criterion as it is evaluated, rather than clearing land-adjacent tags
20 * afterwards, leaves every other criterion's tags alone -- including a static
21 * in_box_lo/in_box_hi region drawn across a coast.
22 *
23 * The inheritance is private on purpose: AMRErrorTag::operator() is not virtual, so converting
24 * a criterion back to the base would compile and quietly run the unguarded test on masked
25 * data. Private inheritance makes that ill-formed while still granting access to the protected
26 * m_test, m_value and m_info. Only the constructors and Field() are re-exported; the base's
27 * seven-argument operator() deliberately is not, so a call that forgets the mask will not
28 * compile.
29 */
30class REMORAErrorTag final : private amrex::AMRErrorTag
31{
32public:
33 //! Every base constructor makes sense here unchanged; this class alters only evaluation.
34 using amrex::AMRErrorTag::AMRErrorTag;
35
36 //! The field name a criterion was built with; ErrorEst switches on it to fill the data.
37 using amrex::AMRErrorTag::Field;
38
39 /**
40 * Restrict this criterion to a time window, given as elapsed time (seconds
41 * since remora.start_time), as total time (seconds on the model clock), or
42 * both, in which case both must hold. Held here in double rather than in
43 * AMRErrorTagInfo, whose Real would round a calendar-scale total time in a
44 * single-precision build.
45 */
47 double min_total, double max_total) noexcept
48 {
53 }
54
55 //! Whether this criterion applies at the given elapsed and total times.
56 [[nodiscard]] bool ActiveAt (double elapsed, double total) const noexcept
57 {
60 }
61
62 /**
63 * Apply this criterion to tba, skipping land.
64 *
65 * Only GRAD, LESS and GREATER consult the mask. BOX and PARSER tag on position alone,
66 * USER hands the whole decision to a functor, and VORT and RELGRAD are unreachable from
67 * REMORA's inputs; all of those go to amrex::AMRErrorTag::operator() unchanged.
68 *
69 * @param[inout] tba tags to update
70 * @param[in] mf single-component field this criterion tests, with one ghost
71 * cell when the test is GRAD
72 * @param[in] mskr3d land/sea mask on mf's BoxArray and DistributionMap, with enough
73 * lateral ghost cells for mask_lo/mask_hi plus one more for GRAD.
74 * nullptr evaluates exactly as amrex::AMRErrorTag would, which is
75 * what a criterion keyed on the mask itself wants, and what a run
76 * with no mask wants since every value is then clean anyway.
77 * @param[in] clearval value marking an untagged cell
78 * @param[in] tagval value marking a tagged cell
79 * @param[in] time current time
80 * @param[in] level level being tagged
81 * @param[in] geom geometry of that level
82 * @param[in] mask_lo lowest offset, in rho-cells relative to a value's own index, of
83 * the cells whose wet/dry state that value depends on -- not
84 * always the cell it is stored in, since a face velocity is masked
85 * by both cells sharing its face and vorticity by a 3x3 block.
86 * Testing a value where it is not clean tags the coast just as
87 * differencing across the coast would. ErrorEst sets these per
88 * field and says why. Zero, the default, means the value is its
89 * own cell alone; the vertical component must be zero, the mask
90 * being column-constant.
91 * @param[in] mask_hi highest such offset; see mask_lo.
92 */
93 void operator() (amrex::TagBoxArray& tba,
94 const amrex::MultiFab* mf,
95 const amrex::MultiFab* mskr3d,
96 char clearval,
97 char tagval,
98 amrex::Real time,
99 int level,
100 const amrex::Geometry& geom,
101 const amrex::IntVect& mask_lo = amrex::IntVect::TheZeroVector(),
102 const amrex::IntVect& mask_hi = amrex::IntVect::TheZeroVector()) const;
103
104private:
105 double m_min_elapsed = std::numeric_limits<double>::lowest();
106 double m_max_elapsed = std::numeric_limits<double>::max();
107 double m_min_total = std::numeric_limits<double>::lowest();
108 double m_max_total = std::numeric_limits<double>::max();
109};
110
111#endif
mf_h setVal(geomdata.ProbHi(2))
bool ActiveAt(double elapsed, double total) const noexcept
Whether this criterion applies at the given elapsed and total times.
void SetTimeWindow(double min_elapsed, double max_elapsed, double min_total, double max_total) noexcept
void operator()(amrex::TagBoxArray &tba, const amrex::MultiFab *mf, const amrex::MultiFab *mskr3d, char clearval, char tagval, amrex::Real time, int level, const amrex::Geometry &geom, const amrex::IntVect &mask_lo=amrex::IntVect::TheZeroVector(), const amrex::IntVect &mask_hi=amrex::IntVect::TheZeroVector()) const