Skip to content

Commit

Permalink
Enable cache for parallel::CellWeights.
Browse files Browse the repository at this point in the history
  • Loading branch information
marcfehling committed Apr 11, 2024
1 parent ab68047 commit 842ce7e
Show file tree
Hide file tree
Showing 6 changed files with 286 additions and 92 deletions.
5 changes: 5 additions & 0 deletions doc/news/changes/minor/20240124Fehling
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
New: parallel::CellWeights is now able to optionally cache weights.
This requires that the weights are determined only by information
about finite elements.
<br>
(Marc Fehling, 2024/01/24)
8 changes: 7 additions & 1 deletion examples/step-75/step-75.cc
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,11 @@ namespace Step75
// the form that $a (n_\text{dofs})^b$ with a provided pair of parameters
// $(a,b)$. We register such a function in the following.
//
// Since we are only using information about the number of degrees of
// freedom per cell, which is a quantity unique to every finite element, we
// can compute the weights in advance. A cache can be set up automatically
// with the `enable_fe_cache` parameter.
//
// For load balancing, efficient solvers like the one we use should scale
// linearly with the number of degrees of freedom owned. We set the
// parameters for cell weighting correspondingly: A weighting factor of $1$
Expand All @@ -987,7 +992,8 @@ namespace Step75
cell_weights = std::make_unique<parallel::CellWeights<dim>>(
dof_handler,
parallel::CellWeights<dim>::ndofs_weighting(
{prm.weighting_factor, prm.weighting_exponent}));
{prm.weighting_factor, prm.weighting_exponent}),
/*enable_fe_cache=*/true);

// In h-adaptive applications, we ensure a 2:1 mesh balance by limiting the
// difference of refinement levels of neighboring cells to one. With the
Expand Down
129 changes: 92 additions & 37 deletions include/deal.II/distributed/cell_weights.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,21 @@ namespace parallel
* hp_dof_handler.get_triangulation().signals.weight.connect(
* parallel::CellWeights<dim, spacedim>::make_weighting_callback(
* hp_dof_handler,
* parallel::CellWeights<dim, spacedim>::ndofs_weighting({1, 1}));
* parallel::CellWeights<dim, spacedim>::ndofs_weighting({1, 1})));
* @endcode
*
* Oftentimes, the weighting function only requires information about the
* finite element (for example about the number of degrees of freedom per
* cell), but not the cell we are currently considering (even though the
* weighting function takes a cell iterator as argument). In this case, it is
* wasteful to re-compute the weight on every cell we visit; instead, the
* weights can be computed for each finite element in use on the DoFHandler in
* advance, and then cached. Such a cache can be set up automatically by using
* the `enable_fe_cache` flag in the constructor or reinit() function, or by
* using the make_cached_weighting_callback() function. Of course, in this
* case no other cell-specific information can be used in the computation of
* the weights.
*
* The use of this class is demonstrated in step-75.
*
* @note See Triangulation::Signals::weight for more information on
Expand Down Expand Up @@ -117,6 +129,45 @@ namespace parallel
unsigned int(const typename DoFHandler<dim, spacedim>::cell_iterator &,
const FiniteElement<dim, spacedim> &)>;

/**
* @name Selection of weighting functions
* @{
*/

/**
* Choose a constant weight @p factor on each cell.
*/
static WeightingFunction
constant_weighting(const unsigned int factor = 1);

/**
* The pair of floating point numbers $(a,b)$ provided via
* @p coefficients determines the weight $w_K$ of each cell $K$ with
* $n_K$ degrees of freedom in the following way: \f[ w_K =
* a \, n_K^b \f]
*
* The right hand side will be rounded to the nearest integer since cell
* weights are required to be integers.
*/
static WeightingFunction
ndofs_weighting(const std::pair<float, float> &coefficients);

/**
* The container @p coefficients provides pairs of floating point numbers
* $(a_i, b_i)$ that determine the weight $w_K$ of each cell
* $K$ with $n_K$ degrees of freedom in the following way: \f[ w_K =
* \sum_i a_i \, n_K^{b_i} \f]
*
* The right hand side will be rounded to the nearest integer since cell
* weights are required to be integers.
*/
static WeightingFunction
ndofs_weighting(const std::vector<std::pair<float, float>> &coefficients);

