3.5-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
Loading...
Searching...
No Matches
couplingmanager1d3d_projection.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 *****************************************************************************/
26
27#ifndef DUMUX_MULTIDOMAIN_EMBEDDED_COUPLINGMANAGER_1D3D_PROJECTION_HH
28#define DUMUX_MULTIDOMAIN_EMBEDDED_COUPLINGMANAGER_1D3D_PROJECTION_HH
29
30#include <vector>
31#include <algorithm>
32#include <string>
33
34#include <dune/common/timer.hh>
35#include <dune/common/exceptions.hh>
36#include <dune/common/fvector.hh>
37#include <dune/geometry/quadraturerules.hh>
38
39#include <dumux/common/tag.hh>
41#include <dumux/common/math.hh>
43
47
50
51namespace Dumux {
52
53// some implementation details of the projection coupling manager
54namespace Detail {
55
64template <class GridGeometry>
66{
67 using GridView = typename GridGeometry::GridView;
68 using GlobalPosition = typename GridView::template Codim<0>::Geometry::GlobalCoordinate;
69 using GridIndex = typename IndexTraits<GridView>::GridIndex;
70
71 struct Segment
72 {
73 GlobalPosition a, b;
74 double r;
75 GridIndex eIdx;
76 };
77
78public:
79 template <class RadiusFunction>
80 SegmentNetwork(const GridGeometry& gg, const RadiusFunction& radiusFunction)
81 {
82 const auto& gridView = gg.gridView();
83 segments_.resize(gridView.size(0));
84 for (const auto &element : elements(gridView))
85 {
86 const auto geometry = element.geometry();
87 const auto eIdx = gg.elementMapper().index(element);
88 const auto radius = radiusFunction(eIdx);
89
90 segments_[eIdx] = Segment{ geometry.corner(0), geometry.corner(1), radius, eIdx };
91 }
92
93 std::cout << "-- Extracted " << segments_.size() << " segments.\n";
94 }
95
97 auto radius(std::size_t eIdx) const
98 { return segments_[eIdx].r; }
99
101 const auto& segment(std::size_t eIdx) const
102 { return segments_[eIdx]; }
103
105 const auto& segments() const
106 { return segments_; }
107
110 auto findClosestSegmentSurface(const GlobalPosition& globalPos) const
111 {
112 GridIndex eIdx = 0;
113 double minSignedDist = std::numeric_limits<double>::max();
114
115 for (const auto &segment : segments_)
116 {
117 const auto signedDist = computeSignedDistance_(globalPos, segment);
118 if (signedDist < minSignedDist)
119 {
120 minSignedDist = signedDist;
121 eIdx = segment.eIdx;
122 }
123 }
124
125 using std::abs;
126 return std::make_tuple(eIdx, abs(minSignedDist));
127 }
128
130 template <class IndexRange>
131 auto findClosestSegmentSurface(const GlobalPosition& globalPos,
132 const IndexRange& segIndices) const
133 {
134 GridIndex eIdx = 0;
135 double minSignedDist = std::numeric_limits<double>::max();
136
137 for (const auto index : segIndices)
138 {
139 const auto &segment = segments_[index];
140 const auto signedDist = computeSignedDistance_(globalPos, segment);
141 if (signedDist < minSignedDist)
142 {
143 minSignedDist = signedDist;
144 eIdx = segment.eIdx;
145 }
146 }
147
148 using std::abs;
149 return std::make_tuple(eIdx, abs(minSignedDist));
150 }
151
152 // Compute the projection point of p onto the segment connecting a->b
153 GlobalPosition projectionPointOnSegment(const GlobalPosition& p, std::size_t idx) const
154 {
155 const auto& segment = segments_[idx];
156 return projectionPointOnSegment_(p, segment.a, segment.b);
157 }
158
159private:
160 // Compute the projection of p onto the segment
161 // returns the closest end point if the orthogonal projection onto the line implied by the segment
162 // is outside the segment
163 GlobalPosition projectionPointOnSegment_(const GlobalPosition& p, const GlobalPosition& a, const GlobalPosition& b) const
164 {
165 const auto v = b - a;
166 const auto w = p - a;
167
168 const auto proj1 = v*w;
169 if (proj1 <= 0.0)
170 return a;
171
172 const auto proj2 = v.two_norm2();
173 if (proj2 <= proj1)
174 return b;
175
176 const auto t = proj1 / proj2;
177 auto x = a;
178 x.axpy(t, v);
179 return x;
180 }
181
182 // Compute the signed (!) distance to a cylinder segment surface and the projection point onto the centerline
183 auto computeSignedDistance_(const GlobalPosition& p, const Segment& segment) const
184 {
185 const auto projPoint = projectionPointOnSegment_(p, segment.a, segment.b);
186 return (p-projPoint).two_norm()-segment.r;
187 }
188
189 std::vector<Segment> segments_;
190};
191
198template<class Network>
200{
201public:
202 NetworkIndicatorFunction(const Network& n)
203 : network_(n)
204 {}
205
206 template<class Pos>
207 auto operator()(const Pos& pos) const
208 {
209 const auto& [closestSegmentIdx, _] = network_.findClosestSegmentSurface(pos);
210 return closestSegmentIdx;
211 }
212
213 template <class Pos, class HintContainer>
214 auto operator()(const Pos& pos, const HintContainer& hints) const
215 {
216 const auto& [closestSegmentIdx, _] = network_.findClosestSegmentSurface(pos, hints);
217 return closestSegmentIdx;
218 }
219
220private:
221 const Network& network_;
222};
223
229{
230public:
231 void push(const std::array<Dune::FieldVector<double, 3>, 3>& corners, double data)
232 {
233 vtkCells_.emplace_back(std::array<std::size_t, 3>{
234 { vtkPoints_.size(), vtkPoints_.size()+1, vtkPoints_.size()+2 }
235 });
236 for (const auto& c : corners)
237 vtkPoints_.push_back(c);
238 vtkCellData_.push_back(data);
239 }
240
241 void write(const std::string& name)
242 {
243 std::ofstream intersectionFile(name);
244 intersectionFile << "# vtk DataFile Version 2.0\n";
245 intersectionFile << "Really cool intersection data\n";
246 intersectionFile << "ASCII\n";
247 intersectionFile << "DATASET UNSTRUCTURED_GRID\n";
248 intersectionFile << "POINTS " << vtkPoints_.size() << " float\n";
249 for (const auto& p : vtkPoints_)
250 intersectionFile << p[0] << " " << p[1] << " " << p[2] << "\n";
251 intersectionFile << "\nCELLS " << vtkCells_.size() << " " << vtkCells_.size()*4 << "\n";
252 for (const auto& c : vtkCells_)
253 intersectionFile << "3 " << c[0] << " " << c[1] << " " << c[2] << "\n";
254 intersectionFile << "\nCELL_TYPES " << vtkCells_.size() << "\n";
255 for (int i = 0; i < vtkCells_.size(); ++i)
256 intersectionFile << "5\n";
257 intersectionFile << "\nCELL_DATA " << vtkCells_.size() << "\nSCALARS index float\nLOOKUP_TABLE default\n";
258 for (const auto& c : vtkCellData_)
259 intersectionFile << c << "\n";
260 }
261
262private:
263 std::vector<Dune::FieldVector<double, 3>> vtkPoints_;
264 std::vector<std::array<std::size_t, 3>> vtkCells_;
265 std::vector<double> vtkCellData_;
266};
267
268} // end namespace Detail
269
270namespace Embedded1d3dCouplingMode {
271struct Projection : public Utility::Tag<Projection> {
272 static std::string name() { return "projection"; }
273};
274
275inline constexpr Projection projection{};
276} // end namespace Embedded1d3dCouplingMode
277
278// forward declaration
279template<class MDTraits, class CouplingMode>
280class Embedded1d3dCouplingManager;
281
330template<class MDTraits>
332: public EmbeddedCouplingManagerBase<MDTraits, Embedded1d3dCouplingManager<MDTraits, Embedded1d3dCouplingMode::Projection>>
333{
336
337 using Scalar = typename MDTraits::Scalar;
338 using SolutionVector = typename MDTraits::SolutionVector;
339 using PointSourceData = typename ParentType::PointSourceTraits::PointSourceData;
340
341 static constexpr auto bulkIdx = typename MDTraits::template SubDomain<0>::Index();
342 static constexpr auto lowDimIdx = typename MDTraits::template SubDomain<1>::Index();
343
344 // the sub domain type aliases
345 template<std::size_t id> using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
346 template<std::size_t id> using Problem = GetPropType<SubDomainTypeTag<id>, Properties::Problem>;
347 template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
348 template<std::size_t id> using GridView = typename GridGeometry<id>::GridView;
349 template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity;
350 template<std::size_t id> using GridIndex = typename IndexTraits<GridView<id>>::GridIndex;
351
352 static constexpr int lowDimDim = GridView<lowDimIdx>::dimension;
353 static constexpr int bulkDim = GridView<bulkIdx>::dimension;
354 static constexpr int dimWorld = GridView<bulkIdx>::dimensionworld;
355
356 template<std::size_t id>
357 static constexpr bool isBox()
358 { return GridGeometry<id>::discMethod == DiscretizationMethods::box; }
359
360 using GlobalPosition = typename Element<bulkIdx>::Geometry::GlobalCoordinate;
361
363
364public:
366
367 using ParentType::ParentType;
368
369 void init(std::shared_ptr<Problem<bulkIdx>> bulkProblem,
370 std::shared_ptr<Problem<lowDimIdx>> lowDimProblem,
371 const SolutionVector& curSol)
372 {
373 ParentType::init(bulkProblem, lowDimProblem, curSol);
374 }
375
376 /* \brief Compute integration point point sources and associated data
377 * This method computes a source term on the explicitly given surface of the network grid
378 * by integrating over the elements of the surface, projecting the integration points onto
379 * the centerlines to evaluate 1d quantities and set point sources (minimum distance projection)
380 *
381 * \param order Unused in this algorithm! (passed from default 1D3D coupling manager)
382 * \param verbose If the source computation is verbose
383 */
384 void computePointSourceData(std::size_t order = 1, bool verbose = false)
385 {
386 // initialize the maps
387 // do some logging and profiling
388 Dune::Timer watch;
389 std::cout << "Initializing the coupling manager (projection)" << std::endl;
390
391 // debug VTK output
392 const bool enableIntersectionOutput = getParam<bool>("MixedDimension.Projection.EnableIntersectionOutput", false);
393 std::unique_ptr<Detail::DebugIntersectionVTKOutput> vtkCoupledFaces =
394 enableIntersectionOutput ? std::make_unique<Detail::DebugIntersectionVTKOutput>() : nullptr;
395 std::unique_ptr<Detail::DebugIntersectionVTKOutput> vtkIntersections =
396 enableIntersectionOutput ? std::make_unique<Detail::DebugIntersectionVTKOutput>() : nullptr;
397
398 // temporarily represent the network domain as a list of segments
399 // a more efficient data structure
400 const auto& lowDimProblem = this->problem(lowDimIdx);
401 const auto& lowDimFvGridGeometry = lowDimProblem.gridGeometry();
402 const auto& lowDimGridView = lowDimFvGridGeometry.gridView();
403 localAreaFactor_.resize(lowDimGridView.size(0), 0.0);
404 const auto radiusFunc = [&](const GridIndex<lowDimIdx> eIdx) {
405 return lowDimProblem.spatialParams().radius(eIdx);
406 };
407 const auto network = SegmentNetwork{
408 lowDimFvGridGeometry, radiusFunc
409 };
410
411 // precompute the vertex indices for efficiency (box method)
412 this->precomputeVertexIndices(bulkIdx);
413 this->precomputeVertexIndices(lowDimIdx);
414
415 const auto& bulkProblem = this->problem(bulkIdx);
416 const auto& bulkFvGridGeometry = bulkProblem.gridGeometry();
417 const auto& bulkGridView = bulkFvGridGeometry.gridView();
418 bulkElementMarker_.assign(bulkGridView.size(0), 0);
419 bulkVertexMarker_.assign(bulkGridView.size(bulkDim), 0);
420
421 // construct a bounding box that may be used to determine coupled faces
422 // the shrinking factor shrinks this bounding box
423 static const auto bBoxShrinking
424 = getParam<Scalar>("MixedDimension.Projection.CoupledBoundingBoxShrinkingFactor", 1e-2);
425 const GlobalPosition threshold(
426 bBoxShrinking*( bulkFvGridGeometry.bBoxMax()-bulkFvGridGeometry.bBoxMin() ).two_norm()
427 );
428 const auto bBoxMinSmall = bulkFvGridGeometry.bBoxMin() + threshold;
429 const auto bBoxMaxSmall = bulkFvGridGeometry.bBoxMax() - threshold;
430 auto insideBBox = [bBoxMin=bBoxMinSmall, bBoxMax=bBoxMaxSmall](const GlobalPosition& point) -> bool
431 {
432 static constexpr Scalar eps_ = 1.0e-7;
433 const Scalar eps0 = eps_*(bBoxMax[0] - bBoxMin[0]);
434 const Scalar eps1 = eps_*(bBoxMax[1] - bBoxMin[1]);
435 const Scalar eps2 = eps_*(bBoxMax[2] - bBoxMin[2]);
436 return (bBoxMin[0] - eps0 <= point[0] && point[0] <= bBoxMax[0] + eps0 &&
437 bBoxMin[1] - eps1 <= point[1] && point[1] <= bBoxMax[1] + eps1 &&
438 bBoxMin[2] - eps2 <= point[2] && point[2] <= bBoxMax[2] + eps2);
439 };
440
441 // setup simplex "quadrature" rule
442 static const auto quadSimplexRefineMaxLevel
443 = getParam<std::size_t>("MixedDimension.Projection.SimplexIntegrationRefine", 4);
444 const auto indicator = Detail::NetworkIndicatorFunction { network };
445
446 // estimate number of point sources for memory allocation
447 static const auto estimateNumberOfPointSources
448 = getParam<std::size_t>("MixedDimension.Projection.EstimateNumberOfPointSources", bulkFvGridGeometry.gridView().size(0));
449
450 this->pointSources(bulkIdx).reserve(estimateNumberOfPointSources);
451 this->pointSources(lowDimIdx).reserve(estimateNumberOfPointSources);
452 this->pointSourceData().reserve(estimateNumberOfPointSources);
453
454 // we go over the bulk surface intersection, check if we are coupled,
455 // and if this is the case, we add integration point sources using
456 // the local simplex refinement quadrature procedure (see paper Koch 2021)
457 for (const auto& element : elements(bulkGridView))
458 {
459 const auto bulkElementIdx = bulkFvGridGeometry.elementMapper().index(element);
460 const auto bulkGeometry = element.geometry();
461 const auto refElement = Dune::referenceElement(element);
462 for (const auto& intersection : intersections(bulkGridView, element))
463 {
464 // skip inner intersection
465 if (!intersection.boundary())
466 continue;
467
468 // check if we are close enough to the coupling interface
469 const auto [isCoupled, closestSegmentIdx, minDist] = isCoupled_(network, intersection, insideBBox);
470 if (!isCoupled)
471 continue;
472
473 // we found an intersection on the coupling interface: mark as coupled element
474 bulkElementMarker_[bulkElementIdx] = 1;
475
476 const auto interfaceGeometry = intersection.geometry();
477 for (int i = 0; i < interfaceGeometry.corners(); ++i)
478 {
479 const auto localVIdx = refElement.subEntity(intersection.indexInInside(), 1, i, bulkDim);
480 const auto vIdx = bulkFvGridGeometry.vertexMapper().subIndex(element, localVIdx, bulkDim);
481 bulkVertexMarker_[vIdx] = 1;
482 }
483
484 // debug graphical intersection output
485 if (enableIntersectionOutput)
486 vtkCoupledFaces->push({
487 { interfaceGeometry.corner(0), interfaceGeometry.corner(1), interfaceGeometry.corner(2)}
488 }, closestSegmentIdx);
489
490 const auto quadSimplex = LocalRefinementSimplexQuadrature{ interfaceGeometry, quadSimplexRefineMaxLevel, indicator };
491
492 // iterate over all quadrature points (children simplices)
493 for (const auto& qp : quadSimplex)
494 {
495 const auto surfacePoint = interfaceGeometry.global(qp.position());
496 const auto closestSegmentIdx = qp.indicator();
497 const auto projPoint = network.projectionPointOnSegment(surfacePoint, closestSegmentIdx);
498
499 addPointSourceAtIP_(bulkGeometry, interfaceGeometry, qp, bulkElementIdx, closestSegmentIdx, surfacePoint, projPoint);
500 addStencilEntries_(bulkElementIdx, closestSegmentIdx);
501 }
502 }
503 }
504
505 // make stencils unique
506 using namespace Dune::Hybrid;
507 forEach(integralRange(Dune::index_constant<2>{}), [&](const auto domainIdx)
508 {
509 for (auto&& stencil : this->couplingStencils(domainIdx))
510 {
511 std::sort(stencil.second.begin(), stencil.second.end());
512 stencil.second.erase(
513 std::unique(stencil.second.begin(), stencil.second.end()),
514 stencil.second.end()
515 );
516 }
517 });
518
519 // debug VTK output
520 if (enableIntersectionOutput)
521 vtkCoupledFaces->write("coupledfaces.vtk");
522
523 // compare theoretical cylinder surface to actual discrete surface
524 // of the coupled bulk interface facets
525 for (const auto& element : elements(lowDimGridView))
526 {
527 const auto length = element.geometry().volume();
528 const auto eIdx = lowDimFvGridGeometry.elementMapper().index(element);
529 const auto radius = this->problem(lowDimIdx).spatialParams().radius(eIdx);
530 const auto cylinderSurface = 2.0*M_PI*radius*length;
531 localAreaFactor_[eIdx] /= cylinderSurface;
532 localAreaFactor_[eIdx] -= 1.0;
533 }
534
535 this->pointSources(bulkIdx).shrink_to_fit();
536 this->pointSources(lowDimIdx).shrink_to_fit();
537 this->pointSourceData().shrink_to_fit();
538
539 std::cout << "-- Coupling at " << this->pointSourceData().size() << " integration points." << std::endl;
540 std::cout << "-- Finished initialization after " << watch.elapsed() << " seconds." << std::endl;
541 }
542
546 // \{
547
549 Scalar radius(std::size_t id) const
550 {
551 const auto& data = this->pointSourceData()[id];
552 return this->problem(lowDimIdx).spatialParams().radius(data.lowDimElementIdx());
553 }
554
555 // \}
556
558 const std::vector<int>& bulkElementMarker() const
559 { return bulkElementMarker_; }
560
562 const std::vector<int>& bulkVertexMarker() const
563 { return bulkVertexMarker_; }
564
568 const std::vector<Scalar>& localAreaFactor() const
569 { return localAreaFactor_; }
570
571private:
572 std::vector<int> bulkElementMarker_, bulkVertexMarker_;
573 std::vector<double> localAreaFactor_;
574
575 // add a point source containing all data needed to evaluate
576 // the coupling source term from both domains
577 template<class BulkGeometry, class InterfaceGeometry, class QP>
578 void addPointSourceAtIP_(const BulkGeometry& bulkGeometry,
579 const InterfaceGeometry& ifGeometry,
580 const QP& qp,
581 const GridIndex<bulkIdx> bulkElementIdx,
582 const GridIndex<lowDimIdx> lowDimElementIdx,
583 const GlobalPosition& surfacePoint,
584 const GlobalPosition& projPoint)
585 {
586 // add a new point source id (for the associated data)
587 const auto id = this->idCounter_++;
588
589 // add a bulk point source
590 const auto qpweight = qp.weight();
591 const auto integrationElement = ifGeometry.integrationElement(qp.position());
592 this->pointSources(bulkIdx).emplace_back(surfacePoint, id, qpweight, integrationElement, bulkElementIdx);
593
594 // find the corresponding projection point and 1d element
595 this->pointSources(lowDimIdx).emplace_back(projPoint, id, qpweight, integrationElement, lowDimElementIdx);
596 localAreaFactor_[lowDimElementIdx] += qpweight*integrationElement;
597
598 const auto& bulkFvGridGeometry = this->problem(bulkIdx).gridGeometry();
599 const auto& lowDimFvGridGeometry = this->problem(lowDimIdx).gridGeometry();
600
601 // pre compute additional data used for the evaluation of
602 // the actual solution dependent source term
603 PointSourceData psData;
604
605 if constexpr (isBox<lowDimIdx>())
606 {
607 std::vector<Dune::FieldVector<Scalar, 1> > shapeValues;
608 const auto lowDimGeometry = this->problem(lowDimIdx).gridGeometry().element(lowDimElementIdx).geometry();
609 this->getShapeValues(lowDimIdx, lowDimFvGridGeometry, lowDimGeometry, projPoint, shapeValues);
610 psData.addLowDimInterpolation(shapeValues, this->vertexIndices(lowDimIdx, lowDimElementIdx), lowDimElementIdx);
611 }
612 else
613 {
614 psData.addLowDimInterpolation(lowDimElementIdx);
615 }
616
617 if constexpr (isBox<bulkIdx>())
618 {
619 std::vector<Dune::FieldVector<Scalar, 1> > shapeValues;
620 this->getShapeValues(bulkIdx, bulkFvGridGeometry, bulkGeometry, surfacePoint, shapeValues);
621 psData.addBulkInterpolation(shapeValues, this->vertexIndices(bulkIdx, bulkElementIdx), bulkElementIdx);
622 }
623 else
624 {
625 psData.addBulkInterpolation(bulkElementIdx);
626 }
627
628 // publish point source data in the global vector
629 this->pointSourceData().emplace_back(std::move(psData));
630 }
631
632 void addStencilEntries_(const GridIndex<bulkIdx> bulkElementIdx, const GridIndex<lowDimIdx> lowDimElementIdx)
633 {
634 // export the bulk coupling stencil
635 if constexpr (isBox<lowDimIdx>())
636 {
637 const auto& vertices = this->vertexIndices(lowDimIdx, lowDimElementIdx);
638 this->couplingStencils(bulkIdx)[bulkElementIdx].insert(
639 this->couplingStencils(bulkIdx)[bulkElementIdx].end(),
640 vertices.begin(), vertices.end()
641 );
642
643 }
644 else
645 {
646 this->couplingStencils(bulkIdx)[bulkElementIdx].push_back(lowDimElementIdx);
647 }
648
649 // export the lowdim coupling stencil
650 if constexpr (isBox<bulkIdx>())
651 {
652 const auto& vertices = this->vertexIndices(bulkIdx, bulkElementIdx);
653 this->couplingStencils(lowDimIdx)[lowDimElementIdx].insert(
654 this->couplingStencils(lowDimIdx)[lowDimElementIdx].end(),
655 vertices.begin(), vertices.end()
656 );
657 }
658 else
659 {
660 this->couplingStencils(lowDimIdx)[lowDimElementIdx].push_back(bulkElementIdx);
661 }
662 }
663
664 template<class BoundaryIntersection, class BBoxCheck>
665 auto isCoupled_(const SegmentNetwork& network, const BoundaryIntersection& intersection, const BBoxCheck& insideBBox) const
666 {
667 const auto center = intersection.geometry().center();
668 const auto [eIdx, minDist] = network.findClosestSegmentSurface(center);
669
670 // all elements in the bounding box are coupled if this is enabled
671 // this is a simplified check that can be enabled for box-shaped domains
672 static const bool considerBBox = getParam<bool>("MixedDimension.Projection.ConsiderFacesWithinBoundingBoxCoupled", false);
673 if (considerBBox && insideBBox(center))
674 return std::make_tuple(true, eIdx, minDist);
675
676 // general coupling face detection algorithm:
677 // if the distance is under a certain threshold we are coupled (and the angle is not very big)
678 static const auto rFactor = getParam<Scalar>("MixedDimension.Projection.CoupledRadiusFactor", 0.1);
679 static const auto spFactor = getParam<Scalar>("MixedDimension.Projection.CoupledAngleFactor", 0.3);
680 const auto projPoint = network.projectionPointOnSegment(center, eIdx);
681 const auto distVec = projPoint - center;
682 const bool isCoupled = minDist < rFactor * network.radius(eIdx) && distVec * intersection.centerUnitOuterNormal() > distVec.two_norm() * spFactor;
683 return std::make_tuple(isCoupled, eIdx, minDist);
684 }
685};
686
687} // end namespace Dumux
688
689#endif
A quadrature rule using local refinement to approximate partitioned elements.
Coupling manager for low-dimensional domains embedded in the bulk domain. Point sources on each integ...
Define some often used mathematical functions.
Helper class to create (named and comparable) tagged types.
Defines the index types used for grid and local indices.
A quadrature based on refinement.
A function to compute the convex hull of a point cloud.
Functionality to triangulate point clouds.
T getParam(Args &&... args)
A free function to get a parameter from the parameter tree singleton.
Definition parameters.hh:151
Definition adapt.hh:29
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::w
Definition pengrobinsonmixture.hh:152
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:150
Distance implementation details.
Definition fclocalassembler.hh:42
constexpr Box box
Definition method.hh:139
Definition couplingmanager1d3d_average.hh:46
constexpr Projection projection
Definition couplingmanager1d3d_projection.hh:275
Struture to define the index types used for grid and local indices.
Definition indextraits.hh:38
typename GridView::IndexSet::IndexType GridIndex
Definition indextraits.hh:39
Property to specify the type of a problem which has to be solved.
Definition common/properties.hh:57
Definition common/properties.hh:102
Helper class to create (named and comparable) tagged types Tags any given type. The tagged type is eq...
Definition tag.hh:42
const Problem< i > & problem(Dune::index_constant< i > domainIdx) const
Definition multidomain/couplingmanager.hh:320
Manages the coupling between bulk elements and lower dimensional elements Point sources on each integ...
Definition couplingmanager1d3d.hh:36
Segment representation of a 1d network grid.
Definition couplingmanager1d3d_projection.hh:66
auto findClosestSegmentSurface(const GlobalPosition &globalPos, const IndexRange &segIndices) const
same as overload with taking a position but only look at the segments specified by the index vector
Definition couplingmanager1d3d_projection.hh:131
const auto & segment(std::size_t eIdx) const
the segment with index eIdx
Definition couplingmanager1d3d_projection.hh:101
auto radius(std::size_t eIdx) const
Definition couplingmanager1d3d_projection.hh:97
GlobalPosition projectionPointOnSegment(const GlobalPosition &p, std::size_t idx) const
Definition couplingmanager1d3d_projection.hh:153
const auto & segments() const
the segments
Definition couplingmanager1d3d_projection.hh:105
SegmentNetwork(const GridGeometry &gg, const RadiusFunction &radiusFunction)
Definition couplingmanager1d3d_projection.hh:80
auto findClosestSegmentSurface(const GlobalPosition &globalPos) const
Definition couplingmanager1d3d_projection.hh:110
Get the closest segment for a given surface point.
Definition couplingmanager1d3d_projection.hh:200
NetworkIndicatorFunction(const Network &n)
Definition couplingmanager1d3d_projection.hh:202
auto operator()(const Pos &pos) const
Definition couplingmanager1d3d_projection.hh:207
auto operator()(const Pos &pos, const HintContainer &hints) const
Definition couplingmanager1d3d_projection.hh:214
Simple legacy VTK writer for outputting debug data on the coupling interface.
Definition couplingmanager1d3d_projection.hh:229
void push(const std::array< Dune::FieldVector< double, 3 >, 3 > &corners, double data)
Definition couplingmanager1d3d_projection.hh:231
void write(const std::string &name)
Definition couplingmanager1d3d_projection.hh:241
Definition couplingmanager1d3d_projection.hh:271
static std::string name()
Definition couplingmanager1d3d_projection.hh:272
void computePointSourceData(std::size_t order=1, bool verbose=false)
Definition couplingmanager1d3d_projection.hh:384
const std::vector< int > & bulkElementMarker() const
Marker that is non-zero for bulk elements that are coupled.
Definition couplingmanager1d3d_projection.hh:558
const std::vector< int > & bulkVertexMarker() const
Marker that is non-zero for bulk vertices that belong to coupled surface facets.
Definition couplingmanager1d3d_projection.hh:562
const std::vector< Scalar > & localAreaFactor() const
Definition couplingmanager1d3d_projection.hh:568
Scalar radius(std::size_t id) const
Methods to be accessed by the subproblems.
Definition couplingmanager1d3d_projection.hh:549
void init(std::shared_ptr< Problem< bulkIdx > > bulkProblem, std::shared_ptr< Problem< lowDimIdx > > lowDimProblem, const SolutionVector &curSol)
Definition couplingmanager1d3d_projection.hh:369
static constexpr Embedded1d3dCouplingMode::Projection couplingMode
Definition couplingmanager1d3d_projection.hh:365
const std::vector< PointSource< i > > & pointSources(Dune::index_constant< i > dom) const
Definition couplingmanagerbase.hh:405
EmbeddedCouplingManagerBase(std::shared_ptr< const GridGeometry< bulkIdx > > bulkGridGeometry, std::shared_ptr< const GridGeometry< lowDimIdx > > lowDimGridGeometry)
Definition couplingmanagerbase.hh:130
const CouplingStencils< i > & couplingStencils(Dune::index_constant< i > dom) const
Definition couplingmanagerbase.hh:410
const PointSourceData & pointSourceData(std::size_t id) const
Definition couplingmanagerbase.hh:375
void init(std::shared_ptr< Problem< bulkIdx > > bulkProblem, std::shared_ptr< Problem< lowDimIdx > > lowDimProblem, const SolutionVector &curSol)
Definition couplingmanagerbase.hh:141
void precomputeVertexIndices(Dune::index_constant< id > domainIdx)
Definition couplingmanagerbase.hh:445
Definition localrefinementquadrature.hh:54
A point source data class used for integration in multidimension models.
Definition pointsourcedata.hh:43
void addLowDimInterpolation(const ShapeValues &shapeValues, const std::vector< GridIndex< lowDimIdx > > &cornerIndices, GridIndex< lowDimIdx > eIdx)
Definition pointsourcedata.hh:72
void addBulkInterpolation(const ShapeValues &shapeValues, const std::vector< GridIndex< bulkIdx > > &cornerIndices, GridIndex< bulkIdx > eIdx)
Definition pointsourcedata.hh:62
Declares all properties used in Dumux.