Wildmeshing Toolkit
InvariantCollection.cpp
Go to the documentation of this file.
2 #include <type_traits>
3 #include <wmtk/Mesh.hpp>
5 
6 namespace wmtk::invariants {
7 
9  : Invariant(m, true, true, true)
10 {}
15 {
16  assert(o.mesh() == mesh());
18  return *this;
19 }
21 {
22  assert(o.mesh() == mesh());
23  m_invariants = std::move(o.m_invariants);
24  return *this;
25 }
26 
27 void InvariantCollection::add(std::shared_ptr<Invariant> invariant)
28 {
29  m_invariants.emplace_back(std::move(invariant));
30 }
32 {
33  for (const auto& invariant : m_invariants) {
34  if (&mesh() != &invariant->mesh()) {
35  for (const Tuple& ct : mesh().map_tuples(invariant->mesh(), t)) {
36  if (!invariant->before(
37  simplex::Simplex(invariant->mesh(), t.primitive_type(), ct))) {
38  return false;
39  }
40  }
41  } else {
42  if (!invariant->before(t)) {
43  return false;
44  }
45  }
46  }
47  return true;
48 }
50  const std::vector<Tuple>& top_dimension_tuples_before,
51  const std::vector<Tuple>& top_dimension_tuples_after) const
52 {
53  for (const auto& invariant : m_invariants) {
54  if (&mesh() != &invariant->mesh()) {
55  const bool invariant_uses_old_state = invariant->use_old_state_in_after();
56  const bool invariant_uses_new_state = invariant->use_new_state_in_after();
57  if (!(invariant_uses_old_state || invariant_uses_new_state)) {
58  continue;
59  }
60  auto map = [&](const auto& tuples) {
61  return mesh().map_tuples(invariant->mesh(), mesh().top_simplex_type(), tuples);
62  };
63  const std::vector<Tuple> mapped_tuples_after =
64  invariant_uses_new_state ? map(top_dimension_tuples_after) : std::vector<Tuple>{};
65  const std::vector<Tuple> mapped_tuples_before =
66  invariant_uses_old_state ? mesh().parent_scope(map, top_dimension_tuples_before)
67  : std::vector<Tuple>{};
68  if (!invariant->after(mapped_tuples_before, mapped_tuples_after)) {
69  return false;
70  }
71  } else {
72  if (!invariant->after(top_dimension_tuples_before, top_dimension_tuples_after)) {
73  return false;
74  }
75  }
76  // assert(&mesh() != &invariant->mesh());
77  // if (!invariant->after(type, tuples)) {
78  // return false;
79  // }
80  }
81  return true;
82 }
83 
85  const std::vector<simplex::Simplex>& simplices_before,
86  const std::vector<simplex::Simplex>& simplices_after) const
87 {
88 #ifndef NDEBUG
89  for (const auto& s : simplices_before) {
90  mesh().parent_scope([&]() { assert(mesh().is_valid(s.tuple())); });
91  }
92  for (const auto& s : simplices_after) {
93  assert(mesh().is_valid(s.tuple()));
94  }
95 #endif
96 
97  for (const auto& invariant : m_invariants) {
98  if (&mesh() != &invariant->mesh()) {
99  auto mapped_simplices_after = mesh().map(invariant->mesh(), simplices_after);
100  auto mapped_simplices_before = mesh().parent_scope(
101  [&]() { return mesh().map(invariant->mesh(), simplices_before); });
102 #ifndef NDEBUG
103  for (const auto& s : mapped_simplices_before) {
104  mesh().parent_scope([&]() { assert(invariant->mesh().is_valid(s.tuple())); });
105  }
106  for (const auto& s : mapped_simplices_after) {
107  assert(invariant->mesh().is_valid(s.tuple()));
108  }
109  assert(mesh().is_from_same_multi_mesh_structure(invariant->mesh()));
110 #endif
111  if (!invariant->directly_modified_after(
112  mapped_simplices_before,
113  mapped_simplices_after)) {
114  return false;
115  }
116  } else {
117  if (!invariant->directly_modified_after(simplices_before, simplices_after)) {
118  return false;
119  }
120  }
121  }
122  return true;
123 }
124 
125 const std::shared_ptr<Invariant>& InvariantCollection::get(int64_t index) const
126 {
127  return m_invariants.at(index);
128 }
130 {
131  return m_invariants.size();
132 }
134 {
135  return m_invariants.empty();
136 }
137 const std::vector<std::shared_ptr<Invariant>>& InvariantCollection::invariants() const
138 {
139  return m_invariants;
140 }
141 
142 std::map<Mesh const*, std::vector<std::shared_ptr<Invariant>>>
144 {
145  decltype(get_map_mesh_to_invariants()) mesh_invariants_map;
146 
147  throw std::runtime_error("Untested code. Potentially wrong.");
148 
149  for (std::shared_ptr<Invariant> inv : m_invariants) {
150  // TODO check if that if statement is correct
151  if (std::is_base_of<InvariantCollection, decltype(inv)::element_type>()) {
152  // go through invariant collections
153  InvariantCollection& sub_ic = static_cast<InvariantCollection&>(*inv);
154  decltype(mesh_invariants_map) sub_map = sub_ic.get_map_mesh_to_invariants();
155 
156  for (const auto& [mptr, i] : sub_map) {
157  auto& vec = mesh_invariants_map[mptr];
158  vec.insert(vec.end(), i.begin(), i.end());
159  }
160  } else {
161  mesh_invariants_map[&(inv->mesh())].push_back(inv);
162  }
163  }
164  //
165 }
166 
167 } // namespace wmtk::invariants
std::vector< Tuple > map_tuples(const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
maps a simplex from this mesh to any other mesh
std::vector< simplex::Simplex > map(const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
maps a simplex from this mesh to any other mesh
decltype(auto) parent_scope(Functor &&f, Args &&... args) const
Evaluate the passed in function inside the parent scope.
bool directly_modified_after(const std::vector< simplex::Simplex > &simplices_before, const std::vector< simplex::Simplex > &simplices_after) const override
void add(std::shared_ptr< Invariant > invariant)
bool before(const simplex::Simplex &t) const override
bool after(const std::vector< Tuple > &top_dimension_tuples_before, const std::vector< Tuple > &top_dimension_tuples_after) const override
std::vector< std::shared_ptr< Invariant > > m_invariants
std::map< Mesh const *, std::vector< std::shared_ptr< Invariant > > > get_map_mesh_to_invariants()
const std::shared_ptr< Invariant > & get(int64_t index) const
const std::vector< std::shared_ptr< Invariant > > & invariants() const
InvariantCollection & operator=(const InvariantCollection &)
const Mesh & mesh() const
Definition: Invariant.cpp:35
PrimitiveType primitive_type() const
Definition: Simplex.hpp:51