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();
111 _petsc_partitioner = dynamic_pointer_cast<PetscExternalPartitioner>(partitioner);
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();
131 _petsc_partitioner = dynamic_pointer_cast<PetscExternalPartitioner>(partitioner);
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;
236 bool shouldComputeInternalSide(
const Elem & ,
const Elem & )
const override
242class WBNodeLoop :
public ThreadedNodeLoop<ConstNodeRange, ConstNodeRange::const_iterator>
261 virtual void onNode(ConstNodeRange::const_iterator & node_it)
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;
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);
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
std::vector< Real > VectorPostprocessorValue
registerMooseObject("MooseApp", WorkBalance)
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual MooseMesh & mesh() override
This class is here to combine the VectorPostprocessor interface and the base class VectorPostprocesso...
static InputParameters validParams()
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
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.
Builds lists and maps that help in knowing which physical hardware nodes each rank is on.
processor_id_type size() const
void gather(const unsigned int root_id, const T &send_data, std::vector< T, A > &recv) const
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
Base class for assembly-like calculations.
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
VectorPostprocessorValue & declareVector(const std::string &vector_name)
Register a new vector to fill up.
Compute several metrics for each MPI process.
void gather(int balance_id, VectorPostprocessorValue &vppv)
std::map< std::string, VectorPostprocessorValue * > _balance_vectors
The VPP vectors that will hold the balance metrics.
WorkBalance(const InputParameters ¶meters)
dof_id_type _local_num_nodes
const RankMap & _rank_map
Helpful in determining the physical layout of the ranks.
VectorPostprocessorValue & _pid
virtual void finalize() override
Finalize.
MultiMooseEnum _balances
The chosen balance metrics to compute.
dof_id_type _local_num_partition_hardware_id_sides
static InputParameters validParams()
int _system
The system to count DoFs from.
dof_id_type _local_num_elems
dof_id_type _local_num_dofs
virtual void execute() override
Execute method.
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
Real _local_partition_hardware_id_surface_area
dof_id_type _local_num_partition_sides
Real _local_partition_surface_area
const Parallel::Communicator & _communicator
std::string toLower(std::string name)
Convert supplied string to lower case.
uint8_t processor_id_type
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
StoredRange< MeshBase::const_node_iterator, const Node * > ConstNodeRange
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real