12 #include "libmesh/parallel_algebra.h" 22 "Groups may be defined using subdomains or element extra ids.");
26 params.
addParam<std::vector<ExtraElementIDName>>(
"extra_id_name",
27 "Name(s) of the extra element ID(s) to use");
28 params.
addParam<std::vector<std::vector<dof_id_type>>>(
30 "Specific ID(s), for each extra id name, for grouping elements. " 31 "If empty, all *valid* ids will be used to bin");
34 params.
set<
bool>(
"auto_sort") =
false;
36 params.
set<
bool>(
"auto_broadcast") =
false;
44 _mesh(_subproblem.
mesh()),
45 _group_type(getParam<
MooseEnum>(
"grouping_type"))
50 _extra_id_names = getParam<std::vector<ExtraElementIDName>>(
"extra_id_name");
61 "Number of extra id names and the indices to select must match. " 62 "If you want all indices for an extra id, use an empty vector entry");
66 mooseError(
"Positions currently supports only up to 4D storage");
72 "An extra id name was specified but elements are not grouped by extra ids");
75 "An extra id was specified but elements are not grouped by extra ids");
87 for (
const auto & block :
blockIDs())
116 std::set<dof_id_type> ids;
117 for (
const auto & elem :
_mesh.
getMesh().active_local_element_ptr_range())
120 if (eeid != DofObject::invalid_id)
124 for (
const auto &
id : ids)
125 indices.push_back(
id);
130 std::vector<Real> volumes;
131 std::vector<std::vector<Real>> volumes_2d;
132 std::vector<std::vector<std::vector<Real>>> volumes_3d;
133 std::vector<std::vector<std::vector<std::vector<Real>>>> volumes_4d;
148 for (
auto & vol_group : volumes_2d)
158 for (
auto & pos_group : vec_pos_group)
161 for (
auto & vec_vol_group : volumes_3d)
164 for (
auto & vol_group : vec_vol_group)
175 for (
auto & vec_pos_group : vec_vec_pos_group)
178 for (
auto & pos_group : vec_pos_group)
182 for (
auto & vec_vec_vol_group : volumes_4d)
185 for (
auto & vec_vol_group : vec_vec_vol_group)
188 for (
auto & vol_group : vec_vol_group)
194 mooseError(
"Too much dimensionality for positions");
197 auto getNestedPositions =
198 [
this](
const std::vector<unsigned int> & indices) -> std::vector<Point> &
200 mooseAssert(indices[
_extra_id_names.size() - 1] == 0,
"Indexing issue");
210 auto getNestedVolumes = [
this, &volumes, &volumes_2d, &volumes_3d, &volumes_4d](
211 const std::vector<unsigned int> & indices) -> std::vector<Real> &
213 mooseAssert(indices[
_extra_id_names.size() - 1] == 0,
"Indexing issue");
217 return volumes_2d[indices[0]];
219 return volumes_3d[indices[0]][indices[1]];
221 return volumes_4d[indices[0]][indices[1]][indices[2]];
224 std::vector<std::map<unsigned int, unsigned int>> positions_indexing(
232 for (
const auto extra_id : indices)
233 positions_indexing[i][extra_id] = j++;
236 for (
const auto & elem :
_mesh.
getMesh().active_local_element_ptr_range())
239 const auto centroid = elem->true_centroid();
240 const auto volume = elem->volume();
243 std::vector<unsigned int> previous_indices(4);
249 if (iter == positions_indexing[i].end())
253 getNestedPositions(previous_indices)[iter->second] +=
volume * centroid;
254 getNestedVolumes(previous_indices)[iter->second] +=
volume;
258 previous_indices[i] = iter->second;
263 unsigned int num_zeros = 0;
268 for (
const auto & vol : volumes)
279 for (
const auto & vol_vec : volumes_2d)
280 for (
const auto & vol : vol_vec)
292 for (
const auto & vol_vec_vec : volumes_3d)
293 for (
const auto & vol_vec : vol_vec_vec)
294 for (
const auto & vol : vol_vec)
307 for (
const auto & vol_vec_vec_vec : volumes_4d)
308 for (
const auto & vol_vec_vec : vol_vec_vec_vec)
309 for (
const auto & vol_vec : vol_vec_vec)
310 for (
const auto & vol : vol_vec)
316 " zero volume bins detected during group centroid position calculation. " 317 "The corresponding positions will be removed from consideration.");
328 volumes.erase(volumes.begin() + i);
336 if (volumes_2d[i][j] != 0)
341 volumes_2d[i].erase(volumes_2d[i].begin() + j);
350 if (volumes_3d[i][j][k] != 0)
355 volumes_3d[i][j].erase(volumes_3d[i][j].begin() + k);
365 if (volumes_4d[i][j][k][l] != 0)
370 volumes_4d[i][j][k].erase(volumes_4d[i][j][k].begin() + l);
384 "We do not expect a valid element extra integer index for subdomains");
386 return elem.subdomain_id();
388 return elem.get_extra_integer(id_index);
ElementGroupCentroidPositions(const InputParameters ¶meters)
std::vector< ExtraElementIDName > _extra_id_names
The names of the extra element ids to use to make groups.
void initialize() override
In charge of computing / loading the positions.
static InputParameters validParams()
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
static MooseEnum groupTypeEnum()
{ How to group elements, to compute centroids for these groups
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
void clearPositions()
Clear all positions vectors.
Positions objects are under the hood Reporters.
const Parallel::Communicator & comm() const
virtual const std::set< SubdomainID > & blockIDs() const
Return the block subdomain ids for this object Note, if this is not block restricted, this function returns all mesh subdomain ids.
virtual bool blockRestricted() const
Returns true if this object has been restricted to a block.
void unrollMultiDPositions()
Unrolls the multi-dimensional position vectors.
auto max(const L &left, const R &right)
bool _initialized
Whether the positions object has been initialized. This must be set by derived objects.
static InputParameters validParams()
void mooseWarning(Args &&... args) const
registerMooseObject("MooseApp", ElementGroupCentroidPositions)
std::vector< std::vector< Point > > _positions_2d
2D storage for all the positions
const std::string & name() const
Get the name of the class.
Positions from centroids of groups of elements (subdomains, extra element ids) in the mesh...
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
static InputParameters validParams()
std::vector< Point > & _positions
For now, only the 1D vector will be shared across all ranks.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
dof_id_type id(const Elem &elem, unsigned int id_index, bool use_subdomains)
std::vector< std::vector< std::vector< Point > > > _positions_3d
3D storage for all the positions
An interface that restricts an object to subdomains via the 'blocks' input parameter.
const std::set< SubdomainID > & meshBlockIDs() const
Return all of the SubdomainIDs for the mesh.
virtual void finalize() override
In charge of reduction across all ranks & sorting for consistent output.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
std::vector< unsigned int > _extra_id_indices
The indices of the extra element ids to use to make groups.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
std::vector< std::vector< dof_id_type > > _extra_id_group_indices
The particular extra id values, for each extra id of interest.
std::vector< std::vector< std::vector< std::vector< Point > > > > _positions_4d
4D storage for all the positions : space & time
auto index_range(const T &sizable)
void set_union(T &data, const unsigned int root_id) const