ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
erf_wall_scalar_bc Namespace Reference

Classes

struct  ParsedWallScalarBC
 
struct  ParsedWallFaceScalars
 
struct  WallFaceParseResult
 

Enumerations

enum class  WallScalarBCIntent : unsigned char { Unspecified , DirichletConserved , DirichletPrimitive , Neumann }
 
enum class  SolidWallKind : unsigned char { NoSlip , Slip }
 

Functions

ParsedWallScalarBC resolve_wall_scalar_value (bool value_specified, amrex::Real primitive_value, bool density_specified_on_same_face, amrex::Real density_value)
 
ParsedWallScalarBC resolve_wall_scalar_gradient (bool gradient_specified, amrex::Real gradient)
 
bool wall_scalar_value_gradient_conflict (bool value_specified, bool gradient_specified)
 
std::string wall_scalar_value_gradient_error (const std::string &face, const std::string &variable)
 
std::string anelastic_wall_density_error (const std::string &face, bool density_specified, bool density_gradient_specified)
 
std::string no_slip_density_gradient_error (const std::string &face)
 
WallFaceParseResult parse_wall_face_scalars (amrex::ParmParse &pp, const std::string &face, SolidWallKind wall_kind, bool anelastic)
 

Enumeration Type Documentation

◆ SolidWallKind

enum erf_wall_scalar_bc::SolidWallKind : unsigned char
strong
Enumerator
NoSlip 
Slip 
20  : unsigned char {
21  NoSlip,
22  Slip
23 };

◆ WallScalarBCIntent

enum erf_wall_scalar_bc::WallScalarBCIntent : unsigned char
strong
Enumerator
Unspecified 
DirichletConserved 
DirichletPrimitive 
Neumann 

Function Documentation

◆ anelastic_wall_density_error()

std::string erf_wall_scalar_bc::anelastic_wall_density_error ( const std::string &  face,
bool  density_specified,
bool  density_gradient_specified 
)
inline

Build the anelastic-mode density error message for a wall face.

Parameters
[in]faceface name used in the input keys
[in]density_specifiedwhether density was specified
[in]density_gradient_specifiedwhether density_grad was specified
126 {
127  if (!density_specified && !density_gradient_specified) {
128  return {};
129  }
130 
131  std::string message = face + ": density and density_grad must be omitted "
132  "on solid walls in anelastic mode (density is fixed by the base state)";
133  if (density_specified && density_gradient_specified) {
134  message += "; both keywords were supplied";
135  } else if (density_specified) {
136  message += "; " + face + ".density was supplied";
137  } else {
138  message += "; " + face + ".density_grad was supplied";
139  }
140  return message;
141 }

Referenced by parse_wall_face_scalars().

Here is the caller graph for this function:

◆ no_slip_density_gradient_error()

std::string erf_wall_scalar_bc::no_slip_density_gradient_error ( const std::string &  face)
inline

Build the unsupported no-slip density-gradient error message.

Parameters
[in]faceface name used in the input keys
150 {
151  return face + ".density_grad is not supported for NoSlipWall; use "
152  + face + ".density for a fixed compressible wall density or omit "
153  "wall density in anelastic mode";
154 }

Referenced by parse_wall_face_scalars().

Here is the caller graph for this function:

◆ parse_wall_face_scalars()

WallFaceParseResult erf_wall_scalar_bc::parse_wall_face_scalars ( amrex::ParmParse &  pp,
const std::string &  face,
SolidWallKind  wall_kind,
bool  anelastic 
)
inline

Parse scalar wall boundary-condition inputs for one face.

