19 #include "libmesh/quadrature.h" 20 #include "libmesh/elem_side_builder.h" 33 MooseEnum system_enum(
"ALL=-1 NL AUX",
"ALL");
37 "The system(s) to retrieve the number of DOFs from (NL, AUX, ALL). Default == ALL");
39 params.
addParam<
bool>(
"sync_to_all_procs",
41 "Whether or not to sync the vectors to all processors. By default we only " 42 "sync them to processor 0 so they can be written out. Setting this to " 43 "true will use more communication, but is necessary if you expect these " 44 "vectors to be available on all processors");
47 "num_elems=0 num_nodes=1 num_dofs=2 num_partition_sides=3 partition_surface_area=4 " 48 "num_partition_hardware_id_sides=5 partition_hardware_id_surface_area=6",
49 "num_elems num_nodes num_dofs num_partition_sides partition_surface_area " 50 "num_partition_hardware_id_sides partition_hardware_id_surface_area");
52 "balances", balances,
"Which metrics do you want to use to represent word balance");
59 _rank_map(_app.rankMap()),
60 _my_hardware_id(_rank_map.hardwareID(processor_id())),
61 _sync_to_all_procs(getParam<bool>(
"sync_to_all_procs")),
65 _local_num_partition_sides(0),
66 _local_partition_surface_area(0),
67 _local_num_partition_hardware_id_sides(0),
68 _local_partition_hardware_id_surface_area(0),
69 _pid(declareVector(
"pid")),
100 _my_hardware_id(rank_map.hardwareID(
mesh.processor_id())),
103 _local_num_partition_sides(0),
104 _local_partition_surface_area(0),
105 _local_num_partition_hardware_id_sides(0),
106 _local_partition_hardware_id_surface_area(0),
107 _this_pid(_mesh.processor_id())
110 auto partitioner =
mesh.getMesh().partitioner()->clone();
117 _rank_map(x._rank_map),
118 _my_hardware_id(x._my_hardware_id),
121 _local_num_partition_sides(0),
122 _local_partition_surface_area(0),
123 _local_num_partition_hardware_id_sides(0),
124 _local_partition_hardware_id_surface_area(0),
125 _this_pid(x._this_pid)
127 if (x._petsc_partitioner)
130 auto partitioner = x._petsc_partitioner->clone();
135 virtual ~WBElementLoop() {}
137 virtual void pre()
override 139 _local_num_elems = 0;
141 _local_num_partition_sides = 0;
142 _local_partition_surface_area = 0;
143 _local_num_partition_hardware_id_sides = 0;
144 _local_partition_hardware_id_surface_area = 0;
147 virtual void onElement(
const Elem * elem)
override 149 if (_petsc_partitioner && _petsc_partitioner->applyElementEeight())
153 _local_num_elems += _petsc_partitioner->computeElementWeight(const_cast<Elem &>(*elem));
161 auto n_sys = elem->n_systems();
162 for (decltype(n_sys) sys = 0; sys < n_sys; sys++)
164 auto n_vars = elem->n_vars(sys);
166 for (decltype(n_vars) var = 0; var <
n_vars; var++)
167 _local_num_dofs += elem->n_dofs(sys, var);
172 auto n_vars = elem->n_vars(static_cast<unsigned int>(_system));
174 for (decltype(n_vars) var = 0; var <
n_vars; var++)
175 _local_num_dofs += elem->n_dofs(static_cast<unsigned int>(_system), var);
179 virtual void onInternalSide(
const Elem * elem,
unsigned int side)
override 181 if (elem->neighbor_ptr(side)->processor_id() != _this_pid)
183 if (_petsc_partitioner && _petsc_partitioner->applySideWeight())
187 _local_num_partition_sides +=
188 _petsc_partitioner->computeSideWeight(const_cast<Elem &>(*elem), side);
191 _local_num_partition_sides++;
195 auto volume = _elem_side_builder(*elem, side).volume();
196 _local_partition_surface_area +=
volume;
198 if (_my_hardware_id != _rank_map.hardwareID(elem->neighbor_ptr(side)->processor_id()))
200 _local_num_partition_hardware_id_sides++;
201 _local_partition_hardware_id_surface_area +=
volume;
206 void join(
const WBElementLoop & y)
208 _local_num_elems += y._local_num_elems;
209 _local_num_dofs += y._local_num_dofs;
210 _local_num_partition_sides += y._local_num_partition_sides;
211 _local_partition_surface_area += y._local_partition_surface_area;
212 _local_num_partition_hardware_id_sides += y._local_num_partition_hardware_id_sides;
213 _local_partition_hardware_id_surface_area += y._local_partition_hardware_id_surface_area;
220 unsigned int _my_hardware_id;
225 Real _local_partition_surface_area;
226 dof_id_type _local_num_partition_hardware_id_sides;
227 Real _local_partition_hardware_id_surface_area;
233 std::unique_ptr<PetscExternalPartitioner> _petsc_partitioner;
242 class WBNodeLoop :
public ThreadedNodeLoop<ConstNodeRange, ConstNodeRange::const_iterator>
263 auto & node = *(*node_it);
270 auto n_sys = node.n_systems();
271 for (decltype(n_sys) sys = 0; sys < n_sys; sys++)
273 auto n_vars = node.n_vars(sys);
275 for (decltype(n_vars) var = 0; var <
n_vars; var++)
276 _local_num_dofs += node.n_dofs(sys, var);
281 auto n_vars = node.n_vars(static_cast<unsigned int>(_system));
283 for (decltype(n_vars) var = 0; var <
n_vars; var++)
284 _local_num_dofs += node.n_dofs(static_cast<unsigned int>(_system), var);
288 void join(WBNodeLoop & y)
290 _local_num_nodes += y._local_num_nodes;
291 _local_num_dofs += y._local_num_dofs;
310 Threads::parallel_reduce(*
mesh.getActiveLocalElementRange(), wb_el);
322 Threads::parallel_reduce(*
mesh.getLocalNodeRange(), wb_nl);
357 mooseError(
"Unknown balance type: ", balance_id);
386 mooseError(
"Unknown balance type: ", balance_id);
396 auto balance_id = balance.id();
400 gather(balance_id, balance_vector);
404 std::iota(
_pid.begin(),
_pid.end(), 0);
MultiMooseEnum _balances
The chosen balance metrics to compute.
dof_id_type _local_num_elems
dof_id_type _local_num_dofs
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
std::string join(Iterator begin, Iterator end, const std::string &delimiter)
Python-like join function for strings over an iterator range.
virtual bool shouldComputeInternalSide(const Elem &elem, const Elem &neighbor) const
Whether to compute the internal side for the provided element-neighbor pair.
virtual void onElement(const Elem *elem)
Assembly of the element (not including surface assembly)
registerMooseObject("MooseApp", WorkBalance)
std::string toLower(const std::string &name)
Convert supplied string to lower case.
VectorPostprocessorValue & _pid
Real _local_partition_surface_area
dof_id_type _local_num_nodes
void gather(const unsigned int root_id, const T &send_data, std::vector< T, A > &recv) const
virtual void pre()
Called before the element range loop.
This class is here to combine the VectorPostprocessor interface and the base class VectorPostprocesso...
Builds lists and maps that help in knowing which physical hardware nodes each rank is on...
static InputParameters validParams()
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
const Parallel::Communicator & _communicator
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
const RankMap & _rank_map
Helpful in determining the physical layout of the ranks.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual void finalize() override
Finalize.
int _system
The system to count DoFs from.
processor_id_type size() const
uint8_t processor_id_type
dof_id_type _local_num_partition_sides
std::map< std::string, VectorPostprocessorValue * > _balance_vectors
The VPP vectors that will hold the balance metrics.
static InputParameters validParams()
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...
VectorPostprocessorValue & declareVector(const std::string &vector_name)
Register a new vector to fill up.
virtual void execute() override
Execute method.
virtual void onInternalSide(const Elem *elem, unsigned int side)
Called when doing internal edge assembling.
dof_id_type _local_num_partition_hardware_id_sides
std::vector< Real > VectorPostprocessorValue
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
vec_type::const_iterator const_iterator
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
WorkBalance(const InputParameters ¶meters)
virtual MooseMesh & mesh() override
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
Base class for assembly-like calculations.
void gather(int balance_id, VectorPostprocessorValue &vppv)
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type...
Partitions a mesh using external petsc partitioners such as parmetis, ptscotch, chaco, party, etc.
Compute several metrics for each MPI process.
Real _local_partition_hardware_id_surface_area
virtual void onNode(IteratorType &node_it)
Called for each node.