Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
element_restriction.hpp
1 #pragma once
2 
3 #include <vector>
4 
5 #include "mfem.hpp"
6 #include "axom/core.hpp"
7 #include "geometry.hpp"
8 
9 inline bool isH1(const mfem::FiniteElementSpace& fes)
10 {
11  return (fes.FEColl()->GetContType() == mfem::FiniteElementCollection::CONTINUOUS);
12 }
13 
14 inline bool isHcurl(const mfem::FiniteElementSpace& fes)
15 {
16  return (fes.FEColl()->GetContType() == mfem::FiniteElementCollection::TANGENTIAL);
17 }
18 
19 inline bool isDG(const mfem::FiniteElementSpace& fes)
20 {
21  return (fes.FEColl()->GetContType() == mfem::FiniteElementCollection::DISCONTINUOUS);
22 }
23 
24 enum class FaceType
25 {
26  BOUNDARY,
27  INTERIOR
28 };
29 
31 struct DoF {
32  // sam: I wanted to use a bitfield for this type, but a 10+ year-old GCC bug
33  // makes it practically impossible to assign to bitfields without warnings/errors
34  // with -Wconversion enabled, see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39170
35  // So, we resort to masks and bitshifting instead.
36 
37  static constexpr uint64_t sign_mask = 0x8000'0000'0000'0000;
38  static constexpr uint64_t orientation_mask = 0x7000'0000'0000'0000;
39  static constexpr uint64_t index_mask = 0x0000'FFFF'FFFF'FFFF'FFFF;
40 
41  static constexpr uint64_t sign_shift = 63;
42  static constexpr uint64_t orientation_shift = 60;
43  static constexpr uint64_t index_shift = 0;
44 
55  uint64_t bits;
56 
58  DoF() : bits{} {}
59 
61  DoF(const DoF& other) : bits{other.bits} {}
62 
64  DoF(uint64_t index, uint64_t sign = 0, uint64_t orientation = 0)
65  : bits((sign & 0x1ULL << sign_shift) + ((orientation & 0x7ULL) << orientation_shift) + index)
66  {
67  }
68 
70  void operator=(const DoF& other) { bits = other.bits; }
71 
73  int sign() const { return (bits & sign_mask) ? -1 : 1; }
74 
76  uint64_t orientation() const { return ((bits & orientation_mask) >> orientation_shift); }
77 
79  uint64_t index() const { return (bits & index_mask); }
80 };
81 
83 template <typename T>
84 struct Range {
85  T* begin() { return ptr[0]; }
86  T* end() { return ptr[1]; }
87  T* ptr[2];
88 };
89 
95 template <typename T>
96 struct Array2D {
97  Array2D() : values{}, dim{} {};
98 
100  Array2D(uint64_t m, uint64_t n) : values(m * n, 0), dim{m, n} {};
101 
103  Array2D(std::vector<T>&& data, uint64_t m, uint64_t n) : values(data), dim{m, n} {};
104 
106  Range<T> operator()(uint64_t i) { return Range<T>{&values[i * dim[1]], &values[(i + 1) * dim[1]]}; }
107 
109  Range<const T> operator()(uint64_t i) const { return Range<const T>{&values[i * dim[1]], &values[(i + 1) * dim[1]]}; }
110 
112  T& operator()(uint64_t i, uint64_t j) { return values[i * dim[1] + j]; }
113 
115  const T& operator()(uint64_t i, uint64_t j) const { return values[i * dim[1] + j]; }
116 
118  Array2D(int m, int n) : values(uint64_t(m) * uint64_t(n), 0), dim{uint64_t(m), uint64_t(n)} {}
119 
121  Array2D(std::vector<T>&& data, int m, int n) : values(data), dim{uint64_t(m), uint64_t(n)} {}
122 
124  Range<T> operator()(int i) { return Range<T>{&values[uint64_t(i) * dim[1]], &values[uint64_t(i + 1) * dim[1]]}; }
125 
128  {
129  return Range<const T>{&values[uint64_t(i) * dim[1]], &values[uint64_t(i + 1) * dim[1]]};
130  }
131 
133  T& operator()(int i, int j) { return values[uint64_t(i) * dim[1] + uint64_t(j)]; }
134 
136  const T& operator()(int i, int j) const { return values[uint64_t(i) * dim[1] + uint64_t(j)]; }
137 
138  std::vector<T> values;
139  uint64_t dim[2];
140 };
141 
142 namespace serac {
143 
149 
151  ElementRestriction(const mfem::FiniteElementSpace* fes, mfem::Geometry::Type elem_geom);
152 
154  ElementRestriction(const mfem::FiniteElementSpace* fes, mfem::Geometry::Type face_geom, FaceType type);
155 
157  uint64_t ESize() const;
158 
160  uint64_t LSize() const;
161 
168  void GetElementVDofs(int i, std::vector<DoF>& dofs) const;
169 
171  DoF GetVDof(DoF node, uint64_t component) const;
172 
174  void Gather(const mfem::Vector& L_vector, mfem::Vector& E_vector) const;
175 
177  void ScatterAdd(const mfem::Vector& E_vector, mfem::Vector& L_vector) const;
178 
180  uint64_t esize;
181 
183  uint64_t lsize;
184 
186  uint64_t components;
187 
189  uint64_t num_nodes;
190 
192  uint64_t num_elements;
193 
195  uint64_t nodes_per_elem;
196 
198  axom::Array<DoF, 2, axom::MemorySpace::Host> dof_info;
199 
201  mfem::Ordering::Type ordering;
202 };
203 
212 
214  BlockElementRestriction(const mfem::FiniteElementSpace* fes);
215 
217  BlockElementRestriction(const mfem::FiniteElementSpace* fes, FaceType type);
218 
220  uint64_t ESize() const;
221 
223  uint64_t LSize() const;
224 
226  mfem::Array<int> bOffsets() const;
227 
229  void Gather(const mfem::Vector& L_vector, mfem::BlockVector& E_block_vector) const;
230 
232  void ScatterAdd(const mfem::BlockVector& E_block_vector, mfem::Vector& L_vector) const;
233 
235  std::map<mfem::Geometry::Type, ElementRestriction> restrictions;
236 };
237 
238 } // namespace serac
239 
246 Array2D<DoF> GetElementDofs(mfem::FiniteElementSpace* fes, mfem::Geometry::Type geom);
247 
255 Array2D<DoF> GetFaceDofs(mfem::FiniteElementSpace* fes, mfem::Geometry::Type face_geom, FaceType type);
Accelerator functionality.
Definition: serac.cpp:38
bool isHcurl(const mfem::ParFiniteElementSpace &fes)
return whether or not the underlying function space is Hcurl or not
constexpr SERAC_HOST_DEVICE auto type(const tuple< T... > &values)
a function intended to be used for extracting the ith type from a tuple.
Definition: tuple.hpp:274
a 2D array
Array2D(std::vector< T > &&data, uint64_t m, uint64_t n)
create an m-by-n two-dimensional array initialized with the values in data (assuming row-major)
uint64_t dim[2]
the number of rows and columns in the array, respectively
Range< T > operator()(int i)
This is an overloaded member function, provided for convenience. It differs from the above function o...
const T & operator()(int i, int j) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::vector< T > values
the values of each element in the array
Range< const T > operator()(int i) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Array2D(uint64_t m, uint64_t n)
create an uninitialized m-by-n two-dimensional array
Range< const T > operator()(uint64_t i) const
access an immutable "row" of this Array2D
Range< T > operator()(uint64_t i)
access a mutable "row" of this Array2D
Array2D(int m, int n)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Array2D(std::vector< T > &&data, int m, int n)
This is an overloaded member function, provided for convenience. It differs from the above function o...
T & operator()(int i, int j)
This is an overloaded member function, provided for convenience. It differs from the above function o...
T & operator()(uint64_t i, uint64_t j)
access a mutable element of this Array2D
const T & operator()(uint64_t i, uint64_t j) const
access an immutable element of this Array2D
a struct of metadata (index, sign, orientation) associated with a degree of freedom
static constexpr uint64_t sign_shift
number of trailing zeros in sign_mask
static constexpr uint64_t orientation_shift
number of trailing zeros in orientation_mask
static constexpr uint64_t sign_mask
bits for sign field
int sign() const
get the sign field of this DoF
static constexpr uint64_t index_shift
number of trailing zeros in index_mask
static constexpr uint64_t orientation_mask
bits for orientation field
static constexpr uint64_t index_mask
bits for the index field
DoF()
default ctor
DoF(uint64_t index, uint64_t sign=0, uint64_t orientation=0)
create a DoF from the given index, sign and orientation values
uint64_t index() const
get the index field of this DoF
void operator=(const DoF &other)
copy assignment operator
uint64_t bits
a 64-bit word encoding the following metadata (laid out from MSB to LSB);
DoF(const DoF &other)
copy ctor
uint64_t orientation() const
get the orientation field of this DoF
a small struct used to enable range-based for loops in Array2D
T * end()
the end of the range
T * begin()
the beginning of the range
T * ptr[2]
the beginning and end of the range
a generalization of mfem::ElementRestriction that works with multiple kinds of element geometries....
BlockElementRestriction()
default ctor leaves this object uninitialized
mfem::Array< int > bOffsets() const
block offsets used when constructing mfem::HypreParVectors
void ScatterAdd(const mfem::BlockVector &E_block_vector, mfem::Vector &L_vector) const
"E->L" in mfem parlance, each element scatter-adds its local vector into the appropriate place in the...
uint64_t ESize() const
the size of the "E-vector" associated with this restriction operator
std::map< mfem::Geometry::Type, ElementRestriction > restrictions
the individual ElementRestriction operators for each element geometry
void Gather(const mfem::Vector &L_vector, mfem::BlockVector &E_block_vector) const
"L->E" in mfem parlance, each element gathers the values that belong to it, and stores them in the "E...
uint64_t LSize() const
the size of the "L-vector" associated with this restriction operator
mfem::Ordering::Type ordering
whether the underlying dofs are arranged "byNodes" or "byVDim"
uint64_t num_nodes
the total number of nodes in the mesh
ElementRestriction()
default ctor leaves this object uninitialized
uint64_t nodes_per_elem
the number of nodes in each element
uint64_t lsize
the size of the "L-vector"
void GetElementVDofs(int i, std::vector< DoF > &dofs) const
Get a list of DoFs for element i
axom::Array< DoF, 2, axom::MemorySpace::Host > dof_info
a 2D array (num_elements-by-nodes_per_elem) holding the dof info extracted from the finite element sp...
void ScatterAdd(const mfem::Vector &E_vector, mfem::Vector &L_vector) const
"E->L" in mfem parlance, each element scatter-adds its local vector into the appropriate place in the...
uint64_t esize
the size of the "E-vector"
uint64_t num_elements
the number of elements of the given geometry
uint64_t components
the number of components at each node
void Gather(const mfem::Vector &L_vector, mfem::Vector &E_vector) const
"L->E" in mfem parlance, each element gathers the values that belong to it, and stores them in the "E...
uint64_t LSize() const
the size of the "L-vector" associated with this restriction operator
uint64_t ESize() const
the size of the "E-vector" associated with this restriction operator
DoF GetVDof(DoF node, uint64_t component) const
get the dof information for a given node / component