3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_DISCRETIZATION_PNM_GRID_GEOMETRY_HH
25#define DUMUX_DISCRETIZATION_PNM_GRID_GEOMETRY_HH
26
27#include <string>
28#include <utility>
29#include <unordered_map>
30#include <functional>
31
32#include <dune/common/exceptions.hh>
33#include <dune/localfunctions/lagrange/lagrangelfecache.hh>
34
39
47
48namespace Dumux::PoreNetwork {
49
54template<class Scalar, class GridView>
56{
57 using GridIndex = typename IndexTraits<GridView>::GridIndex;
58 using SmallLocalIndex = typename IndexTraits<GridView>::SmallLocalIndex;
59 using Label = std::int_least8_t;
60 using Vertex = typename GridView::template Codim<GridView::dimension>::Entity;
61 using Element = typename GridView::template Codim<0>::Entity;
62
63 static const int dim = GridView::dimension;
64
65public:
66
67 template<class GridData>
68 void update(const GridView& gridView, const GridData& gridData)
69 {
70 coordinationNumber_ = gridData.getCoordinationNumbers();
71
72 const auto numThroats = gridView.size(0);
73 throatInscribedRadius_.resize(numThroats);
74 throatLength_.resize(numThroats);
75 throatLabel_.resize(numThroats);
76 throatCrossSectionalArea_.resize(numThroats);
77 throatShapeFactor_.resize(numThroats);
78
79 useSameGeometryForAllPores_ = true;
80 useSameShapeForAllThroats_ = true;
81 overwriteGridDataWithShapeSpecificValues_ = false;
82
83 // first check if the same geometry shall be used for all entities ...
84 if (hasParamInGroup(gridData.paramGroup(), "Grid.ThroatCrossSectionShape"))
85 {
86 const auto throatGeometryInput = getParamFromGroup<std::string>(gridData.paramGroup(), "Grid.ThroatCrossSectionShape");
87 const auto throatGeometry = Throat::shapeFromString(throatGeometryInput);
88 throatGeometry_.resize(1);
89 throatGeometry_[0] = throatGeometry;
90 overwriteGridDataWithShapeSpecificValues_ = getParamFromGroup<bool>(gridData.paramGroup(), "Grid.OverwriteGridDataWithShapeSpecificValues", true);
91
92 std::cout << "Using '" << throatGeometryInput << "' as cross-sectional shape for all throats." << std::endl;
93 }
94 else // .. otherwise, get the corresponding parameter index from the grid data and resize the respective vector
95 {
96 std::cout << "Reading shape factors for throats from grid data." << std::endl;
97 useSameShapeForAllThroats_ = false;
98 throatGeometry_.resize(numThroats);
99 }
100
101 // get the vertex parameters
102 const auto numPores = gridView.size(dim);
103 poreInscribedRadius_.resize(numPores);
104 poreLabel_.resize(numPores);
105 poreVolume_.resize(numPores);
106
107 // first check if the same geometry shall be used for all entities ...
108 if (hasParamInGroup(gridData.paramGroup(), "Grid.PoreGeometry"))
109 {
110 const auto poreGeometryInput = getParamFromGroup<std::string>(gridData.paramGroup(), "Grid.PoreGeometry");
111 poreGeometry_.resize(1);
112 poreGeometry_[0] = Pore::shapeFromString(poreGeometryInput);;
113
114 std::cout << "Using '" << poreGeometryInput << "' as geometry for all pores." << std::endl;
115 }
116 else // .. otherwise, get the corresponding parameter index from the grid data and resize the respective vector
117 {
118 std::cout << "Reading pore shapes from grid data." << std::endl;
119 useSameGeometryForAllPores_ = false;
120 poreGeometry_.resize(numPores);
121 }
122
123
124 for (const auto& vertex : vertices(gridView))
125 {
126 static const auto poreInscribedRadiusIdx = gridData.parameterIndex("PoreInscribedRadius");
127 static const auto poreLabelIdx = gridData.parameterIndex("PoreLabel");
128 const auto vIdx = gridView.indexSet().index(vertex);
129 const auto& params = gridData.parameters(vertex);
130 poreInscribedRadius_[vIdx] = params[poreInscribedRadiusIdx];
131 assert(poreInscribedRadius_[vIdx] > 0.0);
132 poreLabel_[vIdx] = params[poreLabelIdx];
133
135 poreGeometry_[vIdx] = getPoreGeometry_(gridData, vertex);
136
137 poreVolume_[vIdx] = getPoreVolume_(gridData, vertex, vIdx);
138 }
139
140 for (const auto& element : elements(gridView))
141 {
142 const int eIdx = gridView.indexSet().index(element);
143 const auto& params = gridData.parameters(element);
144 static const auto throatInscribedRadiusIdx = gridData.parameterIndex("ThroatInscribedRadius");
145 static const auto throatLengthIdx = gridData.parameterIndex("ThroatLength");
146 throatInscribedRadius_[eIdx] = params[throatInscribedRadiusIdx];
147 throatLength_[eIdx] = params[throatLengthIdx];
148
149 // use a default value if no throat label is given by the grid
150 static const bool gridHasThroatLabel = gridData.gridHasElementParameter("ThroatLabel");
151 if (gridHasThroatLabel)
152 {
153 static const auto throatLabelIdx = gridData.parameterIndex("ThroatLabel");
154 throatLabel_[eIdx] = params[throatLabelIdx];
155 }
156 else
157 {
158 const auto vIdx0 = gridView.indexSet().subIndex(element, 0, dim);
159 const auto vIdx1 = gridView.indexSet().subIndex(element, 1, dim);
160
161 const auto poreLabel0 = poreLabel(vIdx0);
162 const auto poreLabel1 = poreLabel(vIdx1);
163
164 if (poreLabel0 >= 0 && poreLabel1 >= 0)
165 {
166 std::cout << "\n Warning: Throat "
167 << eIdx << " connects two boundary pores with different pore labels. Using the greater pore label as throat label.\n"
168 << "Set the throat labels explicitly in your grid file, if needed." << std::endl;
169 }
170
171 using std::max;
172 throatLabel_[eIdx] = max(poreLabel0, poreLabel1);
173 }
174
176 {
177 static const auto throatShapeFactorIdx = gridData.parameterIndex("ThroatShapeFactor");
178 static const auto throatAreaIdx = gridData.parameterIndex("ThroatCrossSectionalArea");
179 throatShapeFactor_[eIdx] = params[throatShapeFactorIdx];
180 throatGeometry_[eIdx] = Throat::shape(throatShapeFactor_[eIdx]);
181 throatCrossSectionalArea_[eIdx] = params[throatAreaIdx];
182 }
183 else
184 {
185 throatCrossSectionalArea_[eIdx] = getThroatCrossSectionalArea_(gridData, element, eIdx);
186 throatShapeFactor_[eIdx] = getThroatShapeFactor_(gridData, element, eIdx);
187 }
188
189 assert(throatInscribedRadius_[eIdx] > 0.0);
190 assert(throatLength_[eIdx] > 0.0);
191 assert(throatCrossSectionalArea_[eIdx] > 0.0);
192
193 static const bool addThroatVolumeToPoreVolume = getParamFromGroup<bool>(gridData.paramGroup(), "Grid.AddThroatVolumeToPoreVolume", false);
194 if (addThroatVolumeToPoreVolume)
195 {
196 for (int vIdxLocal = 0; vIdxLocal < 2; ++vIdxLocal)
197 {
198 const auto vIdx = gridView.indexSet().subIndex(element, vIdxLocal, dim);
199 poreVolume_[vIdx] += 0.5 * throatCrossSectionalArea_[eIdx] * throatLength_[eIdx];
200 }
201 }
202 }
203
204 maybeResizeContainers_();
205 }
206
208 Label poreLabel(const GridIndex dofIdxGlobal) const
209 { return poreLabel_[dofIdxGlobal]; }
210
212 const std::vector<Label>& poreLabel() const
213 { return poreLabel_; }
214
216 Scalar poreInscribedRadius(const GridIndex dofIdxGlobal) const
217 { return poreInscribedRadius_[dofIdxGlobal]; }
218
220 const std::vector<Scalar>& poreInscribedRadius() const
221 { return poreInscribedRadius_; }
222
224 Scalar poreVolume(const GridIndex dofIdxGlobal) const
225 { return poreVolume_[dofIdxGlobal]; }
226
228 const std::vector<Scalar>& poreVolume() const
229 { return poreVolume_; }
230
232 Scalar throatInscribedRadius(const GridIndex eIdx) const
233 { return throatInscribedRadius_[eIdx]; }
234
236 const std::vector<Scalar>& throatInscribedRadius() const
237 { return throatInscribedRadius_; }
238
240 Scalar throatLength(const GridIndex eIdx) const
241 { return throatLength_[eIdx]; }
242
244 const std::vector<Scalar>& throatLength() const
245 { return throatLength_; }
246
248 Label throatLabel(const GridIndex eIdx) const
249 { return throatLabel_[eIdx]; }
250
252 const std::vector<Label>& throatLabel() const
253 { return throatLabel_; }
254
256 SmallLocalIndex coordinationNumber(const GridIndex dofIdxGlobal) const
257 { return coordinationNumber_[dofIdxGlobal]; }
258
260 const std::vector<SmallLocalIndex>& coordinationNumber() const
261 { return coordinationNumber_; }
262
264 Pore::Shape poreGeometry(const GridIndex vIdx) const
265 { return useSameGeometryForAllPores() ? poreGeometry_[0] : poreGeometry_[vIdx]; }
266
268 const std::vector<Pore::Shape>& poreGeometry() const
269 {
271 {
272 // if a vector of pore geometries is requested (e.g., for vtk output),
273 // resize the container and fill it with the same value everywhere
274 const auto poreGeo = poreGeometry_[0];
275 poreGeometry_.resize(poreInscribedRadius_.size(), poreGeo);
276 }
277
278 return poreGeometry_;
279 }
280
282 Throat::Shape throatCrossSectionShape(const GridIndex eIdx) const
283 { return useSameShapeForAllThroats() ? throatGeometry_[0] : throatGeometry_[eIdx]; }
284
286 const std::vector<Throat::Shape>& throatCrossSectionShape() const
287 {
289 {
290 // if a vector of throat cross section shapes is requested (e.g., for vtk output),
291 // resize the container and fill it with the same value everywhere
292 const auto throatShape = throatGeometry_[0];
293 throatGeometry_.resize(throatInscribedRadius_.size(), throatShape);
294 }
295
296 return throatGeometry_;
297 }
298
300 Scalar throatCrossSectionalArea(const GridIndex eIdx) const
301 { return throatCrossSectionalArea_[eIdx]; }
302
304 const std::vector<Scalar>& throatCrossSectionalArea() const
305 { return throatCrossSectionalArea_; }
306
308 Scalar throatShapeFactor(const GridIndex eIdx) const
309 { return useSameShapeForAllThroats() ? throatShapeFactor_[0] : throatShapeFactor_[eIdx]; }
310
312 const std::vector<Scalar>& throatShapeFactor() const
313 {
315 {
316 // if a vector of throat shape factors is requested (e.g., for vtk output),
317 // resize the container and fill it with the same value everywhere
318 const auto shapeFactor = throatShapeFactor_[0];
319 throatShapeFactor_.resize(throatInscribedRadius_.size(), shapeFactor);
320 }
321
322 return throatShapeFactor_;
323 }
324
327 { return useSameGeometryForAllPores_; }
328
331 { return useSameShapeForAllThroats_; }
332
333private:
334
336 template<class GridData>
337 Pore::Shape getPoreGeometry_(const GridData& gridData, const Vertex& vertex) const
338 {
339 static const auto poreGeometryIdx = gridData.parameterIndex("PoreGeometry");
340 using T = std::underlying_type_t<Pore::Shape>;
341 const auto poreGeometryValue = static_cast<T>(gridData.parameters(vertex)[poreGeometryIdx]);
342 return static_cast<Pore::Shape>(poreGeometryValue);
343 }
344
346 template<class GridData>
347 Scalar getPoreVolume_(const GridData& gridData, const Vertex& vertex, const std::size_t vIdx) const
348 {
349 static const bool gridHasPoreVolume = gridData.gridHasVertexParameter("PoreVolume");
350
351 if (gridHasPoreVolume)
352 {
353 static const auto poreVolumeIdx = gridData.parameterIndex("PoreVolume");
354 return gridData.parameters(vertex)[poreVolumeIdx];
355 }
356 else
357 {
359 {
360 static const Scalar fixedHeight = getParamFromGroup<Scalar>(gridData.paramGroup(), "Grid.PoreHeight", -1.0);
361 const Scalar h = fixedHeight > 0.0 ? fixedHeight : gridData.getParameter(vertex, "PoreHeight");
363 }
364 else
365 return Pore::volume(poreGeometry(vIdx), poreInscribedRadius(vIdx));
366 }
367 }
368
370 template<class GridData>
371 Scalar getThroatCrossSectionalArea_(const GridData& gridData, const Element& element, const std::size_t eIdx) const
372 {
373 static const bool gridHasThroatCrossSectionalArea = gridData.gridHasElementParameter("ThroatCrossSectionalArea");
374 if (gridHasThroatCrossSectionalArea && !overwriteGridDataWithShapeSpecificValues_)
375 {
376 static const auto throatAreaIdx = gridData.parameterIndex("ThroatCrossSectionalArea");
377 return gridData.parameters(element)[throatAreaIdx];
378 }
379 else
380 {
381 if (const auto shape = throatCrossSectionShape(eIdx); shape == Throat::Shape::rectangle)
382 {
383 static const auto throatHeight = getParamFromGroup<Scalar>(gridData.paramGroup(), "Grid.ThroatHeight");
384 return Throat::totalCrossSectionalAreaForRectangle(throatInscribedRadius_[eIdx], throatHeight);
385 }
386 else
387 return Throat::totalCrossSectionalArea(shape, throatInscribedRadius_[eIdx]);
388 }
389 }
390
392 template<class GridData>
393 Scalar getThroatShapeFactor_(const GridData& gridData, const Element& element, const std::size_t eIdx) const
394 {
395 static const bool gridHasThroatShapeFactor = gridData.gridHasElementParameter("ThroatShapeFactor");
396 if (gridHasThroatShapeFactor && !overwriteGridDataWithShapeSpecificValues_)
397 {
398 static const auto throatShapeFactorIdx = gridData.parameterIndex("ThroatShapeFactor");
399 return gridData.parameters(element)[throatShapeFactorIdx];
400 }
401 else
402 {
403 if (const auto shape = throatCrossSectionShape(eIdx); shape == Throat::Shape::rectangle)
404 {
405 static const auto throatHeight = getParamFromGroup<Scalar>(gridData.paramGroup(), "Grid.ThroatHeight");
406 return Throat::shapeFactorRectangle(throatInscribedRadius_[eIdx], throatHeight);
407 }
408 else if (shape == Throat::Shape::polygon || shape == Throat::Shape::scaleneTriangle)
409 {
410 static const auto shapeFactor = getParamFromGroup<Scalar>(gridData.paramGroup(), "Grid.ThroatShapeFactor");
411 return shapeFactor;
412 }
413 else
414 return Throat::shapeFactor<Scalar>(shape, throatInscribedRadius_[eIdx]);
415 }
416 }
417
418 void maybeResizeContainers_()
419 {
420 // check if all throat might have the same shape in order to save some memory
422 std::adjacent_find(throatGeometry_.begin(), throatGeometry_.end(), std::not_equal_to<Throat::Shape>() ) == throatGeometry_.end())
423 {
424 std::cout << "All throats feature the same shape, resizing containers" << std::endl;
425 useSameShapeForAllThroats_ = true;
426 const Scalar shapeFactor = throatShapeFactor_[0];
427 const auto throatGeometry = throatGeometry_[0];
428 throatShapeFactor_.resize(1);
429 throatGeometry_.resize(1);
430 throatShapeFactor_[0] = shapeFactor;
431 throatGeometry_[0] = throatGeometry;
432 }
433
434 // check if all throat might have the same shape in order to save some memory
436 std::adjacent_find(poreGeometry_.begin(), poreGeometry_.end(), std::not_equal_to<Pore::Shape>() ) == poreGeometry_.end())
437 {
438 std::cout << "All pores feature the same shape, resizing containers" << std::endl;
439 useSameGeometryForAllPores_ = true;
440 const auto poreGeometry = poreGeometry_[0];
441 poreGeometry_.resize(1);
442 poreGeometry_[0] = poreGeometry;
443 }
444 }
445
446 mutable std::vector<Pore::Shape> poreGeometry_;
447 std::vector<Scalar> poreInscribedRadius_;
448 std::vector<Scalar> poreVolume_;
449 std::vector<Label> poreLabel_; // 0:no, 1:general, 2:coupling1, 3:coupling2, 4:inlet, 5:outlet
450 std::vector<SmallLocalIndex> coordinationNumber_;
451 mutable std::vector<Throat::Shape> throatGeometry_;
452 mutable std::vector<Scalar> throatShapeFactor_;
453 std::vector<Scalar> throatInscribedRadius_;
454 std::vector<Scalar> throatLength_;
455 std::vector<Label> throatLabel_; // 0:no, 1:general, 2:coupling1, 3:coupling2, 4:inlet, 5:outlet
456 std::vector<Scalar> throatCrossSectionalArea_;
457 bool useSameGeometryForAllPores_;
458 bool useSameShapeForAllThroats_;
459 bool overwriteGridDataWithShapeSpecificValues_;
460};
461
467template<class GridView, class MapperTraits = DefaultMapperTraits<GridView>>
479
485template<class Scalar,
486 class GridView,
487 bool enableGridGeometryCache = false,
490
496template<class Scalar, class GV, class Traits>
497class GridGeometry<Scalar, GV, true, Traits>
498: public BaseGridGeometry<GV, Traits>
499, public Traits::PNMData
500{
502 using ParentType = BaseGridGeometry<GV, Traits>;
503 using GridIndexType = typename IndexTraits<GV>::GridIndex;
504 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
505 using PNMData = typename Traits::PNMData;
506
507 using Element = typename GV::template Codim<0>::Entity;
508 using CoordScalar = typename GV::ctype;
509 static const int dim = GV::dimension;
510 static const int dimWorld = GV::dimensionworld;
511
512public:
516
518 using LocalView = typename Traits::template LocalView<ThisType, true>;
520 using SubControlVolume = typename Traits::SubControlVolume;
522 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
526 using DofMapper = typename Traits::VertexMapper;
528 using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
530 using GridView = GV;
531
533 template<class GridData>
534 GridGeometry(const GridView& gridView, const GridData& gridData)
535 : ParentType(gridView)
536 {
537 static_assert(GridView::dimension == 1, "Porenetwork model only allow GridView::dimension == 1!");
538 update_(gridData);
539 }
540
543 const DofMapper& dofMapper() const
544 { return this->vertexMapper(); }
545
547 std::size_t numScv() const
548 { return numScv_; }
549
551 std::size_t numScvf() const
552 { return numScvf_; }
553
556 std::size_t numBoundaryScvf() const
557 { return 0; }
558
560 std::size_t numDofs() const
561 { return this->vertexMapper().size(); }
562
564 template<class GridData>
565 void update(const GridView& gridView, const GridData& gridData)
566 {
568 update_(gridData);
569 }
570
572 template<class GridData>
573 void update(GridView&& gridView, const GridData& gridData)
574 {
575 ParentType::update(std::move(gridView));
576 update_(gridData);
577 }
578
580 const FeCache& feCache() const
581 { return feCache_; }
582
584 const std::array<SubControlVolume, 2>& scvs(GridIndexType eIdx) const
585 { return scvs_[eIdx]; }
586
588 const std::array<SubControlVolumeFace, 1>& scvfs(GridIndexType eIdx) const
589 { return scvfs_[eIdx]; }
590
592 bool dofOnBoundary(GridIndexType dofIdx) const
593 { return boundaryDofIndices_[dofIdx]; }
594
596 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
597 { return false; }
598
600 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
601 { DUNE_THROW(Dune::NotImplemented, "Periodic boundaries"); }
602
604 std::unordered_map<GridIndexType, GridIndexType> periodicVertexMap() const
605 { return std::unordered_map<GridIndexType, GridIndexType>{}; }
606
608 bool hasBoundaryScvf(GridIndexType eIdx) const
609 { return hasBoundaryScvf_[eIdx]; }
610
611private:
612
613 template<class GridData>
614 void update_(const GridData& gridData)
615 {
616 PNMData::update(this->gridView(), gridData);
617
618 scvs_.clear();
619 scvfs_.clear();
620
621 auto numElements = this->gridView().size(0);
622 scvs_.resize(numElements);
623 scvfs_.resize(numElements);
624 hasBoundaryScvf_.resize(numElements, false);
625
626 boundaryDofIndices_.assign(numDofs(), false);
627
628 numScvf_ = numElements;
629 numScv_ = 2*numElements;
630
631 // Build the SCV and SCV faces
632 for (const auto& element : elements(this->gridView()))
633 {
634 // get the element geometry
635 auto eIdx = this->elementMapper().index(element);
636 auto elementGeometry = element.geometry();
637
638 // construct the sub control volumes
639 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
640 {
641 const auto dofIdxGlobal = this->vertexMapper().subIndex(element, scvLocalIdx, dim);
642
643 // get the corners
644 auto corners = std::array{elementGeometry.corner(scvLocalIdx), elementGeometry.center()};
645
646 // get the fractional volume associated with the scv
647 const auto volume = this->poreVolume(dofIdxGlobal) / this->coordinationNumber(dofIdxGlobal);
648
649 scvs_[eIdx][scvLocalIdx] = SubControlVolume(dofIdxGlobal,
650 scvLocalIdx,
651 eIdx,
652 std::move(corners),
653 volume);
654
655 if (this->poreLabel(dofIdxGlobal) > 0)
656 {
657 if (boundaryDofIndices_[dofIdxGlobal])
658 continue;
659
660 boundaryDofIndices_[dofIdxGlobal] = true;
661 hasBoundaryScvf_[eIdx] = true;
662 }
663 }
664
665 // construct the inner sub control volume face
666 auto unitOuterNormal = elementGeometry.corner(1)-elementGeometry.corner(0);
667 unitOuterNormal /= unitOuterNormal.two_norm();
668 LocalIndexType scvfLocalIdx = 0;
669 scvfs_[eIdx][0] = SubControlVolumeFace(elementGeometry.center(),
670 std::move(unitOuterNormal),
671 this->throatCrossSectionalArea(this->elementMapper().index(element)),
672 scvfLocalIdx++,
673 std::array<LocalIndexType, 2>({0, 1}));
674 }
675 }
676
677 const FeCache feCache_;
678
679 std::vector<std::array<SubControlVolume, 2>> scvs_;
680 std::vector<std::array<SubControlVolumeFace, 1>> scvfs_;
681
682 std::size_t numScv_;
683 std::size_t numScvf_;
684
685 // vertices on the boundary
686 std::vector<bool> boundaryDofIndices_;
687 std::vector<bool> hasBoundaryScvf_;
688};
689
696template<class Scalar, class GV, class Traits>
697class GridGeometry<Scalar, GV, false, Traits>
698: public BaseGridGeometry<GV, Traits>
699, public Traits::PNMData
700{
702 using ParentType = BaseGridGeometry<GV, Traits>;
703 using GridIndexType = typename IndexTraits<GV>::GridIndex;
704 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
705 using PNMData = typename Traits::PNMData;
706
707 static const int dim = GV::dimension;
708 static const int dimWorld = GV::dimensionworld;
709
710 using Element = typename GV::template Codim<0>::Entity;
711 using CoordScalar = typename GV::ctype;
712
713public:
717
719 using LocalView = typename Traits::template LocalView<ThisType, false>;
721 using SubControlVolume = typename Traits::SubControlVolume;
723 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
727 using DofMapper = typename Traits::VertexMapper;
729 using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
731 using GridView = GV;
732
734 template<class GridData>
735 GridGeometry(const GridView& gridView, const GridData& gridData)
736 : ParentType(gridView)
737 {
738 static_assert(GridView::dimension == 1, "Porenetwork model only allow GridView::dimension == 1!");
739 update_(gridData);
740 }
741
742
745 const DofMapper& dofMapper() const
746 { return this->vertexMapper(); }
747
749 std::size_t numScv() const
750 { return numScv_; }
751
753 std::size_t numScvf() const
754 { return numScvf_; }
755
758 std::size_t numBoundaryScvf() const
759 { return 0; }
760
762 std::size_t numDofs() const
763 { return this->vertexMapper().size(); }
764
766 template<class GridData>
767 void update(const GridView& gridView, const GridData& gridData)
768 {
770 update_(gridData);
771 }
772
774 template<class GridData>
775 void update(GridView&& gridView, const GridData& gridData)
776 {
777 ParentType::update(std::move(gridView));
778 update_(gridData);
779 }
780
782 const FeCache& feCache() const
783 { return feCache_; }
784
786 bool dofOnBoundary(GridIndexType dofIdx) const
787 { return boundaryDofIndices_[dofIdx]; }
788
790 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
791 { return false; }
792
794 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
795 { DUNE_THROW(Dune::NotImplemented, "Periodic boundaries"); }
796
798 std::unordered_map<GridIndexType, GridIndexType> periodicVertexMap() const
799 { return std::unordered_map<GridIndexType, GridIndexType>{}; }
800
801private:
802
803 template<class GridData>
804 void update_(const GridData& gridData)
805 {
806 PNMData::update(this->gridView(), gridData);
807
808 boundaryDofIndices_.assign(numDofs(), false);
809
810 // save global data on the grid's scvs and scvfs
811 numScvf_ = this->gridView().size(0);
812 numScv_ = 2*numScvf_;
813
814 for (const auto& element : elements(this->gridView()))
815 {
816 // treat boundaries
817 for (LocalIndexType vIdxLocal = 0; vIdxLocal < 2; ++vIdxLocal)
818 {
819 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdxLocal, dim);
820 if (this->poreLabel(vIdxGlobal) > 0)
821 {
822 if (boundaryDofIndices_[vIdxGlobal])
823 continue;
824
825 boundaryDofIndices_[vIdxGlobal] = true;
826 }
827 }
828 }
829 }
830
831 const FeCache feCache_;
832
833 // Information on the global number of geometries
834 std::size_t numScv_;
835 std::size_t numScvf_;
836
837 // vertices on the boundary
838 std::vector<bool> boundaryDofIndices_;
839};
840
841} // end namespace Dumux::PoreNetwork
842
843#endif
Defines the default element and vertex mapper types.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Defines the index types used for grid and local indices.
Base class for grid geometries.
Helper classes to compute the integration elements.
The available discretization methods in Dumux.
This file contains functions related to calculate pore-body properties.
This file contains functions related to calculate pore-throat properties.
auto volume(const Geometry &geo, unsigned int integrationOrder=4)
The volume of a given geometry.
Definition volume.hh:171
BaseGridGeometry(std::shared_ptr< BaseImplementation > impl)
Constructor from a BaseImplementation.
Definition basegridgeometry.hh:81
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:161
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:177
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:251
CVFE< CVFEMethods::PQ1 > Box
Definition method.hh:83
Definition discretization/porenetwork/fvelementgeometry.hh:34
Shape shapeFromString(const std::string &s)
Get the shape from a string description of the shape.
Definition poreproperties.hh:56
Scalar volume(Shape shape, Scalar inscribedRadius)
Returns the volume of a given geometry based on the inscribed radius.
Definition poreproperties.hh:73
Shape
Collection of different pore-body shapes.
Definition poreproperties.hh:35
@ cylinder
Definition poreproperties.hh:35
constexpr Scalar totalCrossSectionalAreaForRectangle(const Scalar inscribedRadius, const Scalar height) noexcept
Returns the cross-sectional area of a rectangle.
Definition throatproperties.hh:226
constexpr Shape shape(const Scalar shapeFactor) noexcept
Returns the shape for a given shape factor.
Definition throatproperties.hh:177
constexpr Scalar shapeFactorRectangle(const Scalar inscribedRadius, const Scalar height) noexcept
Returns the value of the shape factor for a rectangle.
Definition throatproperties.hh:144
Scalar totalCrossSectionalArea(const Shape shape, const Scalar inscribedRadius)
Returns the cross-sectional area of a given geometry.
Definition throatproperties.hh:211
Shape shapeFromString(const std::string &s)
Get the shape from a string description of the shape.
Definition throatproperties.hh:57
Shape
Collection of different pore-throat shapes.
Definition throatproperties.hh:38
@ scaleneTriangle
Definition throatproperties.hh:38
@ rectangle
Definition throatproperties.hh:38
@ polygon
Definition throatproperties.hh:38
Scalar shapeFactor(Shape shape, const Scalar inscribedRadius)
Returns the value of the shape factor for a given shape.
Definition throatproperties.hh:162
typename GridView::IndexSet::IndexType GridIndex
Definition indextraits.hh:39
std::uint_least8_t SmallLocalIndex
Definition indextraits.hh:41
unsigned int LocalIndex
Definition indextraits.hh:40
const VertexMapper & vertexMapper() const
Returns the mapper for vertices to indices for constant grids.
Definition basegridgeometry.hh:115
const GridView & gridView() const
Return the gridView this grid geometry object lives on.
Definition basegridgeometry.hh:109
void update(const GridView &gridView)
Update all fvElementGeometries (call this after grid adaption).
Definition basegridgeometry.hh:97
Base class for the local geometry for porenetworks.
Definition discretization/porenetwork/fvelementgeometry.hh:43
Base class for geometry data extraction from the grid data format.
Definition discretization/porenetwork/gridgeometry.hh:56
Scalar throatCrossSectionalArea(const GridIndex eIdx) const
Returns the throat's cross-sectional area.
Definition discretization/porenetwork/gridgeometry.hh:300
const std::vector< Scalar > & poreVolume() const
Returns the vector of pore volumes.
Definition discretization/porenetwork/gridgeometry.hh:228
const std::vector< Scalar > & throatInscribedRadius() const
Returns the vector of inscribed throat radii.
Definition discretization/porenetwork/gridgeometry.hh:236
bool useSameGeometryForAllPores() const
Returns whether all pores feature the same shape.
Definition discretization/porenetwork/gridgeometry.hh:326
const std::vector< Label > & poreLabel() const
Returns the vector of pore labels.
Definition discretization/porenetwork/gridgeometry.hh:212
bool useSameShapeForAllThroats() const
Returns whether all throats feature the same cross-sectional shape.
Definition discretization/porenetwork/gridgeometry.hh:330
SmallLocalIndex coordinationNumber(const GridIndex dofIdxGlobal) const
Returns the number of throats connected to a pore (coordination number).
Definition discretization/porenetwork/gridgeometry.hh:256
void update(const GridView &gridView, const GridData &gridData)
Definition discretization/porenetwork/gridgeometry.hh:68
const std::vector< SmallLocalIndex > & coordinationNumber() const
Returns the vector of coordination numbers.
Definition discretization/porenetwork/gridgeometry.hh:260
const std::vector< Scalar > & throatShapeFactor() const
Returns the vector of throat shape factors.
Definition discretization/porenetwork/gridgeometry.hh:312
const std::vector< Scalar > & throatCrossSectionalArea() const
Returns the vector of throat cross-sectional areas.
Definition discretization/porenetwork/gridgeometry.hh:304
Pore::Shape poreGeometry(const GridIndex vIdx) const
the geometry of the pore
Definition discretization/porenetwork/gridgeometry.hh:264
Throat::Shape throatCrossSectionShape(const GridIndex eIdx) const
Returns the throat's cross-sectional shape.
Definition discretization/porenetwork/gridgeometry.hh:282
Label throatLabel(const GridIndex eIdx) const
Returns an index indicating if a throat is touching the domain boundary.
Definition discretization/porenetwork/gridgeometry.hh:248
const std::vector< Label > & throatLabel() const
Returns the vector of throat labels.
Definition discretization/porenetwork/gridgeometry.hh:252
Scalar throatLength(const GridIndex eIdx) const
Returns the length of the throat.
Definition discretization/porenetwork/gridgeometry.hh:240
const std::vector< Throat::Shape > & throatCrossSectionShape() const
Returns the vector of cross-sectional shapes.
Definition discretization/porenetwork/gridgeometry.hh:286
Scalar poreVolume(const GridIndex dofIdxGlobal) const
Returns the volume of the pore.
Definition discretization/porenetwork/gridgeometry.hh:224
Scalar throatInscribedRadius(const GridIndex eIdx) const
Returns the inscribed radius of the throat.
Definition discretization/porenetwork/gridgeometry.hh:232
Label poreLabel(const GridIndex dofIdxGlobal) const
Returns the pore label (e.g. used for setting BCs).
Definition discretization/porenetwork/gridgeometry.hh:208
Scalar poreInscribedRadius(const GridIndex dofIdxGlobal) const
Returns the inscribed radius of the pore.
Definition discretization/porenetwork/gridgeometry.hh:216
const std::vector< Scalar > & throatLength() const
Returns the vector of throat lengths.
Definition discretization/porenetwork/gridgeometry.hh:244
const std::vector< Pore::Shape > & poreGeometry() const
Returns the vector of pore geometries.
Definition discretization/porenetwork/gridgeometry.hh:268
Scalar throatShapeFactor(const GridIndex eIdx) const
Returns the throat's shape factor.
Definition discretization/porenetwork/gridgeometry.hh:308
const std::vector< Scalar > & poreInscribedRadius() const
Returns the vector of inscribed pore radii.
Definition discretization/porenetwork/gridgeometry.hh:220
The default traits.
Definition discretization/porenetwork/gridgeometry.hh:470
PNMFVElementGeometry< GridGeometry, enableCache > LocalView
Definition discretization/porenetwork/gridgeometry.hh:475
PNMSubControlVolume< GridView > SubControlVolume
Definition discretization/porenetwork/gridgeometry.hh:471
DefaultPNMData< typename SubControlVolume::Traits::Scalar, GridView > PNMData
Definition discretization/porenetwork/gridgeometry.hh:477
PNMSubControlVolumeFace< GridView > SubControlVolumeFace
Definition discretization/porenetwork/gridgeometry.hh:472
Base class for the finite volume geometry for porenetwork models.
Definition discretization/porenetwork/gridgeometry.hh:489
Dune::LagrangeLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
export the finite element cache type
Definition discretization/porenetwork/gridgeometry.hh:528
std::size_t numDofs() const
The total number of degrees of freedom.
Definition discretization/porenetwork/gridgeometry.hh:560
const std::array< SubControlVolume, 2 > & scvs(GridIndexType eIdx) const
Get the local scvs for an element.
Definition discretization/porenetwork/gridgeometry.hh:584
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:600
DiscretizationMethods::Box DiscretizationMethod
export the discretization method this geometry belongs to
Definition discretization/porenetwork/gridgeometry.hh:514
std::unordered_map< GridIndexType, GridIndexType > periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition discretization/porenetwork/gridgeometry.hh:604
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition discretization/porenetwork/gridgeometry.hh:522
const DofMapper & dofMapper() const
Definition discretization/porenetwork/gridgeometry.hh:543
std::size_t numScv() const
The total number of sub control volumes.
Definition discretization/porenetwork/gridgeometry.hh:547
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on a periodic boundary (not implemented).
Definition discretization/porenetwork/gridgeometry.hh:596
bool dofOnBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition discretization/porenetwork/gridgeometry.hh:592
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition discretization/porenetwork/gridgeometry.hh:520
typename Traits::template LocalView< ThisType, true > LocalView
export the type of the fv element geometry (the local view type)
Definition discretization/porenetwork/gridgeometry.hh:518
GV GridView
export the grid view type
Definition discretization/porenetwork/gridgeometry.hh:530
std::size_t numScvf() const
The total number of sun control volume faces.
Definition discretization/porenetwork/gridgeometry.hh:551
Extrusion_t< Traits > Extrusion
export the type of extrusion
Definition discretization/porenetwork/gridgeometry.hh:524
const std::array< SubControlVolumeFace, 1 > & scvfs(GridIndexType eIdx) const
Get the local scvfs for an element.
Definition discretization/porenetwork/gridgeometry.hh:588
std::size_t numBoundaryScvf() const
Definition discretization/porenetwork/gridgeometry.hh:556
void update(const GridView &gridView, const GridData &gridData)
update all fvElementGeometries (call this after grid adaption)
Definition discretization/porenetwork/gridgeometry.hh:565
static constexpr DiscretizationMethod discMethod
Definition discretization/porenetwork/gridgeometry.hh:515
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition discretization/porenetwork/gridgeometry.hh:580
typename Traits::VertexMapper DofMapper
export dof mapper type
Definition discretization/porenetwork/gridgeometry.hh:526
bool hasBoundaryScvf(GridIndexType eIdx) const
Returns whether one of the geometry's scvfs lies on a boundary.
Definition discretization/porenetwork/gridgeometry.hh:608
GridGeometry(const GridView &gridView, const GridData &gridData)
Constructor.
Definition discretization/porenetwork/gridgeometry.hh:534
void update(GridView &&gridView, const GridData &gridData)
update all fvElementGeometries (call this after grid adaption)
Definition discretization/porenetwork/gridgeometry.hh:573
bool dofOnBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition discretization/porenetwork/gridgeometry.hh:786
Dune::LagrangeLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
export the finite element cache type
Definition discretization/porenetwork/gridgeometry.hh:729
static constexpr DiscretizationMethod discMethod
Definition discretization/porenetwork/gridgeometry.hh:716
std::size_t numDofs() const
The total number of degrees of freedom.
Definition discretization/porenetwork/gridgeometry.hh:762
std::size_t numBoundaryScvf() const
Definition discretization/porenetwork/gridgeometry.hh:758
void update(GridView &&gridView, const GridData &gridData)
update all fvElementGeometries (call this after grid adaption)
Definition discretization/porenetwork/gridgeometry.hh:775
void update(const GridView &gridView, const GridData &gridData)
update all fvElementGeometries (call this after grid adaption)
Definition discretization/porenetwork/gridgeometry.hh:767
std::size_t numScv() const
The total number of sub control volumes.
Definition discretization/porenetwork/gridgeometry.hh:749
typename Traits::VertexMapper DofMapper
export dof mapper type
Definition discretization/porenetwork/gridgeometry.hh:727
GridGeometry(const GridView &gridView, const GridData &gridData)
Constructor.
Definition discretization/porenetwork/gridgeometry.hh:735
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition discretization/porenetwork/gridgeometry.hh:782
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition discretization/porenetwork/gridgeometry.hh:723
std::unordered_map< GridIndexType, GridIndexType > periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition discretization/porenetwork/gridgeometry.hh:798
Extrusion_t< Traits > Extrusion
export the type of extrusion
Definition discretization/porenetwork/gridgeometry.hh:725
std::size_t numScvf() const
The total number of sun control volume faces.
Definition discretization/porenetwork/gridgeometry.hh:753
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition discretization/porenetwork/gridgeometry.hh:721
typename Traits::template LocalView< ThisType, false > LocalView
export the type of the fv element geometry (the local view type)
Definition discretization/porenetwork/gridgeometry.hh:719
const DofMapper & dofMapper() const
Definition discretization/porenetwork/gridgeometry.hh:745
GV GridView
export the grid view type
Definition discretization/porenetwork/gridgeometry.hh:731
DiscretizationMethods::Box DiscretizationMethod
export the discretization method this geometry belongs to
Definition discretization/porenetwork/gridgeometry.hh:715
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:794
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on a periodic boundary (not implemented).
Definition discretization/porenetwork/gridgeometry.hh:790
the sub control volume for porenetworks
Definition discretization/porenetwork/subcontrolvolume.hh:65
Class for a sub control volume face for porenetworks.
Definition discretization/porenetwork/subcontrolvolumeface.hh:62
Class for grid data attached to dgf or gmsh grid files.
Definition griddata.hh:66
double getParameter(const Element &element, const std::string &fieldName) const
Get a element parameter.
Definition griddata.hh:252
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:112
Class for grid data attached to dgf or gmsh grid files.
Definition porenetwork/griddata.hh:56
bool gridHasElementParameter(const std::string &param) const
Return if a given element parameter is provided by the grid.
Definition porenetwork/griddata.hh:266
std::vector< SmallLocalIndex > getCoordinationNumbers() const
Returns the coordination numbers for all pore bodies.
Definition porenetwork/griddata.hh:151
int parameterIndex(const std::string &paramName) const
Return the index for a given parameter name.
Definition porenetwork/griddata.hh:234
const std::string & paramGroup() const
Return the parameter group.
Definition porenetwork/griddata.hh:260
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:98
Base class for the local geometry for porenetworks.
the sub control volume for pore networks
Base class for a sub control volume face.