Wildmeshing Toolkit
MultiMeshSimplexEventVisitor.hpp
Go to the documentation of this file.
1 #pragma once
2 
4 
5 namespace wmtk::multimesh {
6 template <int64_t cell_dimension, typename Functor>
8 {
9 public:
12  : m_visitor(visitor)
13  {}
14  template <typename T>
15  using GetReturnType_t = typename VisitorType::template GetReturnType_t<T>;
16 
17  auto node_events() const { return m_visitor.node_events(); }
18  const auto& edge_events() const { return m_visitor.edge_events(); }
19 
20  template <typename NodeFunctor>
21  void run_on_nodes(NodeFunctor&& node_functor);
22  template <typename EdgeFunctor>
23  void run_on_edges(EdgeFunctor&& edge_functor);
24 
25  template <typename MeshType, typename... OtherArgumentTypes>
26  const auto& get_cached_return(const MeshType& m, OtherArgumentTypes&&... args) const
27  {
28  return m_visitor.cache().get(m, std::forward<OtherArgumentTypes>(args)...);
29  }
30 
31 private:
33 };
34 template <int64_t cell_dimension, typename Functor>
37 
38 template <int64_t cell_dimension, typename Functor>
39 template <typename EdgeFunctor>
41 {
42  // go through every edge event and run the edge functor on it
43  for (const auto& pr : edge_events()) {
44  // why does clang hate structured bindings so much?
45  const auto& keyA = std::get<0>(pr);
46  const auto& keyB = std::get<1>(pr);
47  // const auto& [parent_ptr, sa] = keyA;
48  // const auto& [child_ptr, sb] = keyB;
49 
50 
51  // extract all the specific types for the edge events
52  std::visit(
53  [&](auto parent_mesh_, auto child_mesh_) noexcept {
54  auto& parent_mesh = parent_mesh_.get();
55  auto& child_mesh = child_mesh_.get();
56  using ChildType = std::decay_t<decltype(child_mesh)>;
57  using ParentType = std::decay_t<decltype(parent_mesh)>;
58 
59  // logger().trace(
60  // "going through edge cache {} => {}",
61  // fmt::join(parent_mesh.absolute_multi_mesh_id(), ","),
62  // fmt::join(child_mesh.absolute_multi_mesh_id(), ","));
63 
64  constexpr static int64_t ParentDim =
65  wmtk::utils::metaprogramming::cell_dimension_v<ParentType>;
66  constexpr static int64_t ChildDim =
67  wmtk::utils::metaprogramming::cell_dimension_v<ChildType>;
68 
69  using ParentReturnType = GetReturnType_t<ParentType>;
70  using ChildReturnType = GetReturnType_t<ChildType>;
71 
72  constexpr static bool ChildHasReturn = !std::is_void_v<ChildReturnType>;
73  constexpr static bool ParentHasReturn = !std::is_void_v<ParentReturnType>;
74 
75  if constexpr (ParentDim >= ChildDim && ChildHasReturn && ParentHasReturn) {
76  const ParentReturnType& parent_return =
77  get_cached_return(parent_mesh, std::get<1>(keyA));
78  const ChildReturnType& child_return =
79  get_cached_return(child_mesh, std::get<1>(keyB));
80  edge_functor(
81  parent_mesh,
82  std::get<1>(keyA),
83  parent_return,
84  child_mesh,
85  std::get<1>(keyB),
86  child_return);
87  }
88  },
89  // TODO: this const casting is ugly, const referencing for the edge functor needs to
90  // be fixed
91  wmtk::utils::metaprogramming::as_mesh_variant(*const_cast<Mesh*>(std::get<0>(keyA))),
92  wmtk::utils::metaprogramming::as_mesh_variant(*const_cast<Mesh*>(std::get<0>(keyB))));
93  }
94 }
95 
96 template <int64_t cell_dimension, typename Functor>
97 template <typename NodeFunctor>
99 {
100  // go through every edge event and run the edge functor on it
101  for (const auto& event : node_events()) {
102  // extract all the specific types for the edge events
103  std::visit(
104  [&](auto parent_mesh_) noexcept {
105  auto& parent_mesh = parent_mesh_.get();
106  using ParentType = std::decay_t<decltype(parent_mesh)>;
107 
108 
109  constexpr static int64_t ParentDim =
110  wmtk::utils::metaprogramming::cell_dimension_v<ParentType>;
111 
112  using ParentReturnType = GetReturnType_t<ParentType>;
113 
114  constexpr static bool ParentHasReturn = !std::is_void_v<ParentReturnType>;
115 
116  if constexpr (ParentHasReturn) {
117  const ParentReturnType& parent_return =
118  get_cached_return(parent_mesh, std::get<1>(event));
119  node_functor(parent_mesh, std::get<1>(event), parent_return);
120  }
121  },
122  // TODO: this const casting is ugly, const referencing for the edge functor needs to
123  // be fixed
124  wmtk::utils::metaprogramming::as_mesh_variant(*const_cast<Mesh*>(std::get<0>(event))));
125  }
126 }
127 
128 } // namespace wmtk::multimesh
MultiMeshSimplexEventVisitor(const MultiMeshSimplexVisitor< cell_dimension, Functor > &visitor)
typename VisitorType::template GetReturnType_t< T > GetReturnType_t
const auto & get_cached_return(const MeshType &m, OtherArgumentTypes &&... args) const
MultiMeshSimplexEventVisitor(const MultiMeshSimplexVisitor< cell_dimension, Functor > &visitor) -> MultiMeshSimplexEventVisitor< cell_dimension, Functor >
MeshVariantType as_mesh_variant(Mesh &mesh)