Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
element_restriction.hpp
1 // Copyright (c) Lawrence Livermore National Security, LLC and
2 // other Smith Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
7 #pragma once
8 
9 #include <cstdint>
10 #include <vector>
11 #include <map>
12 
13 #include "mfem.hpp"
14 #include "axom/core.hpp"
15 #include "geometry.hpp"
16 #include "domain.hpp"
17 
19 #include "smith/numerics/functional/typedefs.hpp"
20 
21 inline bool isH1(const mfem::FiniteElementSpace& fes)
22 {
23  return (fes.FEColl()->GetContType() == mfem::FiniteElementCollection::CONTINUOUS);
24 }
25 
26 inline bool isHcurl(const mfem::FiniteElementSpace& fes)
27 {
28  return (fes.FEColl()->GetContType() == mfem::FiniteElementCollection::TANGENTIAL);
29 }
30 
31 inline bool isDG(const mfem::FiniteElementSpace& fes)
32 {
33  return (fes.FEColl()->GetContType() == mfem::FiniteElementCollection::DISCONTINUOUS);
34 }
35 
36 enum class FaceType
37 {
38  BOUNDARY,
39  INTERIOR
40 };
41 
43 struct DoF {
44  // sam: I wanted to use a bitfield for this type, but a 10+ year-old GCC bug
45  // makes it practically impossible to assign to bitfields without warnings/errors
46  // with -Wconversion enabled, see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39170
47  // So, we resort to masks and bitshifting instead.
48 
49  static constexpr uint64_t sign_mask = 0x8000'0000'0000'0000;
50  static constexpr uint64_t orientation_mask = 0x7000'0000'0000'0000;
51  static constexpr uint64_t index_mask = 0x0000'FFFF'FFFF'FFFF'FFFF;
52 
53  static constexpr uint64_t sign_shift = 63;
54  static constexpr uint64_t orientation_shift = 60;
55  static constexpr uint64_t index_shift = 0;
56 
67  uint64_t bits;
68 
70  DoF() : bits{} {}
71 
73  DoF(const DoF& other) : bits{other.bits} {}
74 
76  DoF(uint64_t index, uint64_t sign = 0, uint64_t orientation = 0)
77  : bits((sign & 0x1ULL << sign_shift) + ((orientation & 0x7ULL) << orientation_shift) + index)
78  {
79  }
80 
82  void operator=(const DoF& other) { bits = other.bits; }
83 
85  int sign() const { return (bits & sign_mask) ? -1 : 1; }
86 
88  uint64_t orientation() const { return ((bits & orientation_mask) >> orientation_shift); }
89 
91  uint64_t index() const { return (bits & index_mask); }
92 };
93 
95 template <typename T>
96 struct Range {
97  T* begin() { return ptr[0]; }
98  T* end() { return ptr[1]; }
99  T* ptr[2];
100 };
101 
107 template <typename T>
108 struct Array2D {
109  Array2D() : values{}, dim{} {};
110 
112  Array2D(uint64_t m, uint64_t n) : values(m * n, 0), dim{m, n} {};
113 
115  Array2D(std::vector<T>&& data, uint64_t m, uint64_t n) : values(data), dim{m, n} {};
116 
118  Range<T> operator()(uint64_t i) { return Range<T>{&values[i * dim[1]], &values[(i + 1) * dim[1]]}; }
119 
121  Range<const T> operator()(uint64_t i) const { return Range<const T>{&values[i * dim[1]], &values[(i + 1) * dim[1]]}; }
122 
124  T& operator()(uint64_t i, uint64_t j) { return values[i * dim[1] + j]; }
125 
127  const T& operator()(uint64_t i, uint64_t j) const { return values[i * dim[1] + j]; }
128 
130  Array2D(int m, int n) : values(uint64_t(m) * uint64_t(n), 0), dim{uint64_t(m), uint64_t(n)} {}
131 
133  Array2D(std::vector<T>&& data, int m, int n) : values(data), dim{uint64_t(m), uint64_t(n)} {}
134 
136  Range<T> operator()(int i) { return Range<T>{&values[uint64_t(i) * dim[1]], &values[uint64_t(i + 1) * dim[1]]}; }
137 
140  {
141  return Range<const T>{&values[uint64_t(i) * dim[1]], &values[uint64_t(i + 1) * dim[1]]};
142  }
143 
145  T& operator()(int i, int j) { return values[uint64_t(i) * dim[1] + uint64_t(j)]; }
146 
148  const T& operator()(int i, int j) const { return values[uint64_t(i) * dim[1] + uint64_t(j)]; }
149 
150  std::vector<T> values;
151  uint64_t dim[2];
152 };
153 
154 namespace smith {
155 
156 struct Domain;
157 
163 
165  ElementRestriction(const fes_t* fes, mfem::Geometry::Type elem_geom, const std::vector<int>& domain_elements);
166 
168  uint64_t ESize() const;
169 
171  uint64_t LSize() const;
172 
179  void GetElementVDofs(int i, std::vector<DoF>& dofs) const;
180 
182  DoF GetVDof(DoF node, uint64_t component) const;
183 
185  void Gather(const mfem::Vector& L_vector, mfem::Vector& E_vector) const;
186 
188  void ScatterAdd(const mfem::Vector& E_vector, mfem::Vector& L_vector) const;
189 
191  uint64_t esize;
192 
194  uint64_t lsize;
195 
197  uint64_t components;
198 
200  uint64_t num_nodes;
201 
203  uint64_t num_elements;
204 
206  uint64_t nodes_per_elem;
207 
209  axom::Array<DoF, 2, smith::detail::host_memory_space> dof_info;
210 
212  mfem::Ordering::Type ordering;
213 };
214 
223 
225  BlockElementRestriction(const fes_t* fes, const Domain& domain);
226 
228  uint64_t ESize() const;
229 
231  uint64_t LSize() const;
232 
234  mfem::Array<int> bOffsets() const;
235 
237  void Gather(const mfem::Vector& L_vector, mfem::BlockVector& E_block_vector) const;
238 
240  void ScatterAdd(const mfem::BlockVector& E_block_vector, mfem::Vector& L_vector) const;
241 
243  std::map<mfem::Geometry::Type, ElementRestriction> restrictions;
244 };
245 
246 } // namespace smith
247 
254 axom::Array<DoF, 2, smith::detail::host_memory_space> GetElementDofs(const smith::fes_t* fes,
255  mfem::Geometry::Type geom);
256 
264 axom::Array<DoF, 2, smith::detail::host_memory_space> GetFaceDofs(const smith::fes_t* fes,
265  mfem::Geometry::Type face_geom, FaceType type);
266 
268 axom::Array<DoF, 2, smith::detail::host_memory_space> GetFaceDofs(const smith::fes_t* fes,
269  mfem::Geometry::Type face_geom,
270  const std::vector<int>& mfem_face_ids);
many of the functions in this file amount to extracting element indices from an mesh_t like
This file defines the host memory space.
Accelerator functionality.
Definition: smith.cpp:36
constexpr SMITH_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:376
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....
uint64_t ESize() const
the size of the "E-vector" associated with this restriction operator
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...
BlockElementRestriction()
default ctor leaves this object uninitialized
uint64_t LSize() const
the size of the "L-vector" associated with this restriction operator
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...
std::map< mfem::Geometry::Type, ElementRestriction > restrictions
the individual ElementRestriction operators for each element geometry
mfem::Array< int > bOffsets() const
block offsets used when constructing mfem::HypreParVectors
a class for representing a geometric region that can be used for integration
Definition: domain.hpp:33
void GetElementVDofs(int i, std::vector< DoF > &dofs) const
Get a list of DoFs for element i
uint64_t esize
the size of the "E-vector"
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"
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 lsize
the size of the "L-vector"
ElementRestriction()
default ctor leaves this object uninitialized
uint64_t num_nodes
the total number of nodes in the mesh
axom::Array< DoF, 2, smith::detail::host_memory_space > dof_info
a 2D array (num_elements-by-nodes_per_elem) holding the dof info extracted from the finite element sp...
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 components
the number of components at each node
uint64_t num_elements
the number of elements of the given geometry
DoF GetVDof(DoF node, uint64_t component) const
get the dof information for a given node / component
uint64_t nodes_per_elem
the number of nodes in each element
uint64_t ESize() const
the size of the "E-vector" associated with this restriction operator