MFEM  v4.6.0
Finite element discretization library
util.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef MFEM_LIBCEED_UTIL
13 #define MFEM_LIBCEED_UTIL
14 
15 #include "../../../config/config.hpp"
16 #include <functional>
17 #include <string>
18 #include <tuple>
19 #include <unordered_map>
20 
21 #include "ceed.hpp"
22 #ifdef MFEM_USE_CEED
23 #include <ceed/backend.h> // for CeedOperatorField
24 #endif
25 
26 namespace mfem
27 {
28 
29 class FiniteElement;
30 class FiniteElementSpace;
31 class ElementTransformation;
32 class IntegrationRule;
33 class Vector;
34 
35 /** @brief Function that determines if a CEED kernel should be used, based on
36  the current mfem::Device configuration. */
37 bool DeviceCanUseCeed();
38 
39 namespace ceed
40 {
41 
42 /** @brief Remove from ceed_basis_map and ceed_restr_map the entries associated
43  with the given @a fes. */
45 
46 #ifdef MFEM_USE_CEED
47 
48 #define PCeedChk(err) do { \
49  if ((err)) \
50  { \
51  const char * errmsg; \
52  CeedGetErrorMessage(internal::ceed, &errmsg); \
53  MFEM_ABORT(errmsg); \
54  } \
55  } while(0);
56 
57 /// Initialize a CeedVector from an mfem::Vector
58 void InitVector(const mfem::Vector &v, CeedVector &cv);
59 
60 /** @brief Initialize a CeedBasis and a CeedElemRestriction based on an
61  mfem::FiniteElementSpace @a fes, and an mfem::IntegrationRule @a ir.
62 
63  @param[in] fes The finite element space.
64  @param[in] ir The integration rule.
65  @param[in] ceed The Ceed object.
66  @param[out] basis The `CeedBasis` to initialize.
67  @param[out] restr The `CeedElemRestriction` to initialize.
68 
69  @warning Only for non-mixed finite element spaces. */
71  const mfem::IntegrationRule &ir,
72  Ceed ceed, CeedBasis *basis,
73  CeedElemRestriction *restr);
74 
75 /** @brief Initialize a CeedBasis and a CeedElemRestriction based on an
76  mfem::FiniteElementSpace @a fes, and an mfem::IntegrationRule @a ir,
77  and a list of @a nelem elements of indices @a indices.
78 
79  @param[in] fes The finite element space.
80  @param[in] ir The integration rule.
81  @param[in] nelem The number of elements.
82  @param[in] indices The indices of the elements of same type in the
83  `FiniteElementSpace`. If `indices == nullptr`, assumes
84  that the `FiniteElementSpace` is not mixed.
85  @param[in] ceed The Ceed object.
86  @param[out] basis The `CeedBasis` to initialize.
87  @param[out] restr The `CeedElemRestriction` to initialize. */
88 void InitBasisAndRestriction(const FiniteElementSpace &fes,
89  const IntegrationRule &ir,
90  int nelem,
91  const int* indices,
92  Ceed ceed, CeedBasis *basis,
93  CeedElemRestriction *restr);
94 
95 int CeedOperatorGetActiveField(CeedOperator oper, CeedOperatorField *field);
96 
97 
98 template <typename Integrator>
99 const IntegrationRule & GetRule(
100  const Integrator &integ,
101  const FiniteElement &trial_fe,
102  const FiniteElement &test_fe,
103  ElementTransformation &Trans);
104 
105 /// Return the path to the libCEED q-function headers.
106 const std::string &GetCeedPath();
107 
108 /// Wrapper for std::hash.
109 template <typename T>
110 inline std::size_t CeedHash(const T key)
111 {
112  return std::hash<T> {}(key);
113 }
114 
115 /// Effective way to combine hashes (from libCEED).
116 inline std::size_t CeedHashCombine(std::size_t seed, std::size_t hash)
117 {
118  // See https://doi.org/10.1002/asi.10170, or
119  // https://dl.acm.org/citation.cfm?id=759509.
120  return seed ^ (hash + (seed << 6) + (seed >> 2));
121 }
122 
123 // Hash table for CeedBasis
124 using BasisKey = std::tuple<const mfem::FiniteElementSpace*,
125  const mfem::IntegrationRule*,
126  int, int, int>;
127 struct BasisHash
128 {
129  std::size_t operator()(const BasisKey& k) const
130  {
131  return CeedHashCombine(
133  CeedHash(std::get<0>(k)),
134  CeedHash(std::get<1>(k))),
136  CeedHashCombine(CeedHash(std::get<2>(k)),
137  CeedHash(std::get<3>(k))),
138  CeedHash(std::get<4>(k))));
139  }
140 };
141 using BasisMap = std::unordered_map<const BasisKey, CeedBasis, BasisHash>;
142 
144 
145 // Hash table for CeedElemRestriction
146 using RestrKey =
147  std::tuple<const mfem::FiniteElementSpace*, int, int, int, int>;
148 struct RestrHash
149 {
150  std::size_t operator()(const RestrKey& k) const
151  {
152  return CeedHashCombine(
155  CeedHash(std::get<0>(k)),
156  CeedHash(std::get<1>(k))),
157  CeedHashCombine(CeedHash(std::get<2>(k)),
158  CeedHash(std::get<3>(k)))),
159  CeedHash(std::get<4>(k)));
160  }
161 };
162 using RestrMap =
163  std::unordered_map<const RestrKey, CeedElemRestriction, RestrHash>;
164 
165 #endif
166 
167 } // namespace ceed
168 
169 namespace internal
170 {
171 
172 #ifdef MFEM_USE_CEED
173 /** @warning These maps have a tendency to create bugs when adding new "types"
174  of CeedBasis and CeedElemRestriction. */
175 extern ceed::BasisMap ceed_basis_map;
176 extern ceed::RestrMap ceed_restr_map;
177 #endif
178 
179 } // namespace internal
180 
181 } // namespace mfem
182 
183 #endif // MFEM_LIBCEED_UTIL
std::unordered_map< const RestrKey, CeedElemRestriction, RestrHash > RestrMap
Definition: util.hpp:163
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:96
void InitVector(const mfem::Vector &v, CeedVector &cv)
Initialize a CeedVector from an mfem::Vector.
Definition: util.cpp:75
std::tuple< const mfem::FiniteElementSpace *, int, int, int, int > RestrKey
Definition: util.hpp:147
int CeedOperatorGetActiveField(CeedOperator oper, CeedOperatorField *field)
Definition: util.cpp:131
std::tuple< const mfem::FiniteElementSpace *, const mfem::IntegrationRule *, int, int, int > BasisKey
Definition: util.hpp:126
std::size_t CeedHashCombine(std::size_t seed, std::size_t hash)
Effective way to combine hashes (from libCEED).
Definition: util.hpp:116
std::unordered_map< const BasisKey, CeedBasis, BasisHash > BasisMap
Definition: util.hpp:141
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:219
const std::string & GetCeedPath()
Return the path to the libCEED q-function headers.
Definition: util.cpp:255
void RemoveBasisAndRestriction(const mfem::FiniteElementSpace *fes)
Remove from ceed_basis_map and ceed_restr_map the entries associated with the given fes...
Definition: util.cpp:41
bool DeviceCanUseCeed()
Function that determines if a CEED kernel should be used, based on the current mfem::Device configura...
Definition: util.cpp:33
std::size_t CeedHash(const T key)
Wrapper for std::hash.
Definition: util.hpp:110
const IntegrationRule & GetRule(const Integrator &integ, const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans)
std::size_t operator()(const RestrKey &k) const
Definition: util.hpp:150
Vector data type.
Definition: vector.hpp:58
std::size_t operator()(const BasisKey &k) const
Definition: util.hpp:129
void InitBasisAndRestriction(const FiniteElementSpace &fes, const IntegrationRule &irm, Ceed ceed, CeedBasis *basis, CeedElemRestriction *restr)
Initialize a CeedBasis and a CeedElemRestriction based on an mfem::FiniteElementSpace fes...
Definition: util.cpp:93