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>
11#include <dune/geometry/utility/typefromvertexcount.hh>
12#include <dune/geometry/multilineargeometry.hh>
15
16#include <dune/vtk/types.hh>
17#include <dune/vtk/gridcreatorinterface.hh>
18#include <dune/vtk/gridfunctions/lagrangegridfunction.hh>
19#include <dune/vtk/utility/lagrangepoints.hh>
20
21namespace Dune::Vtk
22{
23 // \brief Create a grid from data that represents higher (Lagrange) cells.
35 template <class GridType>
37 : public GridCreatorInterface<GridType, LagrangeGridCreator<GridType>>
38 {
41
42 public:
43 using Grid = GridType;
44 using Element = typename Grid::template Codim<0>::Entity;
45 using GlobalCoordinate = typename Super::GlobalCoordinate;
46 using LocalCoordinate = typename Element::Geometry::LocalCoordinate;
47
48 private:
49 struct ElementParametrization
50 {
51 GeometryType type = GeometryTypes::none(Grid::dimension); //< Geometry type of the element
52 std::vector<std::int64_t> nodes = {}; //< Indices of the w.r.t. `nodes_` vector
53 std::vector<unsigned int> corners = {}; //< Insertion-indices of the element corner nodes
54 };
55
56 using Parametrization = std::vector<ElementParametrization>;
57 using Nodes = std::vector<GlobalCoordinate>;
58
59 class LocalParametrization;
60 class LocalFunction;
61
62 public:
64
65 public:
66 using Super::Super;
67 using Super::factory;
68
70 void insertVerticesImpl (std::vector<GlobalCoordinate> const& points,
71 std::vector<std::uint64_t> const& /*point_ids*/)
72 {
73 // store point coordinates in member variable
74 nodes_ = points;
75 }
76
77 template <class F>
78 using HasParametrizedElements = decltype(std::declval<F>().insertElement(std::declval<GeometryType>(),
79 std::declval<std::vector<unsigned int> const&>(), std::declval<std::function<GlobalCoordinate(LocalCoordinate)>>()));
80
82 void insertElementsImpl (std::vector<std::uint8_t> const& types,
83 std::vector<std::int64_t> const& offsets,
84 std::vector<std::int64_t> const& connectivity)
85 {
86 assert(nodes_.size() > 0);
87
88 // mapping of node index to element-vertex index
89 std::vector<std::int64_t> elementVertices(nodes_.size(), -1);
90 parametrization_.reserve(types.size());
91
92 std::int64_t vertexIndex = 0;
93 for (std::size_t i = 0; i < types.size(); ++i) {
94 auto type = Vtk::to_geometry(types[i]);
95 if (type.dim() != Grid::dimension)
96 continue;
97
98 Vtk::CellType cellType{type};
99 auto refElem = referenceElement<double,Grid::dimension>(type);
100
101 std::int64_t shift = (i == 0 ? 0 : offsets[i-1]);
102 std::int64_t nNodes = offsets[i] - shift;
103 int nVertices = refElem.size(Grid::dimension);
104
105 // insert vertices into grid and construct element vertices
106 std::vector<unsigned int> element(nVertices);
107 for (int j = 0; j < nVertices; ++j) {
108 auto index = connectivity.at(shift + j);
109 auto& vertex = elementVertices.at(index);
110 if (vertex < 0) {
111 factory().insertVertex(nodes_.at(index));
112 vertex = vertexIndex++;
113 }
114 element[j] = vertex;
115 }
116
117 // permute element indices
118 if (!cellType.noPermutation()) {
119 // apply index permutation
120 std::vector<unsigned int> cell(element.size());
121 for (int j = 0; j < int(element.size()); ++j)
122 cell[j] = element[cellType.permutation(j)];
123 std::swap(element, cell);
124 }
125
126 // fill vector of element parametrizations
127 parametrization_.push_back(ElementParametrization{type});
128 auto& param = parametrization_.back();
129
130 param.nodes.resize(nNodes);
131 for (std::int64_t j = 0; j < nNodes; ++j)
132 param.nodes[j] = connectivity.at(shift + j);
133 param.corners = element;
134
135 // try to create element with parametrization
136 if constexpr (Std::is_detected_v<HasParametrizedElements, GridFactory<Grid>>) {
137 try {
138 factory().insertElement(type, element,
139 localParametrization(parametrization_.size()-1));
140 } catch (Dune::GridError const& /* notImplemented */) {
141 factory().insertElement(type, element);
142 }
143 } else {
144 factory().insertElement(type, element);
145 }
146 }
147 }
148
150
156 LocalParametrization localParametrization (unsigned int insertionIndex) const
157 {
158 VTK_ASSERT(!nodes_.empty() && !parametrization_.empty());
159 auto const& localParam = parametrization_.at(insertionIndex);
160 return LocalParametrization{nodes_, localParam, order(localParam)};
161 }
162
164
169 LocalParametrization localParametrization (Element const& element) const
170 {
171 VTK_ASSERT(!nodes_.empty() && !parametrization_.empty());
172
173 unsigned int insertionIndex = factory().insertionIndex(element);
174 auto const& localParam = parametrization_.at(insertionIndex);
175 VTK_ASSERT(element.type() == localParam.type);
176
177 return {nodes_, localParam, order(localParam), localGeometry(element, localParam)};
178 }
179
181
188 LocalGeometry localGeometry (Element const& element) const
189 {
190 VTK_ASSERT(!nodes_.empty() && !parametrization_.empty());
191
192 unsigned int insertionIndex = factory().insertionIndex(element);
193 auto const& localParam = parametrization_.at(insertionIndex);
194 VTK_ASSERT(element.type() == localParam.type);
195
196 return localGeometry(element, localParam);
197 }
198
199 private:
200 // implementation details of localGeometry()
201 LocalGeometry localGeometry (Element const& element, ElementParametrization const& localParam) const
202 {
203 auto refElem = referenceElement<typename Element::Geometry::ctype,Element::dimension>(localParam.type);
204
205 // collect indices of vertices
206 std::vector<unsigned int> indices(refElem.size(Grid::dimension));
207 for (int i = 0; i < refElem.size(Grid::dimension); ++i)
208 indices[i] = factory().insertionIndex(element.template subEntity<Grid::dimension>(i));
209
210 // calculate permutation vector
211 std::vector<unsigned int> permutation(indices.size());
212 for (std::size_t i = 0; i < indices.size(); ++i) {
213 auto it = std::find(localParam.corners.begin(), localParam.corners.end(), indices[i]);
214 VTK_ASSERT(it != localParam.corners.end());
215 permutation[i] = std::distance(localParam.corners.begin(), it);
216 }
217
218 std::vector<LocalCoordinate> corners(permutation.size());
219 for (std::size_t i = 0; i < permutation.size(); ++i)
220 corners[i] = refElem.position(permutation[i], Element::dimension);
221
222 return {localParam.type, corners};
223 }
224
225 public:
226
228 int order (GeometryType type, std::size_t nNodes) const
229 {
230 for (int o = 1; o <= int(nNodes); ++o)
231 if (numLagrangePoints(type, o) == std::size_t(nNodes))
232 return o;
233
234 return 1;
235 }
236
237 int order (ElementParametrization const& localParam) const
238 {
239 return order(localParam.type, localParam.nodes.size());
240 }
241
243 int order () const
244 {
245 VTK_ASSERT(!parametrization_.empty());
246 auto const& localParam = parametrization_.front();
247 return order(localParam);
248 }
249
250 public:
252
265 friend LocalFunction localFunction (LagrangeGridCreator& gridCreator)
266 {
267 return LocalFunction{gridCreator};
268 }
269
270 friend LocalFunction localFunction (LagrangeGridCreator const& gridCreator)
271 {
272 return LocalFunction{gridCreator};
273 }
274
275 friend LocalFunction localFunction (LagrangeGridCreator&& gridCreator)
276 {
277 DUNE_THROW(Dune::Exception, "Cannot pass temporary LagrangeGridCreator to localFunction(). Pass an lvalue-reference instead.");
278 return LocalFunction{gridCreator};
279 }
280
281 std::string name () const
282 {
283 return "LagrangeParametrization";
284 }
285
286 int numComponents () const
287 {
288 return GlobalCoordinate::size();
289 }
290
291 Vtk::DataTypes dataType () const
292 {
293 return dataTypeOf<typename Element::Geometry::ctype>();
294 }
295
296 struct EntitySet
297 {
298 using Grid = GridType;
299 using GlobalCoordinate = typename Self::GlobalCoordinate;
300 };
301
303 EntitySet entitySet () const
304 {
305 assert(false && "Should not be used!");
306 return EntitySet{};
307 }
308
310 GlobalCoordinate operator() (GlobalCoordinate const&) const
311 {
312 assert(false && "Should not be used!");
313 return GlobalCoordinate{};
314 }
315
316 private:
318 Nodes nodes_;
319
321 Parametrization parametrization_;
322 };
323
324 // deduction guides
325 template <class Grid>
326 LagrangeGridCreator(GridFactory<Grid>&)
327 -> LagrangeGridCreator<Grid>;
328
329 template <class GridType, class Range, class Context>
330 struct AssociatedGridFunction<LagrangeGridCreator<GridType>, Range, Context>
331 {
332 using type = LagrangeGridFunction<GridType, Range, Context>;
333 };
334
335 template <class Grid>
336 class LagrangeGridCreator<Grid>::LocalParametrization
337 {
338 using ctype = typename Grid::ctype;
339
340 using GlobalCoordinate = typename Grid::template Codim<0>::Entity::Geometry::GlobalCoordinate;
341 using LocalCoordinate = typename Grid::template Codim<0>::Entity::Geometry::LocalCoordinate;
342 using LocalGeometry = MultiLinearGeometry<ctype,Grid::dimension,Grid::dimension>;
343
344 using LocalFE = LagrangeLocalFiniteElement<Vtk::LagrangePointSet, Grid::dimension, ctype, ctype>;
345 using LocalBasis = typename LocalFE::Traits::LocalBasisType;
346 using LocalBasisTraits = typename LocalBasis::Traits;
347
348 public:
350 template <class Nodes, class LocalParam>
351 LocalParametrization (Nodes const& nodes, LocalParam const& param, int order)
352 : localFE_(param.type, order)
353 , localNodes_(param.nodes.size())
354 {
355 for (std::size_t i = 0; i < localNodes_.size(); ++i)
356 localNodes_[i] = nodes[param.nodes[i]];
357 }
358
360 template <class Nodes, class LocalParam, class LG>
361 LocalParametrization (Nodes const& nodes, LocalParam const& param, int order, LG&& localGeometry)
362 : LocalParametrization(nodes, param, order)
363 {
364 localGeometry_.emplace(std::forward<LG>(localGeometry));
365 }
366
368 template <class LocalCoordinate>
369 GlobalCoordinate operator() (LocalCoordinate const& local) const
370 {
371 // map coordinates if element corners are permuted
372 LocalCoordinate x = localGeometry_ ? localGeometry_->global(local) : local;
373
374 LocalBasis const& localBasis = localFE_.localBasis();
375 localBasis.evaluateFunction(x, shapeValues_);
376 assert(shapeValues_.size() == localNodes_.size());
377
378 using field_type = typename LocalBasisTraits::RangeType::field_type;
379
380 GlobalCoordinate out(0);
381 for (std::size_t i = 0; i < shapeValues_.size(); ++i)
382 out.axpy(field_type(shapeValues_[i]), localNodes_[i]);
383
384 return out;
385 }
386
387 private:
388 LocalFE localFE_;
389 std::vector<GlobalCoordinate> localNodes_;
390 std::optional<LocalGeometry> localGeometry_;
391
392 mutable std::vector<typename LocalBasisTraits::RangeType> shapeValues_;
393 };
394
395
396 template <class Grid>
397 class LagrangeGridCreator<Grid>::LocalFunction
398 {
399 using ctype = typename Grid::ctype;
400 using LocalContext = typename Grid::template Codim<0>::Entity;
401 using GlobalCoordinate = typename LocalContext::Geometry::GlobalCoordinate;
402 using LocalCoordinate = typename LocalContext::Geometry::LocalCoordinate;
403 using LocalParametrization = typename LagrangeGridCreator::LocalParametrization;
404
405 public:
406 explicit LocalFunction (LagrangeGridCreator const& gridCreator)
407 : gridCreator_(&gridCreator)
408 {}
409
410 explicit LocalFunction (LagrangeGridCreator&& gridCreator) = delete;
411
413 void bind (LocalContext const& element)
414 {
415 localContext_ = element;
416 localParametrization_.emplace(gridCreator_->localParametrization(element));
417 }
418
419 void unbind () { /* do nothing */ }
420
422 GlobalCoordinate operator() (LocalCoordinate const& local) const
423 {
424 assert(!!localParametrization_);
425 return (*localParametrization_)(local);
426 }
427
429 LocalContext const& localContext () const
430 {
431 return localContext_;
432 }
433
434 private:
435 LagrangeGridCreator const* gridCreator_;
436
437 LocalContext localContext_;
438 std::optional<LocalParametrization> localParametrization_;
439 };
440
441} // end namespace Dune::Vtk
Base class for Dune-Exceptions.
Definition: exceptions.hh:98
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:114
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
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
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
Base class for grid creators in a CRTP style.
Definition: gridcreatorinterface.hh:23
GridFactory< Grid > & factory()
Return the associated GridFactory.
Definition: gridcreatorinterface.hh:75
Definition: lagrangegridcreator.hh:38
GridFactory< Grid > & factory()
Return the associated GridFactory.
Definition: gridcreatorinterface.hh:75
void insertElementsImpl(std::vector< std::uint8_t > const &types, std::vector< std::int64_t > const &offsets, std::vector< std::int64_t > const &connectivity)
Implementation of the interface function insertElements()
Definition: lagrangegridcreator.hh:82
EntitySet entitySet() const
Dummy function returning a placeholder entityset.
Definition: lagrangegridcreator.hh:303
void insertVerticesImpl(std::vector< GlobalCoordinate > const &points, std::vector< std::uint64_t > const &)
Implementation of the interface function insertVertices()
Definition: lagrangegridcreator.hh:70
int order(GeometryType type, std::size_t nNodes) const
Determine lagrange order from number of points.
Definition: lagrangegridcreator.hh:228
int order() const
Determine lagrange order from number of points from the first element parametrization.
Definition: lagrangegridcreator.hh:243
LocalGeometry localGeometry(Element const &element) const
Construct a transformation of local element coordinates.
Definition: lagrangegridcreator.hh:188
GlobalCoordinate operator()(GlobalCoordinate const &) const
Dummy function returning a placeholder entityset.
Definition: lagrangegridcreator.hh:310
LocalParametrization localParametrization(Element const &element) const
Construct an element parametrization.
Definition: lagrangegridcreator.hh:169
LocalParametrization localParametrization(unsigned int insertionIndex) const
Construct an element parametrization.
Definition: lagrangegridcreator.hh:156
friend LocalFunction localFunction(LagrangeGridCreator &gridCreator)
Local function representing the parametrization of the grid.
Definition: lagrangegridcreator.hh:265
A Vtk::LocalFunction is a function-like object that can be bound to a grid element an that provides a...
Definition: localfunction.hh:74
Provide a generic factory class for unstructured grids.
A few common exception classes.
#define VTK_ASSERT(cond)
check if condition cond holds; otherwise, throw a VtkError.
Definition: errors.hh:29
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
constexpr GeometryType none(unsigned int dim)
Returns a GeometryType representing a singular of dimension dim.
Definition: type.hh:471
constexpr GeometryType vertex
GeometryType representing a vertex.
Definition: type.hh:492
Convenience header that includes all implementations of Lagrange finite elements.
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
Mapping of Dune geometry types to VTK cell types.
Definition: types.hh:159
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Feb 14, 23:39, 2026)