/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/common/serial_mirror.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/common/serial_mirror.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
serial_mirror.hh
Go to the documentation of this file.
1#pragma once
2
3// external libraries
4#include <boost/signals2/connection.hpp>
5
6#include <deal.II/distributed/tria_base.h>
7#include <deal.II/grid/tria.h>
8
9// standard library
10#include <map>
11#include <memory>
12#include <mutex>
13
14namespace DiFfRG
15{
47 template <int dim> const dealii::Triangulation<dim> &serial_mirror(const dealii::Triangulation<dim> &source)
48 {
49 if (dynamic_cast<const dealii::parallel::TriangulationBase<dim> *>(&source) == nullptr) return source;
50
51 struct Mirror {
52 std::unique_ptr<dealii::Triangulation<dim>> triangulation;
53 boost::signals2::scoped_connection connection;
54 bool stale = true;
55 };
56
57 static std::mutex mirrors_mutex;
58 static std::map<const dealii::Triangulation<dim> *, Mirror> mirrors;
59
60 std::scoped_lock lock(mirrors_mutex);
61 auto &mirror = mirrors[&source];
62 // A dead connection means the triangulation this entry was built for is gone and something else
63 // now occupies its address, so the cached copy describes a different mesh entirely. Destroying a
64 // triangulation disconnects its slots, which makes this a reliable test.
65 if (!mirror.triangulation || !mirror.connection.connected()) {
66 if (!mirror.triangulation) mirror.triangulation = std::make_unique<dealii::Triangulation<dim>>();
67 mirror.connection = source.signals.any_change.connect([&source]() {
68 std::scoped_lock relock(mirrors_mutex);
69 const auto it = mirrors.find(&source);
70 if (it != mirrors.end()) it->second.stale = true;
71 });
72 mirror.stale = true;
73 }
74
75 auto &copy = *mirror.triangulation;
76 const bool size_mismatch = copy.n_active_cells() != source.n_active_cells() ||
77 copy.n_levels() != source.n_levels() || copy.n_vertices() != source.n_vertices();
78 if (mirror.stale || size_mismatch) {
79 copy.clear();
80 copy.copy_triangulation(source);
81 mirror.stale = false;
82 }
83 return copy;
84 }
85} // namespace DiFfRG
Definition complex_math.hh:10
const dealii::Triangulation< dim > & serial_mirror(const dealii::Triangulation< dim > &source)
A process-local, serial mirror of a (possibly partitioned) triangulation.
Definition serial_mirror.hh:47