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 * REMORA used to suppress the same spurious tags afterwards instead, by appending two
20 * derefine criteria that cleared every land cell and every cell beside one. Running after the
21 * user's own criteria, they also cleared tags a static in_box_lo/in_box_hi region had
22 * deliberately set, so a box drawn across a coast came back refined only on its water part.
23 * Guarding each criterion as it is evaluated leaves every other criterion's tags alone.
24 *
25 * The inheritance is private on purpose: AMRErrorTag::operator() is not virtual, so converting
26 * a criterion back to the base would compile and quietly run the unguarded test on masked
27 * data. Private inheritance makes that ill-formed while still granting access to the protected
28 * m_test, m_value and m_info. Only the constructors and Field() are re-exported; the base's
29 * seven-argument operator() deliberately is not, so a call that forgets the mask will not
30 * compile.
31 */
32class REMORAErrorTag final : private amrex::AMRErrorTag
33{
34public:
35 //! Every base constructor makes sense here unchanged; this class alters only evaluation.
36 using amrex::AMRErrorTag::AMRErrorTag;
37
38 //! The field name a criterion was built with; ErrorEst switches on it to fill the data.
39 using amrex::AMRErrorTag::Field;
40
41 /**
42 * Restrict this criterion to model times in [min_time, max_time], in seconds on the
43 * model clock. Held here in double rather than in AMRErrorTagInfo, whose Real would round
44 * a calendar-scale time in a single-precision build, and whose times would have to be
45 * elapsed ones, fixed against whatever remora.start_time was when the inputs were read.
46 */
47 void SetModelTimeWindow (double min_time, double max_time) noexcept
48 {
51 }
52
53 //! Whether this criterion applies at model time t, in seconds on the model clock.
54 [[nodiscard]] bool ActiveAt (double t) const noexcept
55 {
56 return t >= m_min_model_time && t <= m_max_model_time;
57 }
58
59 /**
60 * Apply this criterion to tba, skipping land.
61 *
62 * Only GRAD, LESS and GREATER consult the mask. BOX and PARSER tag on position alone,
63 * USER hands the whole decision to a functor, and VORT and RELGRAD are unreachable from
64 * REMORA's inputs; all of those go to amrex::AMRErrorTag::operator() unchanged.
65 *
66 * @param[inout] tba tags to update
67 * @param[in] mf single-component field this criterion tests, with one ghost
68 * cell when the test is GRAD
69 * @param[in] mskr3d land/sea mask on mf's BoxArray and DistributionMap, with enough
70 * lateral ghost cells for mask_lo/mask_hi plus one more for GRAD.
71 * nullptr evaluates exactly as amrex::AMRErrorTag would, which is
72 * what a criterion keyed on the mask itself wants, and what a run
73 * with no mask wants since every value is then clean anyway.
74 * @param[in] clearval value marking an untagged cell
75 * @param[in] tagval value marking a tagged cell
76 * @param[in] time current time
77 * @param[in] level level being tagged
78 * @param[in] geom geometry of that level
79 * @param[in] mask_lo lowest offset, in rho-cells relative to a value's own index, of
80 * the cells whose wet/dry state that value depends on -- not
81 * always the cell it is stored in, since a face velocity is masked
82 * by both cells sharing its face and vorticity by a 3x3 block.
83 * Testing a value where it is not clean tags the coast just as
84 * differencing across the coast would. ErrorEst sets these per
85 * field and says why. Zero, the default, means the value is its
86 * own cell alone; the vertical component must be zero, the mask
87 * being column-constant.
88 * @param[in] mask_hi highest such offset; see mask_lo.
89 */
90 void operator() (amrex::TagBoxArray& tba,
91 const amrex::MultiFab* mf,
92 const amrex::MultiFab* mskr3d,
93 char clearval,
94 char tagval,
95 amrex::Real time,
96 int level,
97 const amrex::Geometry& geom,
98 const amrex::IntVect& mask_lo = amrex::IntVect::TheZeroVector(),
99 const amrex::IntVect& mask_hi = amrex::IntVect::TheZeroVector()) const;
100
101private:
102 double m_min_model_time = std::numeric_limits<double>::lowest();
103 double m_max_model_time = std::numeric_limits<double>::max();
104};
105
106#endif
mf_h setVal(geomdata.ProbHi(2))
void SetModelTimeWindow(double min_time, double max_time) noexcept
bool ActiveAt(double t) const noexcept
Whether this criterion applies at model time t, in seconds on the model clock.
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