version 3.11-dev
Loading...
Searching...
No Matches
discretization/porenetwork/gridgeometry.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_DISCRETIZATION_PNM_GRID_GEOMETRY_HH
13#define DUMUX_DISCRETIZATION_PNM_GRID_GEOMETRY_HH
14
15#include <ranges>
16#include <span>
17#include <string>
18#include <utility>
19#include <unordered_map>
20#include <functional>
21
22#include <dune/common/exceptions.hh>
23#include <dune/localfunctions/lagrange/lagrangelfecache.hh>
24
29
37
38namespace Dumux::PoreNetwork {
39
44template<class Scalar, class GridView>
46{
47 using GridIndex = typename IndexTraits<GridView>::GridIndex;
48 using SmallLocalIndex = typename IndexTraits<GridView>::SmallLocalIndex;
49 using Label = std::int_least8_t;
50 using Vertex = typename GridView::template Codim<GridView::dimension>::Entity;
51 using Element = typename GridView::template Codim<0>::Entity;
52
53 static const int dim = GridView::dimension;
54
55public:
56
57 template<class GridData>
58 void update(const GridView& gridView, const GridData& gridData)
59 {
60 coordinationNumber_ = gridData.getCoordinationNumbers();
61
62 const auto numThroats = gridView.size(0);
63 throatInscribedRadius_.resize(numThroats);
64 throatLength_.resize(numThroats);
65 throatLabel_.resize(numThroats);
66 throatCrossSectionalArea_.resize(numThroats);
67 throatShapeFactor_.resize(numThroats);
68
69 useSameGeometryForAllPores_ = true;
70 useSameShapeForAllThroats_ = true;
71 overwriteGridDataWithShapeSpecificValues_ = false;
72
73 // first check if the same geometry shall be used for all entities ...
74 if (hasParamInGroup(gridData.paramGroup(), "Grid.ThroatCrossSectionShape"))
75 {
76 const auto throatGeometryInput = getParamFromGroup<std::string>(gridData.paramGroup(), "Grid.ThroatCrossSectionShape");
77 const auto throatGeometry = Throat::shapeFromString(throatGeometryInput);
78 throatGeometry_.resize(1);
79 throatGeometry_[0] = throatGeometry;
80 overwriteGridDataWithShapeSpecificValues_ = getParamFromGroup<bool>(gridData.paramGroup(), "Grid.OverwriteGridDataWithShapeSpecificValues", true);
81
82 std::cout << "Using '" << throatGeometryInput << "' as cross-sectional shape for all throats." << std::endl;
83 }
84 else // .. otherwise, get the corresponding parameter index from the grid data and resize the respective vector
85 {
86 std::cout << "Reading shape factors for throats from grid data." << std::endl;
87 useSameShapeForAllThroats_ = false;
88 throatGeometry_.resize(numThroats);
89 }
90
91 // get the vertex parameters
92 const auto numPores = gridView.size(dim);
93 poreInscribedRadius_.resize(numPores);
94 poreLabel_.resize(numPores);
95 poreVolume_.resize(numPores);
96
97 // first check if the same geometry shall be used for all entities ...
98 if (hasParamInGroup(gridData.paramGroup(), "Grid.PoreGeometry"))
99 {
100 const auto poreGeometryInput = getParamFromGroup<std::string>(gridData.paramGroup(), "Grid.PoreGeometry");
101 poreGeometry_.resize(1);
102 poreGeometry_[0] = Pore::shapeFromString(poreGeometryInput);;
103
104 std::cout << "Using '" << poreGeometryInput << "' as geometry for all pores." << std::endl;
105 }
106 else // .. otherwise, get the corresponding parameter index from the grid data and resize the respective vector
107 {
108 std::cout << "Reading pore shapes from grid data." << std::endl;
109 useSameGeometryForAllPores_ = false;
110 poreGeometry_.resize(numPores);
111 }
112
113
114 for (const auto& vertex : vertices(gridView))
115 {
116 static const auto poreInscribedRadiusIdx = gridData.parameterIndex("PoreInscribedRadius");
117 static const auto poreLabelIdx = gridData.parameterIndex("PoreLabel");
118 const auto vIdx = gridView.indexSet().index(vertex);
119 const auto& params = gridData.parameters(vertex);
120 poreInscribedRadius_[vIdx] = params[poreInscribedRadiusIdx];
121 assert(poreInscribedRadius_[vIdx] > 0.0);
122 poreLabel_[vIdx] = params[poreLabelIdx];
123
125 poreGeometry_[vIdx] = getPoreGeometry_(gridData, vertex);
126
127 poreVolume_[vIdx] = getPoreVolume_(gridData, vertex, vIdx);
128 }
129
130 for (const auto& element : elements(gridView))
131 {
132 const int eIdx = gridView.indexSet().index(element);
133 const auto& params = gridData.parameters(element);
134 static const auto throatInscribedRadiusIdx = gridData.parameterIndex("ThroatInscribedRadius");
135 static const auto throatLengthIdx = gridData.parameterIndex("ThroatLength");
136 throatInscribedRadius_[eIdx] = params[throatInscribedRadiusIdx];
137 throatLength_[eIdx] = params[throatLengthIdx];
138
139 // use a default value if no throat label is given by the grid
140 static const bool gridHasThroatLabel = gridData.gridHasElementParameter("ThroatLabel");
141 if (gridHasThroatLabel)
142 {
143 static const auto throatLabelIdx = gridData.parameterIndex("ThroatLabel");
144 throatLabel_[eIdx] = params[throatLabelIdx];
145 }
146 else
147 {
148 const auto vIdx0 = gridView.indexSet().subIndex(element, 0, dim);
149 const auto vIdx1 = gridView.indexSet().subIndex(element, 1, dim);
150
151 const auto poreLabel0 = poreLabel(vIdx0);
152 const auto poreLabel1 = poreLabel(vIdx1);
153
154 if (poreLabel0 >= 0 && poreLabel1 >= 0)
155 {
156 std::cout << "\n Warning: Throat "
157 << eIdx << " connects two boundary pores with different pore labels. Using the greater pore label as throat label.\n"
158 << "Set the throat labels explicitly in your grid file, if needed." << std::endl;
159 }
160
161 using std::max;
162 throatLabel_[eIdx] = max(poreLabel0, poreLabel1);
163 }
164
166 {
167 static const auto throatShapeFactorIdx = gridData.parameterIndex("ThroatShapeFactor");
168 static const auto throatAreaIdx = gridData.parameterIndex("ThroatCrossSectionalArea");
169 throatShapeFactor_[eIdx] = params[throatShapeFactorIdx];
170 throatGeometry_[eIdx] = Throat::shape(throatShapeFactor_[eIdx]);
171 throatCrossSectionalArea_[eIdx] = params[throatAreaIdx];
172 }
173 else
174 {
175 throatCrossSectionalArea_[eIdx] = getThroatCrossSectionalArea_(gridData, element, eIdx);
176 throatShapeFactor_[eIdx] = getThroatShapeFactor_(gridData, element, eIdx);
177 }
178
179 assert(throatInscribedRadius_[eIdx] > 0.0);
180 assert(throatLength_[eIdx] > 0.0);
181 assert(throatCrossSectionalArea_[eIdx] > 0.0);
182
183 static const bool addThroatVolumeToPoreVolume = getParamFromGroup<bool>(gridData.paramGroup(), "Grid.AddThroatVolumeToPoreVolume", false);
184 if (addThroatVolumeToPoreVolume)
185 {
186 for (int vIdxLocal = 0; vIdxLocal < 2; ++vIdxLocal)
187 {
188 const auto vIdx = gridView.indexSet().subIndex(element, vIdxLocal, dim);
189 poreVolume_[vIdx] += 0.5 * throatCrossSectionalArea_[eIdx] * throatLength_[eIdx];
190 }
191 }
192 }
193
194 maybeResizeContainers_();
195 }
196
198 Label poreLabel(const GridIndex dofIdxGlobal) const
199 { return poreLabel_[dofIdxGlobal]; }
200
202 const std::vector<Label>& poreLabel() const
203 { return poreLabel_; }
204
206 Scalar poreInscribedRadius(const GridIndex dofIdxGlobal) const
207 { return poreInscribedRadius_[dofIdxGlobal]; }
208
210 const std::vector<Scalar>& poreInscribedRadius() const
211 { return poreInscribedRadius_; }
212
214 Scalar poreVolume(const GridIndex dofIdxGlobal) const
215 { return poreVolume_[dofIdxGlobal]; }
216
218 const std::vector<Scalar>& poreVolume() const
219 { return poreVolume_; }
220
222 Scalar throatInscribedRadius(const GridIndex eIdx) const
223 { return throatInscribedRadius_[eIdx]; }
224
226 const std::vector<Scalar>& throatInscribedRadius() const
227 { return throatInscribedRadius_; }
228
230 Scalar throatLength(const GridIndex eIdx) const
231 { return throatLength_[eIdx]; }
232
234 const std::vector<Scalar>& throatLength() const
235 { return throatLength_; }
236
238 Label throatLabel(const GridIndex eIdx) const
239 { return throatLabel_[eIdx]; }
240
242 const std::vector<Label>& throatLabel() const
243 { return throatLabel_; }
244
246 SmallLocalIndex coordinationNumber(const GridIndex dofIdxGlobal) const
247 { return coordinationNumber_[dofIdxGlobal]; }
248
250 const std::vector<SmallLocalIndex>& coordinationNumber() const
251 { return coordinationNumber_; }
252
254 Pore::Shape poreGeometry(const GridIndex vIdx) const
255 { return useSameGeometryForAllPores() ? poreGeometry_[0] : poreGeometry_[vIdx]; }
256
258 const std::vector<Pore::Shape>& poreGeometry() const
259 {
261 {
262 // if a vector of pore geometries is requested (e.g., for vtk output),
263 // resize the container and fill it with the same value everywhere
264 const auto poreGeo = poreGeometry_[0];
265 poreGeometry_.resize(poreInscribedRadius_.size(), poreGeo);
266 }
267
268 return poreGeometry_;
269 }
270
272 Throat::Shape throatCrossSectionShape(const GridIndex eIdx) const
273 { return useSameShapeForAllThroats() ? throatGeometry_[0] : throatGeometry_[eIdx]; }
274
276 const std::vector<Throat::Shape>& throatCrossSectionShape() const
277 {
279 {
280 // if a vector of throat cross section shapes is requested (e.g., for vtk output),
281 // resize the container and fill it with the same value everywhere
282 const auto throatShape = throatGeometry_[0];
283 throatGeometry_.resize(throatInscribedRadius_.size(), throatShape);
284 }
285
286 return throatGeometry_;
287 }
288
290 Scalar throatCrossSectionalArea(const GridIndex eIdx) const
291 { return throatCrossSectionalArea_[eIdx]; }
292
294 const std::vector<Scalar>& throatCrossSectionalArea() const
295 { return throatCrossSectionalArea_; }
296
298 Scalar throatShapeFactor(const GridIndex eIdx) const
299 { return useSameShapeForAllThroats() ? throatShapeFactor_[0] : throatShapeFactor_[eIdx]; }
300
302 const std::vector<Scalar>& throatShapeFactor() const
303 {
305 {
306 // if a vector of throat shape factors is requested (e.g., for vtk output),
307 // resize the container and fill it with the same value everywhere
308 const auto shapeFactor = throatShapeFactor_[0];
309 throatShapeFactor_.resize(throatInscribedRadius_.size(), shapeFactor);
310 }
311
312 return throatShapeFactor_;
313 }
314
317 { return useSameGeometryForAllPores_; }
318
321 { return useSameShapeForAllThroats_; }
322
323private:
324
326 template<class GridData>
327 Pore::Shape getPoreGeometry_(const GridData& gridData, const Vertex& vertex) const
328 {
329 static const auto poreGeometryIdx = gridData.parameterIndex("PoreGeometry");
330 using T = std::underlying_type_t<Pore::Shape>;
331 const auto poreGeometryValue = static_cast<T>(gridData.parameters(vertex)[poreGeometryIdx]);
332 return static_cast<Pore::Shape>(poreGeometryValue);
333 }
334
336 template<class GridData>
337 Scalar getPoreVolume_(const GridData& gridData, const Vertex& vertex, const std::size_t vIdx) const
338 {
339 static const bool gridHasPoreVolume = gridData.gridHasVertexParameter("PoreVolume");
340
341 if (gridHasPoreVolume)
342 {
343 static const auto poreVolumeIdx = gridData.parameterIndex("PoreVolume");
344 return gridData.parameters(vertex)[poreVolumeIdx];
345 }
346 else
347 {
349 {
350 static const Scalar fixedHeight = getParamFromGroup<Scalar>(gridData.paramGroup(), "Grid.PoreHeight", -1.0);
351 const Scalar h = fixedHeight > 0.0 ? fixedHeight : gridData.getParameter(vertex, "PoreHeight");
353 }
354 else
355 return Pore::volume(poreGeometry(vIdx), poreInscribedRadius(vIdx));
356 }
357 }
358
360 template<class GridData>
361 Scalar getThroatCrossSectionalArea_(const GridData& gridData, const Element& element, const std::size_t eIdx) const
362 {
363 static const bool gridHasThroatCrossSectionalArea = gridData.gridHasElementParameter("ThroatCrossSectionalArea");
364 if (gridHasThroatCrossSectionalArea && !overwriteGridDataWithShapeSpecificValues_)
365 {
366 static const auto throatAreaIdx = gridData.parameterIndex("ThroatCrossSectionalArea");
367 return gridData.parameters(element)[throatAreaIdx];
368 }
369 else
370 {
371 if (const auto shape = throatCrossSectionShape(eIdx); shape == Throat::Shape::rectangle)
372 {
373 static const auto throatHeight = getParamFromGroup<Scalar>(gridData.paramGroup(), "Grid.ThroatHeight");
374 return Throat::totalCrossSectionalAreaForRectangle(throatInscribedRadius_[eIdx], throatHeight);
375 }
376 else
377 return Throat::totalCrossSectionalArea(shape, throatInscribedRadius_[eIdx]);
378 }
379 }
380
382 template<class GridData>
383 Scalar getThroatShapeFactor_(const GridData& gridData, const Element& element, const std::size_t eIdx) const
384 {
385 static const bool gridHasThroatShapeFactor = gridData.gridHasElementParameter("ThroatShapeFactor");
386 if (gridHasThroatShapeFactor && !overwriteGridDataWithShapeSpecificValues_)
387 {
388 static const auto throatShapeFactorIdx = gridData.parameterIndex("ThroatShapeFactor");
389 return gridData.parameters(element)[throatShapeFactorIdx];
390 }
391 else
392 {
393 if (const auto shape = throatCrossSectionShape(eIdx); shape == Throat::Shape::rectangle)
394 {
395 static const auto throatHeight = getParamFromGroup<Scalar>(gridData.paramGroup(), "Grid.ThroatHeight");
396 return Throat::shapeFactorRectangle(throatInscribedRadius_[eIdx], throatHeight);
397 }
398 else if (shape == Throat::Shape::polygon || shape == Throat::Shape::scaleneTriangle)
399 {
400 static const auto shapeFactor = getParamFromGroup<Scalar>(gridData.paramGroup(), "Grid.ThroatShapeFactor");
401 return shapeFactor;
402 }
403 else
404 return Throat::shapeFactor<Scalar>(shape, throatInscribedRadius_[eIdx]);
405 }
406 }
407
408 void maybeResizeContainers_()
409 {
410 // check if all throat might have the same shape in order to save some memory
412 std::adjacent_find(throatGeometry_.begin(), throatGeometry_.end(), std::not_equal_to<Throat::Shape>() ) == throatGeometry_.end())
413 {
414 std::cout << "All throats feature the same shape, resizing containers" << std::endl;
415 useSameShapeForAllThroats_ = true;
416 const Scalar shapeFactor = throatShapeFactor_[0];
417 const auto throatGeometry = throatGeometry_[0];
418 throatShapeFactor_.resize(1);
419 throatGeometry_.resize(1);
420 throatShapeFactor_[0] = shapeFactor;
421 throatGeometry_[0] = throatGeometry;
422 }
423
424 // check if all throat might have the same shape in order to save some memory
426 std::adjacent_find(poreGeometry_.begin(), poreGeometry_.end(), std::not_equal_to<Pore::Shape>() ) == poreGeometry_.end())
427 {
428 std::cout << "All pores feature the same shape, resizing containers" << std::endl;
429 useSameGeometryForAllPores_ = true;
430 const auto poreGeometry = poreGeometry_[0];
431 poreGeometry_.resize(1);
432 poreGeometry_[0] = poreGeometry;
433 }
434 }
435
436 mutable std::vector<Pore::Shape> poreGeometry_;
437 std::vector<Scalar> poreInscribedRadius_;
438 std::vector<Scalar> poreVolume_;
439 std::vector<Label> poreLabel_; // 0:no, 1:general, 2:coupling1, 3:coupling2, 4:inlet, 5:outlet
440 std::vector<SmallLocalIndex> coordinationNumber_;
441 mutable std::vector<Throat::Shape> throatGeometry_;
442 mutable std::vector<Scalar> throatShapeFactor_;
443 std::vector<Scalar> throatInscribedRadius_;
444 std::vector<Scalar> throatLength_;
445 std::vector<Label> throatLabel_; // 0:no, 1:general, 2:coupling1, 3:coupling2, 4:inlet, 5:outlet
446 std::vector<Scalar> throatCrossSectionalArea_;
447 bool useSameGeometryForAllPores_;
448 bool useSameShapeForAllThroats_;
449 bool overwriteGridDataWithShapeSpecificValues_;
450};
451
457template<class GridView, class MapperTraits = DefaultMapperTraits<GridView>>
469
475template<class Scalar,
476 class GridView,
477 bool enableGridGeometryCache = false,
480
486template<class Scalar, class GV, class Traits>
487class GridGeometry<Scalar, GV, true, Traits>
488: public BaseGridGeometry<GV, Traits>
489, public Traits::PNMData
490{
492 using ParentType = BaseGridGeometry<GV, Traits>;
493 using GridIndexType = typename IndexTraits<GV>::GridIndex;
494 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
495 using PNMData = typename Traits::PNMData;
496
497 using Element = typename GV::template Codim<0>::Entity;
498 using CoordScalar = typename GV::ctype;
499 static const int dim = GV::dimension;
500 static const int dimWorld = GV::dimensionworld;
501
502public:
506
508 using LocalView = typename Traits::template LocalView<ThisType, true>;
510 using SubControlVolume = typename Traits::SubControlVolume;
512 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
516 using DofMapper = typename Traits::VertexMapper;
518 using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
520 using GridView = GV;
521
523 template<class GridData>
524 GridGeometry(const GridView& gridView, const GridData& gridData)
525 : ParentType(gridView)
526 {
527 static_assert(GridView::dimension == 1, "Porenetwork model only allow GridView::dimension == 1!");
528 update_(gridData);
529 }
530
533 const DofMapper& dofMapper() const
534 { return this->vertexMapper(); }
535
537 std::size_t numScv() const
538 { return numScv_; }
539
541 std::size_t numScvf() const
542 { return numScvf_; }
543
546 std::size_t numBoundaryScvf() const
547 { return 0; }
548
550 std::size_t numDofs() const
551 { return this->vertexMapper().size(); }
552
554 template<class GridData>
555 void update(const GridView& gridView, const GridData& gridData)
556 {
558 update_(gridData);
559 }
560
562 template<class GridData>
563 void update(GridView&& gridView, const GridData& gridData)
564 {
565 ParentType::update(std::move(gridView));
566 update_(gridData);
567 }
568
570 const FeCache& feCache() const
571 { return feCache_; }
572
574 const std::array<SubControlVolume, 2>& scvs(GridIndexType eIdx) const
575 { return scvs_[eIdx]; }
576
578 const std::array<SubControlVolumeFace, 1>& scvfs(GridIndexType eIdx) const
579 { return scvfs_[eIdx]; }
580
582 bool dofOnBoundary(GridIndexType dofIdx) const
583 { return boundaryDofIndices_[dofIdx]; }
584
586 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
587 { return false; }
588
590 [[deprecated("Will be removed after release 3.11. Use periodicallyMappedDofs, returning a range of dofs")]]
591 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
592 { DUNE_THROW(Dune::NotImplemented, "Periodic boundaries"); }
593
595 std::span<const GridIndexType> periodicallyMappedDofs(GridIndexType dofIdx) const
596 { DUNE_THROW(Dune::NotImplemented, "Periodic boundaries"); }
597
599 bool hasBoundaryScvf(GridIndexType eIdx) const
600 { return hasBoundaryScvf_[eIdx]; }
601
602private:
603
604 template<class GridData>
605 void update_(const GridData& gridData)
606 {
607 PNMData::update(this->gridView(), gridData);
608
609 scvs_.clear();
610 scvfs_.clear();
611
612 auto numElements = this->gridView().size(0);
613 scvs_.resize(numElements);
614 scvfs_.resize(numElements);
615 hasBoundaryScvf_.resize(numElements, false);
616
617 boundaryDofIndices_.assign(numDofs(), false);
618
619 numScvf_ = numElements;
620 numScv_ = 2*numElements;
621
622 // Build the SCV and SCV faces
623 for (const auto& element : elements(this->gridView()))
624 {
625 // get the element geometry
626 auto eIdx = this->elementMapper().index(element);
627 auto elementGeometry = element.geometry();
628
629 // construct the sub control volumes
630 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
631 {
632 const auto dofIdxGlobal = this->vertexMapper().subIndex(element, scvLocalIdx, dim);
633
634 // get the corners
635 auto corners = std::array{elementGeometry.corner(scvLocalIdx), elementGeometry.center()};
636
637 // get the fractional volume associated with the scv
638 const auto volume = this->poreVolume(dofIdxGlobal) / this->coordinationNumber(dofIdxGlobal);
639
640 scvs_[eIdx][scvLocalIdx] = SubControlVolume(dofIdxGlobal,
641 scvLocalIdx,
642 eIdx,
643 std::move(corners),
644 volume);
645
646 if (this->poreLabel(dofIdxGlobal) > 0)
647 {
648 if (boundaryDofIndices_[dofIdxGlobal])
649 continue;
650
651 boundaryDofIndices_[dofIdxGlobal] = true;
652 hasBoundaryScvf_[eIdx] = true;
653 }
654 }
655
656 // construct the inner sub control volume face
657 auto unitOuterNormal = elementGeometry.corner(1)-elementGeometry.corner(0);
658 unitOuterNormal /= unitOuterNormal.two_norm();
659 LocalIndexType scvfLocalIdx = 0;
660 scvfs_[eIdx][0] = SubControlVolumeFace(elementGeometry.center(),
661 std::move(unitOuterNormal),
662 this->throatCrossSectionalArea(this->elementMapper().index(element)),
663 scvfLocalIdx++,
664 std::array<LocalIndexType, 2>({0, 1}));
665 }
666 }
667
668 const FeCache feCache_;
669
670 std::vector<std::array<SubControlVolume, 2>> scvs_;
671 std::vector<std::array<SubControlVolumeFace, 1>> scvfs_;
672
673 std::size_t numScv_;
674 std::size_t numScvf_;
675
676 // vertices on the boundary
677 std::vector<bool> boundaryDofIndices_;
678 std::vector<bool> hasBoundaryScvf_;
679};
680
687template<class Scalar, class GV, class Traits>
688class GridGeometry<Scalar, GV, false, Traits>
689: public BaseGridGeometry<GV, Traits>
690, public Traits::PNMData
691{
693 using ParentType = BaseGridGeometry<GV, Traits>;
694 using GridIndexType = typename IndexTraits<GV>::GridIndex;
695 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
696 using PNMData = typename Traits::PNMData;
697
698 static const int dim = GV::dimension;
699 static const int dimWorld = GV::dimensionworld;
700
701 using Element = typename GV::template Codim<0>::Entity;
702 using CoordScalar = typename GV::ctype;
703
704public:
708
710 using LocalView = typename Traits::template LocalView<ThisType, false>;
712 using SubControlVolume = typename Traits::SubControlVolume;
714 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
718 using DofMapper = typename Traits::VertexMapper;
720 using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
722 using GridView = GV;
723
725 template<class GridData>
726 GridGeometry(const GridView& gridView, const GridData& gridData)
727 : ParentType(gridView)
728 {
729 static_assert(GridView::dimension == 1, "Porenetwork model only allow GridView::dimension == 1!");
730 update_(gridData);
731 }
732
733
736 const DofMapper& dofMapper() const
737 { return this->vertexMapper(); }
738
740 std::size_t numScv() const
741 { return numScv_; }
742
744 std::size_t numScvf() const
745 { return numScvf_; }
746
749 std::size_t numBoundaryScvf() const
750 { return 0; }
751
753 std::size_t numDofs() const
754 { return this->vertexMapper().size(); }
755
757 template<class GridData>
758 void update(const GridView& gridView, const GridData& gridData)
759 {
761 update_(gridData);
762 }
763
765 template<class GridData>
766 void update(GridView&& gridView, const GridData& gridData)
767 {
768 ParentType::update(std::move(gridView));
769 update_(gridData);
770 }
771
773 const FeCache& feCache() const
774 { return feCache_; }
775
777 bool dofOnBoundary(GridIndexType dofIdx) const
778 { return boundaryDofIndices_[dofIdx]; }
779
781 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
782 { return false; }
783
785 [[deprecated("Will be removed after release 3.11. Use periodicallyMappedDofs, returning a range of dofs")]]
786 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
787 { DUNE_THROW(Dune::NotImplemented, "Periodic boundaries"); }
788
790 std::span<const GridIndexType> periodicallyMappedDofs(GridIndexType dofIdx) const
791 { DUNE_THROW(Dune::NotImplemented, "Periodic boundaries"); }
792
793private:
794
795 template<class GridData>
796 void update_(const GridData& gridData)
797 {
798 PNMData::update(this->gridView(), gridData);
799
800 boundaryDofIndices_.assign(numDofs(), false);
801
802 // save global data on the grid's scvs and scvfs
803 numScvf_ = this->gridView().size(0);
804 numScv_ = 2*numScvf_;
805
806 for (const auto& element : elements(this->gridView()))
807 {
808 // treat boundaries
809 for (LocalIndexType vIdxLocal = 0; vIdxLocal < 2; ++vIdxLocal)
810 {
811 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdxLocal, dim);
812 if (this->poreLabel(vIdxGlobal) > 0)
813 {
814 if (boundaryDofIndices_[vIdxGlobal])
815 continue;
816
817 boundaryDofIndices_[vIdxGlobal] = true;
818 }
819 }
820 }
821 }
822
823 const FeCache feCache_;
824
825 // Information on the global number of geometries
826 std::size_t numScv_;
827 std::size_t numScvf_;
828
829 // vertices on the boundary
830 std::vector<bool> boundaryDofIndices_;
831};
832
833} // end namespace Dumux::PoreNetwork
834
835#endif
Base class for grid geometries.
const VertexMapper & vertexMapper() const
Returns the mapper for vertices to indices for constant grids.
Definition basegridgeometry.hh:106
const GridView & gridView() const
Return the gridView this grid geometry object lives on.
Definition basegridgeometry.hh:100
void update(const GridView &gridView)
Update all fvElementGeometries (call this after grid adaption).
Definition basegridgeometry.hh:88
Class for grid data attached to dgf or gmsh grid files.
Definition griddata.hh:57
double getParameter(const Element &element, const std::string &fieldName) const
Get an element parameter.
Definition griddata.hh:254
const std::vector< double > & parameters(const Vertex &vertex) const
Call the parameters function of the DGF grid pointer if available for vertex data.
Definition griddata.hh:114
Base class for geometry data extraction from the grid data format.
Definition discretization/porenetwork/gridgeometry.hh:46
Scalar throatCrossSectionalArea(const GridIndex eIdx) const
Returns the throat's cross-sectional area.
Definition discretization/porenetwork/gridgeometry.hh:290
const std::vector< Scalar > & poreVolume() const
Returns the vector of pore volumes.
Definition discretization/porenetwork/gridgeometry.hh:218
const std::vector< Scalar > & throatInscribedRadius() const
Returns the vector of inscribed throat radii.
Definition discretization/porenetwork/gridgeometry.hh:226
bool useSameGeometryForAllPores() const
Returns whether all pores feature the same shape.
Definition discretization/porenetwork/gridgeometry.hh:316
const std::vector< Label > & poreLabel() const
Returns the vector of pore labels.
Definition discretization/porenetwork/gridgeometry.hh:202
bool useSameShapeForAllThroats() const
Returns whether all throats feature the same cross-sectional shape.
Definition discretization/porenetwork/gridgeometry.hh:320
SmallLocalIndex coordinationNumber(const GridIndex dofIdxGlobal) const
Returns the number of throats connected to a pore (coordination number).
Definition discretization/porenetwork/gridgeometry.hh:246
void update(const GridView &gridView, const GridData &gridData)
Definition discretization/porenetwork/gridgeometry.hh:58
const std::vector< SmallLocalIndex > & coordinationNumber() const
Returns the vector of coordination numbers.
Definition discretization/porenetwork/gridgeometry.hh:250
const std::vector< Scalar > & throatShapeFactor() const
Returns the vector of throat shape factors.
Definition discretization/porenetwork/gridgeometry.hh:302
const std::vector< Scalar > & throatCrossSectionalArea() const
Returns the vector of throat cross-sectional areas.
Definition discretization/porenetwork/gridgeometry.hh:294
Pore::Shape poreGeometry(const GridIndex vIdx) const
the geometry of the pore
Definition discretization/porenetwork/gridgeometry.hh:254
Throat::Shape throatCrossSectionShape(const GridIndex eIdx) const
Returns the throat's cross-sectional shape.
Definition discretization/porenetwork/gridgeometry.hh:272
Label throatLabel(const GridIndex eIdx) const
Returns an index indicating if a throat is touching the domain boundary.
Definition discretization/porenetwork/gridgeometry.hh:238
const std::vector< Label > & throatLabel() const
Returns the vector of throat labels.
Definition discretization/porenetwork/gridgeometry.hh:242
Scalar throatLength(const GridIndex eIdx) const
Returns the length of the throat.
Definition discretization/porenetwork/gridgeometry.hh:230
const std::vector< Throat::Shape > & throatCrossSectionShape() const
Returns the vector of cross-sectional shapes.
Definition discretization/porenetwork/gridgeometry.hh:276
Scalar poreVolume(const GridIndex dofIdxGlobal) const
Returns the volume of the pore.
Definition discretization/porenetwork/gridgeometry.hh:214
Scalar throatInscribedRadius(const GridIndex eIdx) const
Returns the inscribed radius of the throat.
Definition discretization/porenetwork/gridgeometry.hh:222
Label poreLabel(const GridIndex dofIdxGlobal) const
Returns the pore label (e.g. used for setting BCs).
Definition discretization/porenetwork/gridgeometry.hh:198
Scalar poreInscribedRadius(const GridIndex dofIdxGlobal) const
Returns the inscribed radius of the pore.
Definition discretization/porenetwork/gridgeometry.hh:206
const std::vector< Scalar > & throatLength() const
Returns the vector of throat lengths.
Definition discretization/porenetwork/gridgeometry.hh:234
const std::vector< Pore::Shape > & poreGeometry() const
Returns the vector of pore geometries.
Definition discretization/porenetwork/gridgeometry.hh:258
Scalar throatShapeFactor(const GridIndex eIdx) const
Returns the throat's shape factor.
Definition discretization/porenetwork/gridgeometry.hh:298
const std::vector< Scalar > & poreInscribedRadius() const
Returns the vector of inscribed pore radii.
Definition discretization/porenetwork/gridgeometry.hh:210
Class for grid data attached to dgf or gmsh grid files.
Definition porenetwork/griddata.hh:44
bool gridHasElementParameter(const std::string &param) const
Return if a given element parameter is provided by the grid.
Definition porenetwork/griddata.hh:254
std::vector< SmallLocalIndex > getCoordinationNumbers() const
Returns the coordination numbers for all pore bodies.
Definition porenetwork/griddata.hh:139
int parameterIndex(const std::string &paramName) const
Return the index for a given parameter name.
Definition porenetwork/griddata.hh:222
const std::string & paramGroup() const
Return the parameter group.
Definition porenetwork/griddata.hh:248
const std::vector< double > & parameters(const Vertex &vertex) const
Call the parameters function of the DGF grid pointer if available for vertex data.
Definition porenetwork/griddata.hh:86
bool dofOnBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition discretization/porenetwork/gridgeometry.hh:777
Dune::LagrangeLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
export the finite element cache type
Definition discretization/porenetwork/gridgeometry.hh:720
static constexpr DiscretizationMethod discMethod
Definition discretization/porenetwork/gridgeometry.hh:707
std::size_t numDofs() const
The total number of degrees of freedom.
Definition discretization/porenetwork/gridgeometry.hh:753
std::size_t numBoundaryScvf() const
Definition discretization/porenetwork/gridgeometry.hh:749
void update(GridView &&gridView, const GridData &gridData)
update all fvElementGeometries (call this after grid adaption)
Definition discretization/porenetwork/gridgeometry.hh:766
void update(const GridView &gridView, const GridData &gridData)
update all fvElementGeometries (call this after grid adaption)
Definition discretization/porenetwork/gridgeometry.hh:758
std::size_t numScv() const
The total number of sub control volumes.
Definition discretization/porenetwork/gridgeometry.hh:740
typename Traits::VertexMapper DofMapper
export dof mapper type
Definition discretization/porenetwork/gridgeometry.hh:718
GridGeometry(const GridView &gridView, const GridData &gridData)
Constructor.
Definition discretization/porenetwork/gridgeometry.hh:726
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition discretization/porenetwork/gridgeometry.hh:773
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition discretization/porenetwork/gridgeometry.hh:714
Extrusion_t< Traits > Extrusion
export the type of extrusion
Definition discretization/porenetwork/gridgeometry.hh:716
std::size_t numScvf() const
The total number of sun control volume faces.
Definition discretization/porenetwork/gridgeometry.hh:744
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition discretization/porenetwork/gridgeometry.hh:712
typename Traits::template LocalView< ThisType, false > LocalView
export the type of the fv element geometry (the local view type)
Definition discretization/porenetwork/gridgeometry.hh:710
const DofMapper & dofMapper() const
Definition discretization/porenetwork/gridgeometry.hh:736
GV GridView
export the grid view type
Definition discretization/porenetwork/gridgeometry.hh:722
DiscretizationMethods::Box DiscretizationMethod
export the discretization method this geometry belongs to
Definition discretization/porenetwork/gridgeometry.hh:706
GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
The index of the vertex / d.o.f. on the other side of the periodic boundary.
Definition discretization/porenetwork/gridgeometry.hh:786
std::span< const GridIndexType > periodicallyMappedDofs(GridIndexType dofIdx) const
The indices of the vertices / d.o.f.s on the other side of the periodic boundary.
Definition discretization/porenetwork/gridgeometry.hh:790
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on a periodic boundary (not implemented).
Definition discretization/porenetwork/gridgeometry.hh:781
Dune::LagrangeLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
export the finite element cache type
Definition discretization/porenetwork/gridgeometry.hh:518
std::size_t numDofs() const
The total number of degrees of freedom.
Definition discretization/porenetwork/gridgeometry.hh:550
const std::array< SubControlVolume, 2 > & scvs(GridIndexType eIdx) const
Get the local scvs for an element.
Definition discretization/porenetwork/gridgeometry.hh:574
GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
The index of the vertex / d.o.f. on the other side of the periodic boundary.
Definition discretization/porenetwork/gridgeometry.hh:591
DiscretizationMethods::Box DiscretizationMethod
export the discretization method this geometry belongs to
Definition discretization/porenetwork/gridgeometry.hh:504
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition discretization/porenetwork/gridgeometry.hh:512
const DofMapper & dofMapper() const
Definition discretization/porenetwork/gridgeometry.hh:533
std::size_t numScv() const
The total number of sub control volumes.
Definition discretization/porenetwork/gridgeometry.hh:537
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on a periodic boundary (not implemented).
Definition discretization/porenetwork/gridgeometry.hh:586
bool dofOnBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition discretization/porenetwork/gridgeometry.hh:582
std::span< const GridIndexType > periodicallyMappedDofs(GridIndexType dofIdx) const
The indices of the vertices / d.o.f.s on the other side of the periodic boundary.
Definition discretization/porenetwork/gridgeometry.hh:595
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition discretization/porenetwork/gridgeometry.hh:510
typename Traits::template LocalView< ThisType, true > LocalView
export the type of the fv element geometry (the local view type)
Definition discretization/porenetwork/gridgeometry.hh:508
GV GridView
export the grid view type
Definition discretization/porenetwork/gridgeometry.hh:520
std::size_t numScvf() const
The total number of sun control volume faces.
Definition discretization/porenetwork/gridgeometry.hh:541
Extrusion_t< Traits > Extrusion
export the type of extrusion
Definition discretization/porenetwork/gridgeometry.hh:514
const std::array< SubControlVolumeFace, 1 > & scvfs(GridIndexType eIdx) const
Get the local scvfs for an element.
Definition discretization/porenetwork/gridgeometry.hh:578
std::size_t numBoundaryScvf() const
Definition discretization/porenetwork/gridgeometry.hh:546
void update(const GridView &gridView, const GridData &gridData)
update all fvElementGeometries (call this after grid adaption)
Definition discretization/porenetwork/gridgeometry.hh:555
static constexpr DiscretizationMethod discMethod
Definition discretization/porenetwork/gridgeometry.hh:505
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition discretization/porenetwork/gridgeometry.hh:570
typename Traits::VertexMapper DofMapper
export dof mapper type
Definition discretization/porenetwork/gridgeometry.hh:516
bool hasBoundaryScvf(GridIndexType eIdx) const
Returns whether one of the geometry's scvfs lies on a boundary.
Definition discretization/porenetwork/gridgeometry.hh:599
GridGeometry(const GridView &gridView, const GridData &gridData)
Constructor.
Definition discretization/porenetwork/gridgeometry.hh:524
void update(GridView &&gridView, const GridData &gridData)
update all fvElementGeometries (call this after grid adaption)
Definition discretization/porenetwork/gridgeometry.hh:563
Base class for the finite volume geometry for porenetwork models.
Definition discretization/porenetwork/gridgeometry.hh:479
Base class for the local geometry for porenetworks.
Definition discretization/porenetwork/fvelementgeometry.hh:33
Class for a sub control volume face for porenetworks.
Definition discretization/porenetwork/subcontrolvolumeface.hh:51
the sub control volume for porenetworks
Definition discretization/porenetwork/subcontrolvolume.hh:50
Defines the default element and vertex mapper types.
Base class for the local geometry for porenetworks.
the sub control volume for pore networks
Base class for a sub control volume face.
Helper classes to compute the integration elements.
BaseGridGeometry(std::shared_ptr< BaseImplementation > impl)
Constructor from a BaseImplementation.
Definition basegridgeometry.hh:72
auto volume(const Geometry &geo, unsigned int integrationOrder=4)
The volume of a given geometry.
Definition volume.hh:159
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:165
bool hasParamInGroup(const std::string &paramGroup, const std::string &param)
Check whether a key exists in the parameter tree with a model group prefix.
Definition parameters.hh:181
Defines the index types used for grid and local indices.
The available discretization methods in Dumux.
CVFE< CVFEMethods::PQ1 > Box
Definition method.hh:102
typename ScalarType< X >::Type Scalar
Definition odesolver.hh:52
Shape shapeFromString(const std::string &s)
Get the shape from a string description of the shape.
Definition poreproperties.hh:44
Scalar volume(Shape shape, Scalar inscribedRadius)
Returns the volume of a given geometry based on the inscribed radius.
Definition poreproperties.hh:61
Shape
Collection of different pore-body shapes.
Definition poreproperties.hh:23
@ cylinder
Definition poreproperties.hh:23
constexpr Scalar totalCrossSectionalAreaForRectangle(const Scalar inscribedRadius, const Scalar height) noexcept
Returns the cross-sectional area of a rectangle.
Definition throatproperties.hh:214
constexpr Shape shape(const Scalar shapeFactor) noexcept
Returns the shape for a given shape factor.
Definition throatproperties.hh:165
constexpr Scalar shapeFactorRectangle(const Scalar inscribedRadius, const Scalar height) noexcept
Returns the value of the shape factor for a rectangle.
Definition throatproperties.hh:132
Scalar totalCrossSectionalArea(const Shape shape, const Scalar inscribedRadius)
Returns the cross-sectional area of a given geometry.
Definition throatproperties.hh:199
Shape shapeFromString(const std::string &s)
Get the shape from a string description of the shape.
Definition throatproperties.hh:45
Shape
Collection of different pore-throat shapes.
Definition throatproperties.hh:26
@ scaleneTriangle
Definition throatproperties.hh:26
@ rectangle
Definition throatproperties.hh:26
@ polygon
Definition throatproperties.hh:26
Scalar shapeFactor(Shape shape, const Scalar inscribedRadius)
Returns the value of the shape factor for a given shape.
Definition throatproperties.hh:150
Definition discretization/porenetwork/fvelementgeometry.hh:24
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:257
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
This file contains functions related to calculate pore-body properties.
typename GridView::IndexSet::IndexType GridIndex
Definition indextraits.hh:27
std::uint_least8_t SmallLocalIndex
Definition indextraits.hh:29
unsigned int LocalIndex
Definition indextraits.hh:28
The default traits.
Definition discretization/porenetwork/gridgeometry.hh:460
PNMFVElementGeometry< GridGeometry, enableCache > LocalView
Definition discretization/porenetwork/gridgeometry.hh:465
PNMSubControlVolume< GridView > SubControlVolume
Definition discretization/porenetwork/gridgeometry.hh:461
DefaultPNMData< typename SubControlVolume::Traits::Scalar, GridView > PNMData
Definition discretization/porenetwork/gridgeometry.hh:467
PNMSubControlVolumeFace< GridView > SubControlVolumeFace
Definition discretization/porenetwork/gridgeometry.hh:462
This file contains functions related to calculate pore-throat properties.