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