Wildmeshing Toolkit
MeshCRTP.hpp
Go to the documentation of this file.
1 #pragma once
2 #include "Mesh.hpp"
3 #if defined(__cpp_concepts) && defined(__cpp_lib_ranges)
4 #include <ranges>
5 #endif
6 
7 
8 namespace wmtk {
9 
10 namespace attribute {
11 template <typename T, typename MeshType, int Dim>
12 class Accessor;
13 }
14 
22 template <typename Derived>
23 class MeshCRTP : public Mesh
24 {
25 private:
26  // using Mesh::create_accessor;
27  // using Mesh::create_const_accessor;
28 
29 public:
30  template <typename U, typename MeshType, int Dim>
31  friend class attribute::Accessor;
32  template <int64_t cell_dimension, typename NodeFunctor>
34  using Mesh::Mesh;
36  Derived& derived() { return static_cast<Derived&>(*this); }
38  const Derived& derived() const { return static_cast<const Derived&>(*this); }
39 
40  Tuple switch_tuple(const Tuple& tuple, PrimitiveType type) const override
41  {
42  assert(type <= top_simplex_type());
43  return derived().switch_tuple(tuple, type);
44  }
47 #if defined(__cpp_concepts) && defined(__cpp_lib_ranges)
48  template <std::ranges::forward_range ContainerType>
49 #else
50  template <typename ContainerType>
51 #endif
52  Tuple switch_tuples(const Tuple& tuple, const ContainerType& op_sequence) const;
54  Tuple switch_tuples(const Tuple& tuple, const std::initializer_list<PrimitiveType>& op_sequence)
55  const;
56 
58  bool is_ccw(const Tuple& tuple) const override { return derived().is_ccw(tuple); }
60  bool is_boundary(PrimitiveType pt, const Tuple& tuple) const override
61  {
62  return derived().is_boundary(pt, tuple);
63  }
64 
66  template <typename T, int Dim = Eigen::Dynamic>
68  const TypedAttributeHandle<T>& handle)
69  {
71  }
73  template <typename T, int Dim = Eigen::Dynamic>
75  const attribute::TypedAttributeHandle<T>& handle) const
76  {
78  }
79 
81  template <typename T, int Dim = Eigen::Dynamic>
83  const attribute::MeshAttributeHandle& handle)
84  {
85  assert(&handle.mesh() == this);
86  assert(handle.holds<T>());
87  return create_accessor<T, Dim>(handle.as<T>());
88  }
89 
90 
92  template <typename T, int Dim = Eigen::Dynamic>
94  const attribute::MeshAttributeHandle& handle) const
95  {
96  assert(&handle.mesh() == this);
97  assert(handle.holds<T>());
98  return create_const_accessor<T, Dim>(handle.as<T>());
99  }
100 
101 protected:
103  int64_t id(const Tuple& tuple, PrimitiveType type) const { return derived().id(tuple, type); }
106  int64_t id_virtual(const Tuple& tuple, PrimitiveType type) const final override
107  {
108  return id(tuple, type);
109  }
110 
112  int64_t id(const simplex::Simplex& s) const final override
113  {
114 
115  return id(s.tuple(),s.primitive_type());
116  }
117 
118  // catch any other Mesh id methods that might emerge by default
119  using Mesh::id;
120 
121 
122 protected:
123  Tuple tuple_from_id(const PrimitiveType type, const int64_t gid) const override
124  {
125  return derived().tuple_from_id(type, gid);
126  }
127 };
128 
129 template <typename Derived>
130 #if defined(__cpp_concepts) && defined(__cpp_lib_ranges)
131 template <std::ranges::forward_range ContainerType>
132 #else
133 template <typename ContainerType>
134 #endif
135 Tuple MeshCRTP<Derived>::switch_tuples(const Tuple& tuple, const ContainerType& sequence) const
136 {
137  static_assert(std::is_same_v<typename ContainerType::value_type, PrimitiveType>);
138  Tuple r = tuple;
139  const PrimitiveType top_type = top_simplex_type();
140 
141  const int64_t boundary_dim = top_cell_dimension() - 1;
142  const PrimitiveType boundary_pt = static_cast<PrimitiveType>(boundary_dim);
143 
144  for (const PrimitiveType primitive : sequence) {
145  // for top level simplices we cannot navigate across boundaries
146  if (primitive == top_type && is_boundary(boundary_pt, r)) {
147  assert(!is_boundary(boundary_pt, r));
148  r = {};
149  return r;
150  }
151  r = switch_tuple(r, primitive);
152  }
153  return r;
154 }
155 
156 
157 template <typename Derived>
159  const Tuple& tuple,
160  const std::initializer_list<PrimitiveType>& op_sequence) const
161 {
162  return switch_tuples<std::initializer_list<PrimitiveType>>(tuple, op_sequence);
163 }
164 } // namespace wmtk
A Curiously Recurring Template Pattern shim to enable generic specialization of functions.
Definition: MeshCRTP.hpp:24
int64_t id_virtual(const Tuple &tuple, PrimitiveType type) const final override
internal utility for overriding the mesh class's id function without having the final override block ...
Definition: MeshCRTP.hpp:106
Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const override
switch the orientation of the Tuple of the given dimension
Definition: MeshCRTP.hpp:40
Derived & derived()
CRTP utility to extract the derived type of this.
Definition: MeshCRTP.hpp:36
attribute::Accessor< T, Derived, Dim > create_accessor(const TypedAttributeHandle< T > &handle)
constructs an accessor that is aware of the derived mesh's type
Definition: MeshCRTP.hpp:67
const Derived & derived() const
CRTP utility to extract the derived type of this with constnesss.
Definition: MeshCRTP.hpp:38
int64_t id(const Tuple &tuple, PrimitiveType type) const
return the global id of the Tuple of the given dimension
Definition: Mesh.hpp:1021
attribute::Accessor< T, Derived, Dim > create_accessor(const attribute::MeshAttributeHandle &handle)
constructs a accessor that is aware of the derived mesh's type
Definition: MeshCRTP.hpp:82
const attribute::Accessor< T, Derived, Dim > create_const_accessor(const attribute::TypedAttributeHandle< T > &handle) const
constructs a const accessor that is aware of the derived mesh's type
Definition: MeshCRTP.hpp:74
bool is_ccw(const Tuple &tuple) const override
returns if a tuple is counterclockwise or not
Definition: MeshCRTP.hpp:58
Tuple switch_tuples(const Tuple &tuple, const std::initializer_list< PrimitiveType > &op_sequence) const
annoying initializer list prototype to catch switch_tuples(t, {PV,PE})
Definition: MeshCRTP.hpp:158
Tuple tuple_from_id(const PrimitiveType type, const int64_t gid) const override
internal function that returns the tuple of requested type, and has the global index cid
Definition: MeshCRTP.hpp:123
int64_t id(const Tuple &tuple, PrimitiveType type) const
Returns the id of a simplex encoded in a tuple.
Definition: MeshCRTP.hpp:103
int64_t id(const simplex::Simplex &s) const final override
variant of id that can cache internally held values
Definition: MeshCRTP.hpp:112
bool is_boundary(PrimitiveType pt, const Tuple &tuple) const override
returns if a simplex is on the boundary of hte mesh. For anything but dimension - 1 this checks if th...
Definition: MeshCRTP.hpp:60
Tuple switch_tuples(const Tuple &tuple, const ContainerType &op_sequence) const
Performs a sequence of switch_tuple operations in the order specified in op_sequence.
Definition: MeshCRTP.hpp:135
const attribute::Accessor< T, Derived, Dim > create_const_accessor(const attribute::MeshAttributeHandle &handle) const
constructs a const accessor that is aware of the derived mesh's type
Definition: MeshCRTP.hpp:93
Mesh(const int64_t &dimension)
int64_t id(const Tuple &tuple, PrimitiveType type) const
return the global id of the Tuple of the given dimension
Definition: Mesh.hpp:1021
PrimitiveType top_simplex_type() const
Definition: Mesh.hpp:997
A CachingAccessor that uses tuples for accessing attributes instead of indices.
Definition: Accessor.hpp:25
auto as() const -> const held_handle_type< held_type_from_primitive< T >()> &
Handle that represents attributes for some mesh.
Definition: Accessor.hpp:6