Dune Core Modules (2.11.0)

lagrangegridcreator.hh
1#pragma once
2
3#include <cassert>
4#include <cstdint>
5#include <limits>
6#include <optional>
7#include <vector>
8
10#include <dune/common/hybridutilities.hh>
12#include <dune/geometry/utility/typefromvertexcount.hh>
13#include <dune/geometry/multilineargeometry.hh>
16
17#include <dune/gmsh4/types.hh>
18#include <dune/gmsh4/gridcreatorinterface.hh>
20#include <dune/gmsh4/utility/lagrangepoints.hh>
21
22namespace Dune
23{
24 namespace Gmsh4
25 {
26 // \brief Create a grid from data that represents higher (Lagrange) cells.
38 template <class GridType>
40 : public GridCreatorInterface<GridType, LagrangeGridCreator<GridType>>
41 {
44 using GlobalCoordinate = typename Super::GlobalCoordinate;
45
46 using Nodes = std::vector<GlobalCoordinate>;
47
48 struct ElementParametrization
49 {
50 GeometryType type; //< Geometry type of the element
51 std::vector<std::int64_t> nodes; //< Indices of the w.r.t. `nodes_` vector
52 std::vector<unsigned int> corners; //< Insertion-indices of the element corner nodes
53 };
54
55 using Parametrization = std::vector<ElementParametrization>;
56 using Element = typename GridType::template Codim<0>::Entity;
57 using LocalCoordinate = typename Element::Geometry::LocalCoordinate;
58
59 class LocalParametrization;
60 class LocalFunction;
61
62 public:
63 using Super::Super;
64 using Super::factory;
65
67 template <class NodeAttributes>
68 void insertVerticesImpl (std::size_t numNodes,
69 std::pair<std::size_t,std::size_t> nodeTagRange,
70 std::vector<NodeAttributes> const& entityBlocks)
71 {
72 vertexMap_.resize(nodeTagRange.second - nodeTagRange.first + 1);
73 vertexShift_ = nodeTagRange.first;
74 nodes_.resize(numNodes);
75 GlobalCoordinate p;
76 size_t vertexIndex = 0;
77
78 for (auto const& entityBlock : entityBlocks) {
79 for (auto const& node : entityBlock.nodes) {
80 for (std::size_t j = 0; j < p.size(); ++j)
81 p[j] = node.xyz[j];
82 nodes_[vertexIndex] = p;
83 vertexMap_[node.tag - vertexShift_] = vertexIndex++;
84 }
85 }
86 }
87
88 template <class F>
89 using HasParametrizedElements = decltype(std::declval<F>().insertElement(std::declval<GeometryType>(),
90 std::declval<std::vector<unsigned int> const&>(), std::declval<std::function<GlobalCoordinate(LocalCoordinate)>>()));
91
93 template <class ElementAttributes, class BoundaryEntities>
94 void insertElementsImpl (std::size_t numElements,
95 std::pair<std::size_t,std::size_t> elementTagRange,
96 std::vector<ElementAttributes> const& entityBlocks,
97 BoundaryEntities const& boundaryEntities)
98 {
99 const int dim = GridType::dimension;
100 std::vector<unsigned int> connectivity;
101 std::size_t cornerIndex = 0;
102 std::vector<std::int64_t> cornerVertices(nodes_.size(), -1);
103
104 for (auto const& entityBlock : entityBlocks) {
105 if (entityBlock.entityDim < dim - 1)
106 continue;
107
108 auto type = Gmsh4::gmshNumberToGeometryType(entityBlock.elementType);
109 Gmsh4::CellType cell{type};
110
111 if (entityBlock.entityDim == dim) { //element
112 auto refElem = referenceElement<double, dim>(type);
113 connectivity.resize(refElem.size(dim));
114
115 for (auto const& element : entityBlock.elements) {
116 GMSH4_ASSERT(element.nodes.size() >= connectivity.size());
117 for (std::size_t j = 0; j < connectivity.size(); ++j) {
118 auto index = vertexMap_[element.nodes[j] - vertexShift_];
119 auto& vertex = cornerVertices.at(index);
120 if (vertex < 0) {
121 factory().insertVertex(nodes_.at(index));
122 vertex = cornerIndex++;
123 }
124 connectivity[cell.gmshVertexToDuneVertex(j)] = vertex;
125 }
126
127 // fill vector of element parametrizations
128 parametrization_.push_back(ElementParametrization{type});
129 auto& param = parametrization_.back();
130 param.nodes.resize(element.nodes.size());
131 for (std::size_t j = 0; j < element.nodes.size(); ++j)
132 param.nodes[j] = vertexMap_[element.nodes[j] - vertexShift_];
133 param.corners = connectivity;
134
135 // try to create element with parametrization
136 if constexpr (Std::is_detected_v<HasParametrizedElements, GridFactory<GridType>>) {
137 try {
138 factory().insertElement(type, connectivity,
139 localParametrization(parametrization_.size()-1));
140 } catch (Dune::GridError const& /* notImplemented */) {
141 factory().insertElement(type, connectivity);
142 }
143 } else {
144 factory().insertElement(type, connectivity);
145 }
146 }
147 }
148 }
149 }
150
152
158 LocalParametrization localParametrization (unsigned int insertionIndex) const
159 {
160 assert(!nodes_.empty() && !parametrization_.empty());
161 auto const& localParam = parametrization_.at(insertionIndex);
162 return LocalParametrization{nodes_, localParam, order(localParam)};
163 }
164
166
178 LocalParametrization localParametrization (Element const& element) const
179 {
180 assert(!nodes_.empty() && !parametrization_.empty());
181
182 unsigned int insertionIndex = factory().insertionIndex(element);
183 auto const& localParam = parametrization_.at(insertionIndex);
184 GMSH4_ASSERT(element.type() == localParam.type);
185
186 // collect indices of vertices
187 std::vector<unsigned int> indices(element.subEntities(GridType::dimension));
188 for (unsigned int i = 0; i < element.subEntities(GridType::dimension); ++i)
189 indices[i] = factory().insertionIndex(element.template subEntity<GridType::dimension>(i));
190
191 // calculate permutation vector
192 std::vector<unsigned int> permutation(indices.size());
193 for (std::size_t i = 0; i < indices.size(); ++i) {
194 auto it = std::find(localParam.corners.begin(), localParam.corners.end(), indices[i]);
195 GMSH4_ASSERT(it != localParam.corners.end());
196 permutation[i] = std::distance(localParam.corners.begin(), it);
197 }
198
199 return LocalParametrization{nodes_, localParam, order(localParam), permutation};
200 }
201
203 template <class LocalParam>
204 int order (LocalParam const& localParam) const
205 {
206 GeometryType type = localParam.type;
207 int nNodes = localParam.nodes.size();
208 for (int o = 1; o <= nNodes; ++o)
209#if DUNE_VERSION_LT(DUNE_LOCALFUNCTIONS,2,8)
210 if (numLagrangePoints(type.id(), type.dim(), o) == std::size_t(nNodes))
211#else
212 if (numLagrangePoints(type, o) == std::size_t(nNodes))
213#endif
214 return o;
215
216 return 1;
217 }
218
220 int order () const
221 {
222 GMSH4_ASSERT(!parametrization_.empty());
223 return order(parametrization_.front());
224 }
225
226 public:
228
241 friend LocalFunction localFunction (LagrangeGridCreator& gridCreator)
242 {
243 return LocalFunction{gridCreator};
244 }
245
246 friend LocalFunction localFunction (LagrangeGridCreator const& gridCreator)
247 {
248 return LocalFunction{gridCreator};
249 }
250
251 friend LocalFunction localFunction (LagrangeGridCreator&& gridCreator)
252 {
253 DUNE_THROW(Dune::Gmsh4Error, "Cannot pass temporary LagrangeGridCreator to localFunction(). Pass an lvalue-reference instead.");
254 return LocalFunction{gridCreator};
255 }
256
257 struct EntitySet
258 {
259 using Grid = GridType;
260 using GlobalCoordinate = typename Self::GlobalCoordinate;
261 };
262
264 EntitySet entitySet () const
265 {
266 assert(false && "Should not be used!");
267 return EntitySet{};
268 }
269
271 GlobalCoordinate operator() (GlobalCoordinate const&) const
272 {
273 assert(false && "Should not be used!");
274 return GlobalCoordinate{};
275 }
276
277 private:
279 Nodes nodes_;
280
282 Parametrization parametrization_;
283
284 std::vector<std::size_t> vertexMap_;
285 std::size_t vertexShift_ = 0;
286 };
287
288 // deduction guides
289 template <class Grid>
290 LagrangeGridCreator(GridFactory<Grid>&)
291 -> LagrangeGridCreator<Grid>;
292
293
294 template <class Grid>
295 class LagrangeGridCreator<Grid>::LocalParametrization
296 {
297 using ctype = typename Grid::ctype;
298
299 using GlobalCoordinate = typename Grid::template Codim<0>::Entity::Geometry::GlobalCoordinate;
300 using LocalCoordinate = typename Grid::template Codim<0>::Entity::Geometry::LocalCoordinate;
302
304 using LocalBasis = typename LocalFE::Traits::LocalBasisType;
305 using LocalBasisTraits = typename LocalBasis::Traits;
306
307 public:
309 template <class Nodes, class LocalParam>
310 LocalParametrization (Nodes const& nodes, LocalParam const& param, int order)
311 : localFE_(param.type, order)
312 , localNodes_(param.nodes.size())
313 {
314 for (std::size_t i = 0; i < localNodes_.size(); ++i)
315 localNodes_[i] = nodes[param.nodes[i]];
316 }
317
319 template <class Nodes, class LocalParam, class Permutation>
320 LocalParametrization (Nodes const& nodes, LocalParam const& param, int order, Permutation const& permutation)
321 : LocalParametrization(nodes, param, order)
322 {
323 auto refElem = referenceElement<ctype,Grid::dimension>(param.type);
324 std::vector<LocalCoordinate> corners(permutation.size());
325 for (std::size_t i = 0; i < permutation.size(); ++i)
326 corners[i] = refElem.position(permutation[i], Grid::dimension);
327
328 localGeometry_.emplace(param.type, corners);
329 }
330
332 template <class LocalCoordinate>
333 GlobalCoordinate operator() (LocalCoordinate const& local) const
334 {
335 // map coordinates if element corners are permuted
336 LocalCoordinate x = localGeometry_ ? localGeometry_->global(local) : local;
337
338 LocalBasis const& localBasis = localFE_.localBasis();
339 localBasis.evaluateFunction(x, shapeValues_);
340 GMSH4_ASSERT(shapeValues_.size() == localNodes_.size());
341
342 GlobalCoordinate out(0);
343 for (std::size_t i = 0; i < shapeValues_.size(); ++i)
344 out.axpy(shapeValues_[i], localNodes_[i]);
345
346 return out;
347 }
348
349 private:
350 LocalFE localFE_;
351 std::vector<GlobalCoordinate> localNodes_;
352 std::optional<LocalGeometry> localGeometry_;
353
354 mutable std::vector<typename LocalBasisTraits::RangeType> shapeValues_;
355 };
356
357
358 template <class Grid>
359 class LagrangeGridCreator<Grid>::LocalFunction
360 {
361 using ctype = typename Grid::ctype;
362 using LocalContext = typename Grid::template Codim<0>::Entity;
363 using GlobalCoordinate = typename LocalContext::Geometry::GlobalCoordinate;
364 using LocalCoordinate = typename LocalContext::Geometry::LocalCoordinate;
365 using LocalParametrization = typename LagrangeGridCreator::LocalParametrization;
366
367 public:
368 explicit LocalFunction (LagrangeGridCreator& gridCreator)
369 : gridCreator_(&gridCreator)
370 {}
371
372 explicit LocalFunction (LagrangeGridCreator const& gridCreator)
373 : gridCreator_(&gridCreator)
374 {}
375
376 explicit LocalFunction (LagrangeGridCreator&& gridCreator) = delete;
377
379 void bind (LocalContext const& element)
380 {
381 localContext_ = element;
382 localParametrization_.emplace(gridCreator_->localParametrization(element));
383 }
384
385 void unbind () { /* do nothing */ }
386
388 GlobalCoordinate operator() (LocalCoordinate const& local) const
389 {
390 assert(!!localParametrization_);
391 return (*localParametrization_)(local);
392 }
393
395 LocalContext const& localContext () const
396 {
397 return localContext_;
398 }
399
400 private:
401 LagrangeGridCreator const* gridCreator_;
402
403 LocalContext localContext_;
404 std::optional<LocalParametrization> localParametrization_;
405 };
406
407 } // end namespace Gmsh4
408} // end namespace Dune
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:114
constexpr unsigned int dim() const
Return dimension of the type.
Definition: type.hh:360
constexpr unsigned int id() const
Return the topology id of the type.
Definition: type.hh:365
Mapping of Dune geometry types to Gmsh cell types.
Definition: types.hh:25
Base class for grid creators in a CRTP style.
Definition: gridcreatorinterface.hh:23
GridFactory< Grid > & factory()
Return the associated GridFactory.
Definition: gridcreatorinterface.hh:60
Base class for exceptions in Dune grid modules.
Definition: exceptions.hh:20
virtual unsigned int insertionIndex(const typename Codim< 0 >::Entity &entity) const
obtain an element's insertion index
Definition: gridfactory.hh:181
Provide a generic factory class for unstructured grids.
Definition: gridfactory.hh:275
virtual void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices)
Insert an element into the coarse grid.
Definition: gridfactory.hh:307
virtual void insertVertex(const FieldVector< ctype, dimworld > &pos)
Insert a vertex into the coarse grid.
Definition: gridfactory.hh:296
Grid abstract base class.
Definition: grid.hh:375
static constexpr int dimension
The dimension of the grid.
Definition: grid.hh:387
ct ctype
Define type used for coordinates in grid module.
Definition: grid.hh:518
generic geometry implementation based on corner coordinates
Definition: multilineargeometry.hh:181
Provide a generic factory class for unstructured grids.
A few common exception classes.
Various macros to work with Dune module version numbers.
#define DUNE_VERSION_LT(module, major, minor)
True if 'module' has a version less than major.minor.
Definition: version.hh:100
Macro for wrapping error checks and throwing exceptions.
#define GMSH4_ASSERT(cond)
check if condition cond holds; otherwise, throw a Gmsh4Error.
Definition: errors.hh:34
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
constexpr GeometryType vertex
GeometryType representing a vertex.
Definition: type.hh:492
Convenience header that includes all implementations of Lagrange finite elements.
Dune namespace
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
Static tag representing a codimension.
Definition: dimension.hh:24
Definition: lagrangegridcreator.hh:41
LocalParametrization localParametrization(Element const &element) const
Construct an element parametrization.
Definition: lagrangegridcreator.hh:178
LocalParametrization localParametrization(unsigned int insertionIndex) const
Construct an element parametrization.
Definition: lagrangegridcreator.hh:158
void insertElementsImpl(std::size_t numElements, std::pair< std::size_t, std::size_t > elementTagRange, std::vector< ElementAttributes > const &entityBlocks, BoundaryEntities const &boundaryEntities)
Implementation of the interface function insertElements()
Definition: lagrangegridcreator.hh:94
int order(LocalParam const &localParam) const
Determine Lagrange order from number of points.
Definition: lagrangegridcreator.hh:204
void insertVerticesImpl(std::size_t numNodes, std::pair< std::size_t, std::size_t > nodeTagRange, std::vector< NodeAttributes > const &entityBlocks)
Implementation of the interface function insertVertices()
Definition: lagrangegridcreator.hh:68
int order() const
Determine Lagrange order from number of points from the first element parametrization.
Definition: lagrangegridcreator.hh:220
friend LocalFunction localFunction(LagrangeGridCreator &gridCreator)
Local function representing the parametrization of the grid.
Definition: lagrangegridcreator.hh:241
GridFactory< Grid > & factory()
Return the associated GridFactory.
Definition: gridcreatorinterface.hh:60
EntitySet entitySet() const
Dummy function returning a placeholder entityset.
Definition: lagrangegridcreator.hh:264
GlobalCoordinate operator()(GlobalCoordinate const &) const
Dummy function returning a placeholder entityset.
Definition: lagrangegridcreator.hh:271
Type traits for LocalBasisVirtualInterface.
Definition: localbasis.hh:35
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Feb 14, 23:39, 2026)