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)
269 if (MooseUtils::absoluteFuzzyEqual(vol, 0))
274 for (
const auto i : index_range(volumes_2d))
279 for (
const auto & vol_vec : volumes_2d)
280 for (
const auto & vol : vol_vec)
281 if (MooseUtils::absoluteFuzzyEqual(vol, 0))
286 for (
const auto i : index_range(volumes_3d))
287 for (
const auto j : index_range(volumes_3d[i]))
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)
295 if (MooseUtils::absoluteFuzzyEqual(vol, 0))
300 for (
const auto i : index_range(volumes_4d))
301 for (
const auto j : index_range(volumes_4d[i]))
302 for (
const auto k : index_range(volumes_4d[i][j]))
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)
311 if (MooseUtils::absoluteFuzzyEqual(vol, 0))
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);
383 mooseAssert(!use_subdomains || (id_index == std::numeric_limits<unsigned short>::max()),
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);
registerMooseObject("MooseApp", ElementGroupCentroidPositions)
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
An interface that restricts an object to subdomains via the 'blocks' input parameter.
virtual const std::set< SubdomainID > & blockIDs() const
Return the block subdomain ids for this object Note, if this is not block restricted,...
const std::set< SubdomainID > & meshBlockIDs() const
Return all of the SubdomainIDs for the mesh.
virtual bool blockRestricted() const
Returns true if this object has been restricted to a block.
static InputParameters validParams()
Positions from centroids of groups of elements (subdomains, extra element ids) in the mesh.
dof_id_type id(const Elem &elem, unsigned int id_index, bool use_subdomains)
std::vector< std::vector< dof_id_type > > _extra_id_group_indices
The particular extra id values, for each extra id of interest.
ElementGroupCentroidPositions(const InputParameters ¶meters)
static InputParameters validParams()
std::vector< unsigned int > _extra_id_indices
The indices of the extra element ids to use to make groups.
void initialize() override
In charge of computing / loading the positions.
static MooseEnum groupTypeEnum()
{ How to group elements, to compute centroids for these groups
std::vector< ExtraElementIDName > _extra_id_names
The names of the extra element ids to use to make groups.
const std::string & name() const
Get the name of the class.
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.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Positions objects are under the hood Reporters.
std::vector< std::vector< std::vector< std::vector< Point > > > > _positions_4d
4D storage for all the positions : space & time
std::vector< std::vector< Point > > _positions_2d
2D storage for all the positions
void clearPositions()
Clear all positions vectors.
std::vector< Point > & _positions
For now, only the 1D vector will be shared across all ranks.
void unrollMultiDPositions()
Unrolls the multi-dimensional position vectors.
static InputParameters validParams()
std::vector< std::vector< std::vector< Point > > > _positions_3d
3D storage for all the positions
virtual void finalize() override
In charge of reduction across all ranks & sorting for consistent output.
bool _initialized
Whether the positions object has been initialized. This must be set by derived objects.
void set_union(T &data, const unsigned int root_id) const
const Parallel::Communicator & comm() const