18 #include "libmesh/mesh_tools.h" 19 #include "libmesh/point.h" 28 params.
addParam<
unsigned int>(
"num_layers",
"The number of layers.");
29 params.
addParam<std::vector<Real>>(
"bounds",
30 "The 'bounding' positions of the layers i.e.: '0, " 31 "1.2, 3.7, 4.2' will mean 3 layers between those " 34 "bound_uniform_splits > 0",
35 "The number of times the bins specified in 'bounds' " 36 "should be split uniformly.");
37 params.
addParam<std::vector<unsigned int>>(
38 "bound_splits",
"Number of uniform splits of all layers in 'bounds' (default to all ones)");
40 MooseEnum sample_options(
"direct interpolate average",
"direct");
43 "How to sample the layers. 'direct' means get the value of the layer " 44 "the point falls in directly (or average if that layer has no value). " 45 " 'interpolate' does a linear interpolation between the two closest " 46 "layers. 'average' averages the two closest layers.");
48 params.
addParam<
unsigned int>(
"average_radius",
50 "When using 'average' sampling this is how " 51 "the number of values both above and below " 52 "the layer that will be averaged.");
57 "When true the value in each layer is the sum of the values up to and including that layer");
59 "positive_cumulative_direction",
61 "When 'cumulative' is true, whether the direction for summing the cumulative value " 62 "is the positive direction or negative direction");
64 params.
addParam<std::vector<SubdomainName>>(
65 "block",
"The list of block ids (SubdomainID) that this object will be applied");
67 params.
addParam<std::vector<SubdomainName>>(
"layer_bounding_block",
68 "List of block ids (SubdomainID) that are used to " 69 "determine the upper and lower geometric bounds for " 70 "all layers. If this is not specified, the ids " 71 "specified in 'block' are used for this purpose.");
74 "Minimum coordinate along 'direction' that bounds the layers");
76 "Maximum coordinate along 'direction' that bounds the layers");
78 "direction num_layers bounds direction_min direction_max bound_uniform_splits bound_splits",
79 "Layers extent and definition");
80 params.
addParamNamesToGroup(
"sample_type average_radius cumulative positive_cumulative_direction",
81 "Value sampling / aggregating");
87 parameters.getObjectName() +
"_layered_base",
90 _layered_base_name(parameters.getObjectName()),
91 _layered_base_params(parameters),
93 _direction(_direction_enum),
95 _average_radius(parameters.
get<unsigned
int>(
"average_radius")),
96 _using_displaced_mesh(_layered_base_params.
get<bool>(
"use_displaced_mesh")),
97 _layer_values(declareRestartableData<
std::vector<
Real>>(
"layer_values")),
98 _layer_has_value(declareRestartableData<
std::vector<
int>>(
"layer_has_value")),
99 _cumulative(parameters.
get<bool>(
"cumulative")),
100 _positive_cumulative_direction(parameters.
get<bool>(
"positive_cumulative_direction")),
101 _layered_base_subproblem(*parameters.getCheckedPointerParam<
SubProblem *>(
"_subproblem")),
102 _layer_bounding_blocks(),
103 _has_direction_max_min(false)
107 mooseError(
"'bounds' and 'num_layers' cannot both be set");
111 "The 'positive_cumulative_direction' parameter is unused when 'cumulative' is false");
125 mooseError(
"At least two boundaries must be provided in 'bounds' to form layers!");
132 mooseError(
"Parameters 'bound_splits' and 'bound_uniform_splits' cannot be both supplied");
138 for (
unsigned int s = 0; s < splits; ++s)
140 std::vector<Real> new_bnds;
157 mooseError(
"'bound_splits' size must be equal to the size of 'bounds' minus one");
159 std::vector<Real> new_layers;
160 new_layers.reserve(std::accumulate(nsubs.begin(), nsubs.end(), (
unsigned int)0));
168 new_layers.push_back(new_layers.back() + dz);
180 mooseError(
"One of 'bounds' or 'num_layers' must be specified");
183 mooseError(
"'sample_type = interpolate' not supported with 'bounds'");
191 mooseWarning(
"'direction_min' is unused when providing 'bounds'");
194 mooseWarning(
"'direction_max' is unused when providing 'bounds'");
197 if (has_layer_bounding_block && (has_direction_min || has_direction_max))
198 mooseError(
"Only one of 'layer_bounding_block' and the pair 'direction_max' and " 199 "'direction_min' can be provided");
202 if (has_direction_min != has_direction_max)
203 mooseError(
"If providing the layer max/min directions, both 'direction_max' and " 204 "'direction_min' must be specified.");
206 if (has_layer_bounding_block)
214 if (has_direction_min && has_direction_max)
221 mooseError(
"'direction_max' must be larger than 'direction_min'");
240 int higher_layer = -1;
241 int lower_layer = -1;
252 for (
int i = layer - 1; i >= 0; i--)
261 if (higher_layer == -1 && lower_layer == -1)
268 if (higher_layer == -1)
271 if (
unsigned(higher_layer) == layer)
274 if (lower_layer == -1)
281 if (higher_layer == -1)
286 Real lower_value = 0;
287 if (lower_layer != -1)
289 lower_coor += (lower_layer + 1) * layer_length;
298 (higher_value - lower_value) * (p(
_direction) - lower_coor) / layer_length;
303 unsigned int num_values = 0;
305 if (higher_layer != -1)
309 int current_layer = higher_layer + i;
322 if (lower_layer != -1)
326 int current_layer = lower_layer - i;
328 if (current_layer < 0)
339 return total / num_values;
395 const auto & lb =
dynamic_cast<const LayeredBase &
>(y);
397 if (lb.layerHasValue(i))
423 std::vector<Real>::const_iterator one_higher =
428 return static_cast<unsigned int>(
437 return static_cast<unsigned int>(std::distance(
_layer_bounds.begin(), one_higher - 1));
483 for (
auto & elem_ptr : *
mesh.getActiveLocalElementRange())
485 auto subdomain_id = elem_ptr->subdomain_id();
491 for (
auto & node : elem_ptr->node_ref_range())
virtual MooseMesh & mesh()=0
std::vector< Real > & _layer_values
Value of the integral for each layer.
bool _using_displaced_mesh
true if this object operates on the displaced mesh, otherwise false
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
A class for creating restricted objects.
std::string _layered_base_name
Name of this object.
SubProblem & _layered_base_subproblem
Subproblem for the child object.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
bool _interval_based
Whether or not this object is based on equally spaced intervals or "bounds".
bool _cumulative
Whether the values are cumulative over the layers.
void getBounds()
Compute bounds, restricted to blocks if given.
const Parallel::Communicator & comm() const
std::vector< int > & _layer_has_value
Whether or not each layer has had any value summed into it.
static InputParameters validParams()
const InputParameters & _layered_base_params
Params for this object.
std::vector< Real > _layer_centers
center coordinates of each layer
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_names) const
Get the associated subdomainIDs for the subdomain names that are passed in.
auto max(const L &left, const R &right)
virtual void threadJoin(const UserObject &y)
unsigned int _direction
The component direction the layers are going in. We cache this for speed (so we're not always going t...
std::vector< SubdomainID > _layer_bounding_blocks
List of SubdomainIDs, if given.
void libmesh_ignore(const Args &...)
unsigned int _average_radius
How many layers both above and below the found layer will be used in the average. ...
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
virtual Real getLayerValue(unsigned int layer) const
Get the value for a given layer.
void computeLayerCenters()
Compute the center points for each layer.
void setLayerValue(unsigned int layer, Real value)
Set the value for a particular layer.
virtual Real integralValue(const Point &p) const
Given a Point return the integral value associated with the layer that point falls in...
const bool _positive_cumulative_direction
Whether the cumulative values should be summed in the positive or negative direction.
virtual unsigned int getLayer(const Point &p) const
Helper function to return the layer the point lies in.
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
virtual void initialize()
unsigned int _num_layers
Number of layers to split the mesh into.
std::vector< Real > _layer_bounds
The boundaries of the layers.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Generic class for solving transient nonlinear problems.
void max(const T &r, T &o, Request &req) const
This base class computes volume integrals of a variable storing partial sums for the specified number...
IntRange< T > make_range(T beg, T end)
unsigned int _sample_type
How to sample the values.
LayeredBase(const InputParameters ¶meters)
auto min(const L &left, const R &right)
void ErrorVector unsigned int
auto index_range(const T &sizable)
Base class for user-specific data.
const Elem & get(const ElemType type_in)
bool _has_direction_max_min
whether the max/min coordinate in the direction is known from user input