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<unsigned int>>>(
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(_fe_problem.
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<unsigned int> ids;
117 for (
const auto & elem :
_mesh.
getMesh().active_local_element_ptr_range())
120 for (
const auto &
id : ids)
121 indices.push_back(
id);
126 std::vector<Real> volumes;
127 std::vector<std::vector<Real>> volumes_2d;
128 std::vector<std::vector<std::vector<Real>>> volumes_3d;
129 std::vector<std::vector<std::vector<std::vector<Real>>>> volumes_4d;
144 for (
auto & vol_group : volumes_2d)
154 for (
auto & pos_group : vec_pos_group)
157 for (
auto & vec_vol_group : volumes_3d)
160 for (
auto & vol_group : vec_vol_group)
171 for (
auto & vec_pos_group : vec_vec_pos_group)
174 for (
auto & pos_group : vec_pos_group)
178 for (
auto & vec_vec_vol_group : volumes_4d)
181 for (
auto & vec_vol_group : vec_vec_vol_group)
184 for (
auto & vol_group : vec_vol_group)
190 mooseError(
"Too much dimensionality for positions");
193 auto getNestedPositions =
194 [
this](
const std::vector<unsigned int> & indices) -> std::vector<Point> &
196 mooseAssert(indices[
_extra_id_names.size() - 1] == 0,
"Indexing issue");
206 auto getNestedVolumes = [
this, &volumes, &volumes_2d, &volumes_3d, &volumes_4d](
207 const std::vector<unsigned int> & indices) -> std::vector<Real> &
209 mooseAssert(indices[
_extra_id_names.size() - 1] == 0,
"Indexing issue");
213 return volumes_2d[indices[0]];
215 return volumes_3d[indices[0]][indices[1]];
217 return volumes_4d[indices[0]][indices[1]][indices[2]];
220 std::vector<std::map<unsigned int, unsigned int>> positions_indexing(
228 for (
const auto extra_id : indices)
229 positions_indexing[i][extra_id] = j++;
232 for (
const auto & elem :
_mesh.
getMesh().active_local_element_ptr_range())
235 const auto centroid = elem->true_centroid();
236 const auto volume = elem->volume();
239 std::vector<unsigned int> previous_indices(4);
245 if (iter == positions_indexing[i].end())
249 getNestedPositions(previous_indices)[iter->second] +=
volume * centroid;
250 getNestedVolumes(previous_indices)[iter->second] +=
volume;
254 previous_indices[i] = iter->second;
259 unsigned int num_zeros = 0;
264 for (
const auto & vol : volumes)
275 for (
const auto & vol_vec : volumes_2d)
276 for (
const auto & vol : vol_vec)
288 for (
const auto & vol_vec_vec : volumes_3d)
289 for (
const auto & vol_vec : vol_vec_vec)
290 for (
const auto & vol : vol_vec)
303 for (
const auto & vol_vec_vec_vec : volumes_4d)
304 for (
const auto & vol_vec_vec : vol_vec_vec_vec)
305 for (
const auto & vol_vec : vol_vec_vec)
306 for (
const auto & vol : vol_vec)
312 " zero volume bins detected during group centroid position calculation. " 313 "The corresponding positions will be removed from consideration.");
324 volumes.erase(volumes.begin() + i);
332 if (volumes_2d[i][j] != 0)
337 volumes_2d[i].erase(volumes_2d[i].begin() + j);
346 if (volumes_3d[i][j][k] != 0)
351 volumes_3d[i][j].erase(volumes_3d[i][j].begin() + k);
361 if (volumes_4d[i][j][k][l] != 0)
366 volumes_4d[i][j][k].erase(volumes_4d[i][j][k].begin() + l);
380 "We do not expect a valid element extra integer index for subdomains");
382 return elem.subdomain_id();
384 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.
unsigned int id(const Elem &elem, unsigned int id_index, bool use_subdomains)
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()
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...
std::vector< std::vector< std::vector< Point > > > _positions_3d
3D storage for all the positions
std::vector< std::vector< unsigned int > > _extra_id_group_indices
The particular extra id values, for each extra id of interest.
An interface that restricts an object to subdomains via the 'blocks' input parameter.
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
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< 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