Parameters
[in]ppParmParse object scoped to the wall face
[in]faceface name used in errors
[in]wall_kindno-slip or slip wall type
[in]anelasticwhether anelastic mode is active
169 {
170  // The value-carrying keys are probed with negative sentinels and their presence is
171  // read off the resulting value, not off the queryAdd return value. queryAdd inserts
172  // the default into the (process-global) ParmParse table on a miss, so its return
173  // value means "did this key exist before this call" -- true for every call after the
174  // first. ERF::init_bcs() runs twice on restart, and ERF_InitBCs.cpp parses the same
175  // density/qv keys under the same face prefix, so a return-value test reports
176  // "user specified" with a value of zero on the second pass. That is what produced
177  // the spurious NoSlipWall density_grad abort in #3922.
178  //
179  // density_grad and theta_grad deliberately keep plain query(): every real value is a
180  // legal gradient, including zero and negatives, so no sentinel can encode "unset".
181  amrex::Real density = amrex::Real(-1.0);
182  pp.queryAdd("density", density);
183  const bool density_specified = (density > amrex::Real(0.0));
184  if (!density_specified) { density = amrex::Real(0.0); }
185 
186  amrex::Real density_grad = amrex::Real(0.0);
187  const bool density_gradient_specified = pp.query("density_grad", density_grad);
188 
189  amrex::Real theta = amrex::Real(-1.0);
190  pp.queryAdd("theta", theta);
191  const bool theta_specified = (theta > amrex::Real(0.0));
192  if (!theta_specified) { theta = amrex::Real(0.0); }
193 
194  amrex::Real theta_grad = amrex::Real(0.0);
195  const bool theta_gradient_specified = pp.query("theta_grad", theta_grad);
196 
197  amrex::Real qv = amrex::Real(-1.0);
198  if (wall_kind == SolidWallKind::NoSlip) { pp.queryAdd("qv", qv); }
199  const bool qv_specified = (wall_kind == SolidWallKind::NoSlip) &&
200  (qv >= amrex::Real(0.0));
201  if (!qv_specified) { qv = amrex::Real(0.0); }
202 
203  WallFaceParseResult result;
204  if (anelastic && (density_specified || density_gradient_specified)) {
205  result.error = anelastic_wall_density_error(
206  face, density_specified, density_gradient_specified);
207  return result;
208  }
209 
210  if (wall_kind == SolidWallKind::NoSlip && density_gradient_specified) {
211  result.error = no_slip_density_gradient_error(face);
212  return result;
213  }
214 
215  if (wall_kind == SolidWallKind::Slip &&
216  wall_scalar_value_gradient_conflict(density_specified,
217  density_gradient_specified)) {
218  result.error = wall_scalar_value_gradient_error(face, "density");
219  return result;
220  }
221 
222  if (wall_scalar_value_gradient_conflict(theta_specified,
223  theta_gradient_specified)) {
224  result.error = wall_scalar_value_gradient_error(face, "theta");
225  return result;
226  }
227 
228  if (density_specified) {
229  result.scalars.density = {
230  WallScalarBCIntent::DirichletConserved, density};
231  }
232  result.scalars.theta = resolve_wall_scalar_value(
233  theta_specified, theta, density_specified, density);
234  if (theta_gradient_specified) {
235  result.scalars.theta = resolve_wall_scalar_gradient(true, theta_grad);
236  }
237 
238  if (wall_kind == SolidWallKind::Slip && density_gradient_specified) {
239  result.scalars.density = resolve_wall_scalar_gradient(true, density_grad);
240  }
241 
242  if (qv_specified) {
243  result.scalars.qv = resolve_wall_scalar_value(
244  true, qv, density_specified, density);
245  }
246 
247  return result;
248 }
ParmParse pp("prob")
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ theta
Definition: ERF_SLM.H:20
@ qv
Definition: ERF_Kessler.H:30
std::string wall_scalar_value_gradient_error(const std::string &face, const std::string &variable)
Definition: ERF_WallScalarBC.H:108
bool wall_scalar_value_gradient_conflict(bool value_specified, bool gradient_specified)
Definition: ERF_WallScalarBC.H:95
std::string anelastic_wall_density_error(const std::string &face, bool density_specified, bool density_gradient_specified)
Definition: ERF_WallScalarBC.H:123
ParsedWallScalarBC resolve_wall_scalar_value(bool value_specified, amrex::Real primitive_value, bool density_specified_on_same_face, amrex::Real density_value)
Definition: ERF_WallScalarBC.H:55
std::string no_slip_density_gradient_error(const std::string &face)
Definition: ERF_WallScalarBC.H:149
ParsedWallScalarBC resolve_wall_scalar_gradient(bool gradient_specified, amrex::Real gradient)
Definition: ERF_WallScalarBC.H:79

Referenced by ERF::init_phys_bcs().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ resolve_wall_scalar_gradient()

ParsedWallScalarBC erf_wall_scalar_bc::resolve_wall_scalar_gradient ( bool  gradient_specified,
amrex::Real  gradient 
)
inline

Resolve a wall scalar gradient into Neumann storage.

Parameters
[in]gradient_specifiedwhether the scalar gradient was specified
[in]gradientgradient value from inputs
81 {
82  if (!gradient_specified) {
83  return {};
84  }
85  return {WallScalarBCIntent::Neumann, gradient};
86 }

Referenced by parse_wall_face_scalars().

Here is the caller graph for this function:

◆ resolve_wall_scalar_value()

ParsedWallScalarBC erf_wall_scalar_bc::resolve_wall_scalar_value ( bool  value_specified,
amrex::Real  primitive_value,
bool  density_specified_on_same_face,
amrex::Real  density_value 
)
inline

Resolve a wall scalar value into primitive or conserved storage.

Parameters
[in]value_specifiedwhether the scalar value was specified
[in]primitive_valueprimitive scalar value from inputs
[in]density_specified_on_same_facewhether density was specified on the same face
[in]density_valuedensity value used for conserved conversion
59 {
60  if (!value_specified) {
61  return {};
62  }
63 
64  if (density_specified_on_same_face) {
65  return {WallScalarBCIntent::DirichletConserved,
66  density_value * primitive_value};
67  }
68 
69  return {WallScalarBCIntent::DirichletPrimitive, primitive_value};
70 }

Referenced by parse_wall_face_scalars().

Here is the caller graph for this function:

◆ wall_scalar_value_gradient_conflict()

bool erf_wall_scalar_bc::wall_scalar_value_gradient_conflict ( bool  value_specified,
bool  gradient_specified 
)
inline

Test whether value and gradient inputs conflict.

Parameters
[in]value_specifiedwhether a scalar value was specified
[in]gradient_specifiedwhether a scalar gradient was specified
97 {
98  return value_specified && gradient_specified;
99 }

Referenced by parse_wall_face_scalars().

Here is the caller graph for this function:

◆ wall_scalar_value_gradient_error()

std::string erf_wall_scalar_bc::wall_scalar_value_gradient_error ( const std::string &  face,
const std::string &  variable 
)
inline

Build the error message for mutually exclusive wall scalar inputs.

Parameters
[in]faceface name used in the input keys
[in]variablevariable name used in the input keys
110 {
111  return face + "." + variable + " and " + face + "." + variable
112  + "_grad are mutually exclusive";
113 }

Referenced by parse_wall_face_scalars().

Here is the caller graph for this function: