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)
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. 
std::string toLower(std::string name)
Convert supplied string to lower case. 
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 and optionally a file path to the top-level block p...
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.