15#include <deal.II/base/exceptions.h>
16#include <deal.II/base/mpi.h>
17#include <deal.II/base/numbers.h>
18#include <deal.II/base/utilities.h>
20#include <deal.II/distributed/tria.h>
22#include <deal.II/dofs/dof_handler.h>
24#include <deal.II/grid/tria.h>
26#include <deal.II/non_matching/mesh_classifier.h>
28#include <deal.II/numerics/solution_transfer.h>
33#include <boost/range/iterator_range.hpp>
34#include <boost/signals2/connection.hpp>
84 using CellIterator =
typename dealii::Triangulation<dim>::cell_iterator;
98 (
dynamic_cast<const dealii::parallel::distributed::Triangulation<dim> *
>(&tria_in) !=
101 "The weighted repartitioning requires a parallel::distributed::Triangulation."));
121 update(
const dealii::NonMatching::MeshClassifier<dim> &mesh_classifier)
127 for (
const auto &cell :
tria->active_cell_iterators())
128 if (cell->is_locally_owned())
129 weights[cell->active_cell_index()] =
148 if (cell->has_children())
150 unsigned int weight = 0;
151 for (
unsigned int c = 0; c < cell->n_children(); ++c)
152 weight = std::max(weight,
get_weight(cell->child(c)));
156 const unsigned int index = cell->active_cell_index();
160 dealii::ExcMessage(
"The cached partitioning weights are outdated. Call "
161 "PartitionWeights::update() after each change of the "
175 dealii::Utilities::MPI::MinMaxAvg
178 double local_load = 0.;
179 for (
const auto &cell :
tria->active_cell_iterators())
180 if (cell->is_locally_owned())
183 return dealii::Utilities::MPI::min_max_avg(local_load, mpi_comm);
188 const dealii::Triangulation<dim> *
tria;
210 auto &signals =
tria->signals;
213 [
this](
const CellIterator &cell,
const dealii::CellStatus) ->
unsigned int {
214 return this->get_weight(cell);
218 {&signals.pre_distributed_refinement, &signals.pre_distributed_repartition})
219 connections.emplace_back(signal->connect([
this]() { this->prepare_transfer(); }));
222 {&signals.post_distributed_refinement, &signals.post_distributed_repartition})
223 connections.emplace_back(signal->connect([
this]() { this->finish_transfer(); }));
236 Assert(
weights_handle == dealii::numbers::invalid_unsigned_int, dealii::ExcInternalError());
240 weights_handle =
const_cast<dealii::Triangulation<dim> &
>(*tria).register_data_attach(
241 [
this](
const CellIterator &cell,
const dealii::CellStatus) {
242 return dealii::Utilities::pack(this->
get_weight(cell),
false);
255 Assert(
weights_handle != dealii::numbers::invalid_unsigned_int, dealii::ExcInternalError());
257 std::vector<unsigned int> new_weights(
tria->n_active_cells(), 1);
259 const_cast<dealii::Triangulation<dim> &
>(*tria).notify_ready_to_unpack(
262 const dealii::CellStatus status,
263 const boost::iterator_range<std::vector<char>::const_iterator> &data) {
264 const auto weight = dealii::Utilities::unpack<unsigned int>(data.begin(),
269 if (status == dealii::CellStatus::cell_will_be_refined)
270 for (
const auto &child : cell->child_iterators())
271 new_weights[child->active_cell_index()] = weight;
273 new_weights[cell->active_cell_index()] = weight;
293 case dealii::NonMatching::LocationToLevelSet::inside:
296 case dealii::NonMatching::LocationToLevelSet::outside:
299 case dealii::NonMatching::LocationToLevelSet::intersected:
303 AssertThrow(
false, dealii::ExcMessage(
"Unknown location of the cell."));
345 template <
int dim,
typename VectorType>
348 [[maybe_unused]] dealii::Triangulation<dim> &tria,
350 [[maybe_unused]]
const std::function<
void()> &distribute_level_set_dofs,
351 [[maybe_unused]]
const dealii::DoFHandler<dim> &level_set_dof_handler,
352 [[maybe_unused]] VectorType &level_set_dof_vector,
353 [[maybe_unused]]
const std::function<
void()> &setup_dof_system,
354 [[maybe_unused]]
const std::function<
void()> &post = {})
356 if constexpr (dim == 1)
364 auto *distributed_tria =
365 dynamic_cast<dealii::parallel::distributed::Triangulation<dim> *
>(&tria);
367 if (distributed_tria ==
nullptr)
371 DoFHandlerAndVectorDataType<dim, VectorType> data;
374 attach_vectors(data);
375 data.shrink_to_fit();
378 const unsigned int n_dof_handlers = data.size();
381 std::vector<std::unique_ptr<dealii::SolutionTransfer<dim, VectorType>>> solution_transfers(
383 std::vector<std::vector<const VectorType *>> old_vectors(n_dof_handlers);
384 std::vector<std::vector<bool>> had_ghost_values(n_dof_handlers);
386 for (
unsigned int j = 0; j < n_dof_handlers; ++j)
388 std::vector<VectorType *> vectors;
389 data[j].second(vectors);
391 for (
const auto &v : vectors)
393 had_ghost_values[j].push_back(v->has_ghost_elements());
395 v->update_ghost_values();
396 old_vectors[j].push_back(v);
399 solution_transfers[j] =
400 std::make_unique<dealii::SolutionTransfer<dim, VectorType>>(*data[j].first);
401 solution_transfers[j]->prepare_for_coarsening_and_refinement(old_vectors[j]);
404 level_set_dof_vector.update_ghost_values();
405 dealii::SolutionTransfer<dim, VectorType> level_set_transfer(level_set_dof_handler);
406 level_set_transfer.prepare_for_coarsening_and_refinement(level_set_dof_vector);
410 distributed_tria->repartition();
413 distribute_level_set_dofs();
414 level_set_dof_vector.zero_out_ghost_values();
415 level_set_transfer.interpolate(level_set_dof_vector);
416 level_set_dof_vector.update_ghost_values();
423 if (n_dof_handlers > 0)
425 DoFHandlerAndVectorDataType<dim, VectorType> new_data;
426 attach_vectors(new_data);
428 for (
unsigned int j = 0; j < n_dof_handlers; ++j)
430 std::vector<VectorType *> new_vectors;
431 new_data[j].second(new_vectors);
433 for (
const auto &v : new_vectors)
436 solution_transfers[j]->interpolate(new_vectors);
438 for (
unsigned int i = 0; i < new_vectors.size(); ++i)
439 if (had_ghost_values[j][i])
440 new_vectors[i]->update_ghost_values();
463 return repartition_data.
enable and (n_time_step % repartition_data.
every_n_step == 0);
Cell weights for the repartitioning of a parallel::distributed::Triangulation according to the locati...
Definition repartition.hpp:82
void update(const dealii::NonMatching::MeshClassifier< dim > &mesh_classifier)
Compute and cache the weights of the locally owned active cells according to their location with resp...
Definition repartition.hpp:121
void finish_transfer()
Unpack the cached weights after the triangulation has changed.
Definition repartition.hpp:253
void prepare_transfer()
Attach the cached weights to the cells before the triangulation changes.
Definition repartition.hpp:234
dealii::Utilities::MPI::MinMaxAvg compute_load_statistics(const MPI_Comm mpi_comm) const
Compute statistics of the summed cell weights (i.e. the estimated load) of the locally owned cells ov...
Definition repartition.hpp:176
const CutRepartitionData repartition_data
Repartitioning parameters including the cell weights.
Definition repartition.hpp:191
typename dealii::Triangulation< dim >::cell_iterator CellIterator
Definition repartition.hpp:84
const dealii::Triangulation< dim > * tria
Pointer to the triangulation.
Definition repartition.hpp:188
std::vector< unsigned int > weights
Cached weights of the active cells (indexed by the active cell index)
Definition repartition.hpp:194
PartitionWeights(const dealii::Triangulation< dim > &tria_in, const CutRepartitionData &repartition_data_in)
Constructor.
Definition repartition.hpp:92
unsigned int get_partition_weight(const dealii::NonMatching::LocationToLevelSet location) const
Get the partitioning weight of a cell according to its location with respect to the level set.
Definition repartition.hpp:289
unsigned int weights_handle
Handle of the cell-attached weights during a change of the triangulation.
Definition repartition.hpp:197
unsigned int get_weight(const CellIterator &cell) const
Get the cached weight of a cell.
Definition repartition.hpp:146
void connect_to_triangulation()
Connect the function returning the cached weights to the weight signal of the triangulation,...
Definition repartition.hpp:208
std::vector< boost::signals2::scoped_connection > connections
Connections to the signals of the triangulation.
Definition repartition.hpp:200
Utilities for the weighted repartitioning of a parallel::distributed::Triangulation in cutFEM/cutDG a...
Definition amr.hpp:15
bool repartition_triangulation(dealii::Triangulation< dim > &tria, const AttachDoFHandlerAndVectorsType< dim, VectorType > &attach_vectors, const std::function< void()> &distribute_level_set_dofs, const dealii::DoFHandler< dim > &level_set_dof_handler, VectorType &level_set_dof_vector, const std::function< void()> &setup_dof_system, const std::function< void()> &post={})
Repartition the triangulation tria among the MPI processes and transfer the attached DoF vectors and ...
Definition repartition.hpp:347
bool do_repartition(const unsigned int n_time_step, const CutRepartitionData &repartition_data)
Determine whether the triangulation should be repartitioned at time step number n_time_step.
Definition repartition.hpp:461
std::function< void(DoFHandlerAndVectorDataType< dim, VectorType > &)> AttachDoFHandlerAndVectorsType
Definition attach_vectors.hpp:21
unsigned int intersected
Weight of cells intersected by the zero level-set isosurface.
Definition cut_data.hpp:97
unsigned int inside
Weight of cells located completely inside (negative level set)
Definition cut_data.hpp:91
unsigned int outside
Weight of cells located completely outside (positive level set)
Definition cut_data.hpp:94
Collection of parameters for the weighted repartitioning of the triangulation in cut applications.
Definition cut_data.hpp:74
bool enable
Definition cut_data.hpp:77
struct MeltPoolDG::CutRepartitionData::Weights weights
unsigned int every_n_step
The triangulation is repartitioned every n-th time step.
Definition cut_data.hpp:80