/**
* @}
*/

/**
* Constructor.
*
Expand All @@ -131,9 +182,12 @@ namespace parallel
* determine each cell's finite element.
* @param[in] weighting_function The function that determines each
* cell's weight during load balancing.
* @param[in] enable_fe_cache Determine weights in advance for each
* finite element. Omits all other cell-specific characteristics.
*/
CellWeights(const DoFHandler<dim, spacedim> &dof_handler,
const WeightingFunction &weighting_function);
const WeightingFunction &weighting_function,
const bool enable_fe_cache = false);

/**
* Destructor.
Expand All @@ -146,11 +200,17 @@ namespace parallel
* Connect a different @p weighting_function to the Triangulation
* associated with the @p dof_handler.
*
* With @p enable_fe_cache set to true, we determine weights in advance for
* each finite element of @p dof_handler and build a cache. Thus, to determine
* a cell's weight, only information on its finite element will be used, and
* all other cell-specific characteristics are omitted.
*
* Disconnects the function previously connected to the weighting signal.
*/
void
reinit(const DoFHandler<dim, spacedim> &dof_handler,
const WeightingFunction &weighting_function);
const WeightingFunction &weighting_function,
const bool enable_fe_cache = false);

/**
* Converts a @p weighting_function to a different type that qualifies as
Expand All @@ -167,43 +227,23 @@ namespace parallel
const WeightingFunction &weighting_function);

/**
* @name Selection of weighting functions
* @{
*/

/**
* Choose a constant weight @p factor on each cell.
*/
static WeightingFunction
constant_weighting(const unsigned int factor = 1);

/**
* The pair of floating point numbers $(a,b)$ provided via
* @p coefficients determines the weight $w_K$ of each cell $K$ with
* $n_K$ degrees of freedom in the following way: \f[ w_K =
* a \, n_K^b \f]
* Use @p weighting_function to evaluate the weight for each finite element
* of @p dof_handler. These weights act as a cache and will be used to
* determine each cell's weight. All other cell-specific characteristics in
* determining weights are omitted.
*
* The right hand side will be rounded to the nearest integer since cell
* weights are required to be integers.
*/
static WeightingFunction
ndofs_weighting(const std::pair<float, float> &coefficients);

/**
* The container @p coefficients provides pairs of floating point numbers
* $(a_i, b_i)$ that determine the weight $w_K$ of each cell
* $K$ with $n_K$ degrees of freedom in the following way: \f[ w_K =
* \sum_i a_i \, n_K^{b_i} \f]
* Returns a callback function, which can be connected to a weighting signal
* of a Triangulation.
*
* The right hand side will be rounded to the nearest integer since cell
* weights are required to be integers.
*/
static WeightingFunction
ndofs_weighting(const std::vector<std::pair<float, float>> &coefficients);

/**
* @}
* This function does <b>not</b> connect the callback function to the
* Triangulation associated with the @p dof_handler.
*/
static std::function<unsigned int(
const typename dealii::Triangulation<dim, spacedim>::cell_iterator &cell,
const CellStatus status)>
make_weighting_callback_with_cache(
const DoFHandler<dim, spacedim> &dof_handler,
const WeightingFunction &weighting_function);

private:
/**
Expand All @@ -226,6 +266,21 @@ namespace parallel
const DoFHandler<dim, spacedim> &dof_handler,
const parallel::TriangulationBase<dim, spacedim> &triangulation,
const WeightingFunction &weighting_function);

/**
* A callback function that will be connected to the `weight` signal of
* the @p triangulation, to which the @p dof_handler is attached. Ultimately
* returns the weight for each cell, determined by the @p weight_cache
* provided as a parameter. Returns zero if @p dof_handler has not been
* initialized yet.
*/
static unsigned int
weighting_callback_with_cache(
const typename dealii::Triangulation<dim, spacedim>::cell_iterator &cell,
const CellStatus status,
const DoFHandler<dim, spacedim> &dof_handler,
const parallel::TriangulationBase<dim, spacedim> &triangulation,
const std::vector<unsigned int> &weight_cache);
};
} // namespace parallel

Expand Down

0 comments on commit 842ce7e

Please sign in to comment.