version 3.11-dev
Loading...
Searching...
No Matches
couplingmanager1d3d_kernel.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
13#ifndef DUMUX_MULTIDOMAIN_EMBEDDED_COUPLINGMANAGER_1D3D_KERNEL_HH
14#define DUMUX_MULTIDOMAIN_EMBEDDED_COUPLINGMANAGER_1D3D_KERNEL_HH
15
16#include <vector>
17
18#include <dune/common/timer.hh>
19#include <dune/geometry/quadraturerules.hh>
20#include <dune/grid/common/capabilities.hh>
21
22#include <dumux/common/tag.hh>
26
30
31namespace Dumux {
32
34struct Kernel : public Utility::Tag<Kernel> {
35 static std::string name() { return "kernel"; }
36};
37
38inline constexpr Kernel kernel{};
39} // end namespace Embedded1d3dCouplingMode
40
41// forward declaration
42template<class MDTraits, class CouplingMode>
43class Embedded1d3dCouplingManager;
44
51template<class MDTraits>
53: public Embedded1d3dCouplingManagerBase<MDTraits, Embedded1d3dCouplingManager<MDTraits, Embedded1d3dCouplingMode::Kernel>>
54{
57 using BaseType = EmbeddedCouplingManagerBase<MDTraits, ParentType>; //TODO: Better naming?
58 using Scalar = typename MDTraits::Scalar;
59 using SolutionVector = typename MDTraits::SolutionVector;
60 using PointSourceData = typename BaseType::PointSourceTraits::PointSourceData;
61
62 static constexpr auto bulkIdx = typename MDTraits::template SubDomain<0>::Index();
63 static constexpr auto lowDimIdx = typename MDTraits::template SubDomain<1>::Index();
64
65 // the sub domain type aliases
66 template<std::size_t id> using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
67 template<std::size_t id> using Problem = GetPropType<SubDomainTypeTag<id>, Properties::Problem>;
68 template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
69 template<std::size_t id> using GridView = typename GridGeometry<id>::GridView;
70 template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity;
71 template<std::size_t id> using GridIndex = typename IndexTraits<GridView<id>>::GridIndex;
72
73 using GlobalPosition = typename Element<bulkIdx>::Geometry::GlobalCoordinate;
74
75 template<std::size_t id>
76 static constexpr bool isBox()
77 { return GridGeometry<id>::discMethod == DiscretizationMethods::box; }
78
80 static constexpr bool bulkIsCartesian
81 = Dune::Capabilities::isCartesian<typename GridView<bulkIdx>::Grid>::v;
82
83 enum {
84 bulkDim = GridView<bulkIdx>::dimension,
85 lowDimDim = GridView<lowDimIdx>::dimension,
86 dimWorld = GridView<bulkIdx>::dimensionworld
87 };
88
89 // detect if a class (the spatial params) has a kernelWidthFactor() function
90 template <typename T, typename ...Ts>
91 using VariableKernelWidthDetector = decltype(std::declval<T>().kernelWidthFactor(std::declval<Ts>()...));
92
93 template<class T, typename ...Args>
94 static constexpr bool hasKernelWidthFactor()
95 { return Dune::Std::is_detected<VariableKernelWidthDetector, T, Args...>::value; }
96
97public:
99
100 using ParentType::ParentType;
101
102 void init(std::shared_ptr<Problem<bulkIdx>> bulkProblem,
103 std::shared_ptr<Problem<lowDimIdx>> lowDimProblem,
104 const SolutionVector& curSol)
105 {
106 ParentType::init(bulkProblem, lowDimProblem, curSol);
107
108 const auto refinement = getParamFromGroup<int>(bulkProblem->paramGroup(), "Grid.Refinement", 0);
109 if (refinement > 0)
110 DUNE_THROW(Dune::NotImplemented, "The current intersection detection may likely fail for refined grids.");
111 }
112
119 template<std::size_t id, class JacobianPattern>
120 void extendJacobianPattern(Dune::index_constant<id> domainI, JacobianPattern& pattern) const
121 {
122 extendedSourceStencil_.extendJacobianPattern(*this, domainI, pattern);
123 }
124
132 template<std::size_t i, class LocalAssemblerI, class JacobianMatrixDiagBlock, class GridVariables>
133 void evalAdditionalDomainDerivatives(Dune::index_constant<i> domainI,
134 const LocalAssemblerI& localAssemblerI,
135 const typename LocalAssemblerI::LocalResidual::ElementResidualVector&,
136 JacobianMatrixDiagBlock& A,
137 GridVariables& gridVariables)
138 {
139 extendedSourceStencil_.evalAdditionalDomainDerivatives(*this, domainI, localAssemblerI, A, gridVariables);
140 }
141
142 /* \brief Compute integration point point sources and associated data
143 *
144 * This method uses grid glue to intersect the given grids. Over each intersection
145 * we later need to integrate a source term. This method places point sources
146 * at each quadrature point and provides the point source with the necessary
147 * information to compute integrals (quadrature weight and integration element)
148 * \param order The order of the quadrature rule for integration of sources over an intersection
149 * \param verbose If the point source computation is verbose
150 */
151 void computePointSourceData(std::size_t order = 1, bool verbose = false)
152 {
153 // initialize the maps
154 // do some logging and profiling
155 Dune::Timer watch;
156 std::cout << "[coupling] Initializing the integration point source data structures..." << std::endl;
157
158 // prepare the internal data structures
159 prepareDataStructures_();
160 std::cout << "[coupling] Resized data structures." << std::endl;
161
162 const auto& bulkGridGeometry = this->problem(bulkIdx).gridGeometry();
163 const auto& lowDimGridGeometry = this->problem(lowDimIdx).gridGeometry();
164
165 // generate a bunch of random vectors and values for
166 // Monte-carlo integration on the cylinder defined by line and radius
167 static const double characteristicRelativeLength = getParam<double>("MixedDimension.KernelIntegrationCRL", 0.1);
168 EmbeddedCoupling::CylinderIntegration<Scalar> cylIntegration(characteristicRelativeLength, 1);
169
170 static const bool writeIntegrationPointsToFile = getParam<bool>("MixedDimension.WriteIntegrationPointsToFile", false);
171 if (writeIntegrationPointsToFile)
172 {
173 std::ofstream ipPointFile("kernel_points.log", std::ios::trunc);
174 ipPointFile << "x,y,z\n";
175 std::cout << "[coupling] Initialized kernel_points.log." << std::endl;
176 }
177
178 for (const auto& is : intersections(this->glue()))
179 {
180 // all inside elements are identical...
181 const auto& inside = is.targetEntity(0);
182 // get the intersection geometry for integrating over it
183 const auto intersectionGeometry = is.geometry();
184 const auto lowDimElementIdx = lowDimGridGeometry.elementMapper().index(inside);
185
186 // for each intersection integrate kernel and add:
187 // * 1d: a new point source
188 // * 3d: a new kernel volume source
189 const auto radius = this->problem(lowDimIdx).spatialParams().radius(lowDimElementIdx);
190 const auto kernelWidthFactor = kernelWidthFactor_(this->problem(lowDimIdx).spatialParams(), lowDimElementIdx);
191 const auto kernelWidth = kernelWidthFactor*radius;
192 const auto a = intersectionGeometry.corner(0);
193 const auto b = intersectionGeometry.corner(1);
194 cylIntegration.setGeometry(a, b, kernelWidth);
195
196 // we can have multiple 3d elements per 1d intersection
197 for (int outsideIdx = 0; outsideIdx < is.numDomainNeighbors(); ++outsideIdx)
198 {
199 // compute source id
200 // for each id we have
201 // (1) a point source for the 1d domain
202 // (2) a bulk source weight for the each element in the 3d domain (the fraction of the total source/sink for the 1d element with the point source)
203 // TODO: i.e. one integration of the kernel should be enough (for each of the weights it's weight/embeddings)
204 // (3) the flux scaling factor for each outside element, i.e. each id
205 const auto id = this->idCounter_++;
206
207 // compute the weights for the bulk volume sources
208 const auto& outside = is.domainEntity(outsideIdx);
209 const auto bulkElementIdx = bulkGridGeometry.elementMapper().index(outside);
210 const auto surfaceFactor = computeBulkSource(intersectionGeometry, radius, kernelWidth, id, lowDimElementIdx, bulkElementIdx, cylIntegration, is.numDomainNeighbors());
211
212 // place a point source at the intersection center
213 const auto center = intersectionGeometry.center();
214 this->pointSources(lowDimIdx).emplace_back(center, id, surfaceFactor, intersectionGeometry.volume(), lowDimElementIdx);
215 this->pointSources(lowDimIdx).back().setEmbeddings(is.numDomainNeighbors());
216
217 // pre compute additional data used for the evaluation of
218 // the actual solution dependent source term
219 PointSourceData psData;
220
221 // lowdim interpolation (evaluate at center)
222 if constexpr (isBox<lowDimIdx>())
223 {
224 using ShapeValues = std::vector<Dune::FieldVector<Scalar, 1> >;
225 const auto lowDimGeometry = this->problem(lowDimIdx).gridGeometry().element(lowDimElementIdx).geometry();
226 ShapeValues shapeValues;
227 this->getShapeValues(lowDimIdx, this->problem(lowDimIdx).gridGeometry(), lowDimGeometry, center, shapeValues);
228 psData.addLowDimInterpolation(shapeValues, this->vertexIndices(lowDimIdx, lowDimElementIdx), lowDimElementIdx);
229 }
230 else
231 {
232 psData.addLowDimInterpolation(lowDimElementIdx);
233 }
234
235 // bulk interpolation (evaluate at center)
236 if constexpr (isBox<bulkIdx>())
237 {
238 using ShapeValues = std::vector<Dune::FieldVector<Scalar, 1> >;
239 const auto bulkGeometry = this->problem(bulkIdx).gridGeometry().element(bulkElementIdx).geometry();
240 ShapeValues shapeValues;
241 this->getShapeValues(bulkIdx, this->problem(bulkIdx).gridGeometry(), bulkGeometry, center, shapeValues);
242 psData.addBulkInterpolation(shapeValues, this->vertexIndices(bulkIdx, bulkElementIdx), bulkElementIdx);
243 }
244 else
245 {
246 psData.addBulkInterpolation(bulkElementIdx);
247 }
248
249 // publish point source data in the global vector
250 this->pointSourceData().emplace_back(std::move(psData));
251
252 // the flux scaling factor assumes the radially symmetric solution around a straight
253 // line, so the distance is measured to the line through the segment. The distance to
254 // the segment itself would grow with the parts of the bulk element beyond the segment
255 // ends, e.g. if several lower-dimensional elements are embedded in one bulk element.
256 const auto avgMinDist = averageDistanceLineGeometry(a, b, outside.geometry());
257 this->averageDistanceToBulkCell().push_back(avgMinDist);
258 fluxScalingFactor_.push_back(this->problem(bulkIdx).fluxScalingFactor(avgMinDist, radius, kernelWidth));
259
260 // export the lowdim coupling stencil
261 // we insert all vertices / elements and make it unique later
262 if constexpr (isBox<bulkIdx>())
263 {
264 const auto& vertices = this->vertexIndices(bulkIdx, bulkElementIdx);
265 this->couplingStencils(lowDimIdx)[lowDimElementIdx].insert(this->couplingStencils(lowDimIdx)[lowDimElementIdx].end(),
266 vertices.begin(), vertices.end());
267 }
268 else
269 {
270 this->couplingStencils(lowDimIdx)[lowDimElementIdx].push_back(bulkElementIdx);
271 }
272 }
273 }
274
275 // make the stencils unique
276 makeUniqueStencil_();
277
278 if (!this->pointSources(bulkIdx).empty())
279 DUNE_THROW(Dune::InvalidStateException, "Kernel method shouldn't have point sources in the bulk domain but only volume sources!");
280
281 std::cout << "[coupling] Finished preparing manager in " << watch.elapsed() << " seconds." << std::endl;
282 }
283
287 // \{
288
289
291 const std::vector<std::size_t>& bulkSourceIds(GridIndex<bulkIdx> eIdx, int scvIdx = 0) const
292 { return bulkSourceIds_[eIdx][scvIdx]; }
293
295 const std::vector<Scalar>& bulkSourceWeights(GridIndex<bulkIdx> eIdx, int scvIdx = 0) const
296 { return bulkSourceWeights_[eIdx][scvIdx]; }
297
299 Scalar fluxScalingFactor(std::size_t id) const
300 { return fluxScalingFactor_[id]; }
301
302 // \}
303
307 const typename BaseType::template CouplingStencils<bulkIdx>::mapped_type&
308 extendedSourceStencil(std::size_t eIdx) const
309 {
310 const auto& sourceStencils = extendedSourceStencil_.stencil();
311 if (auto stencil = sourceStencils.find(eIdx); stencil != sourceStencils.end())
312 return stencil->second;
313
314 return this->emptyStencil(bulkIdx);
315 }
316
317private:
319 template<class Line, class CylIntegration>
320 Scalar computeBulkSource(const Line& line, const Scalar radius, const Scalar kernelWidth,
321 std::size_t id, GridIndex<lowDimIdx> lowDimElementIdx, GridIndex<bulkIdx> coupledBulkElementIdx,
322 const CylIntegration& cylIntegration, int embeddings)
323 {
324 // Monte-carlo integration on the cylinder defined by line and radius
325 // The bounding box is taken from the grid itself so that unstructured grids, which
326 // have no Grid.LowerLeft/UpperRight/Cells parameters, work unchanged. Only the
327 // Cartesian fast path needs the cell counts.
328 const auto& min = this->problem(bulkIdx).gridGeometry().bBoxMin();
329 const auto& max = this->problem(bulkIdx).gridGeometry().bBoxMax();
330 std::array<int, bulkDim> cells{};
331 if constexpr (bulkIsCartesian)
332 {
333 static const auto bulkParamGroup = this->problem(bulkIdx).paramGroup();
334 static const auto cartesianCells = getParamFromGroup<std::array<int, bulkDim>>(bulkParamGroup, "Grid.Cells");
335 cells = cartesianCells;
336 }
337 const auto cylSamples = cylIntegration.size();
338 const auto& a = line.corner(0);
339 const auto& b = line.corner(1);
340
341 // optionally write debugging / visual output of the integration points
342 static const auto writeIntegrationPointsToFile = getParam<bool>("MixedDimension.WriteIntegrationPointsToFile", false);
343 if (writeIntegrationPointsToFile)
344 {
345 std::ofstream ipPointFile("kernel_points.log", std::ios::app);
346 for (int i = 0; i < cylSamples; ++i)
347 {
348 const auto& point = cylIntegration.integrationPoint(i);
349 if (const bool hasIntersection = intersectsPointBoundingBox(point, min, max); hasIntersection)
350 ipPointFile << point[0] << "," << point[1] << "," << point[2] << '\n';
351 }
352 }
353
354 Scalar integral = 0.0;
355 for (int i = 0; i < cylSamples; ++i)
356 {
357 const auto& point = cylIntegration.integrationPoint(i);
358 if (const bool hasIntersection = intersectsPointBoundingBox(point, min, max); hasIntersection)
359 {
360 const auto bulkElementIdx = bulkElementIndex_(point, min, max, cells);
361 if (bulkElementIdx == invalidElement_)
362 continue;
363 assert(bulkElementIdx < this->problem(bulkIdx).gridGeometry().gridView().size(0));
364 const auto localWeight = evalConstKernel_(a, b, point, radius, kernelWidth)*cylIntegration.integrationElement(i)/Scalar(embeddings);
365 integral += localWeight;
366
367 if constexpr (isBox<bulkIdx>())
368 {
369 using ShapeValues = std::vector<Dune::FieldVector<Scalar, 1> >;
370 const auto& gg = this->problem(bulkIdx).gridGeometry();
371 ShapeValues shapeValues;
372 this->getShapeValues(bulkIdx, gg, gg.element(bulkElementIdx).geometry(), point, shapeValues);
373
374 bool addedStencil = false;
375 for (int v = 0; v < static_cast<int>(shapeValues.size()); ++v)
376 {
377 const auto w = localWeight*shapeValues[v][0];
378 if (!bulkSourceIds_[bulkElementIdx][v].empty() && id == bulkSourceIds_[bulkElementIdx][v].back())
379 bulkSourceWeights_[bulkElementIdx][v].back() += w;
380 else
381 {
382 bulkSourceIds_[bulkElementIdx][v].emplace_back(id);
383 bulkSourceWeights_[bulkElementIdx][v].emplace_back(w);
384 addedStencil = true;
385 }
386 }
387 if (addedStencil)
388 addBulkSourceStencils_(bulkElementIdx, lowDimElementIdx, coupledBulkElementIdx);
389 }
390 else
391 {
392 if (!bulkSourceIds_[bulkElementIdx][0].empty() && id == bulkSourceIds_[bulkElementIdx][0].back())
393 bulkSourceWeights_[bulkElementIdx][0].back() += localWeight;
394 else
395 {
396 bulkSourceIds_[bulkElementIdx][0].emplace_back(id);
397 bulkSourceWeights_[bulkElementIdx][0].emplace_back(localWeight);
398 addBulkSourceStencils_(bulkElementIdx, lowDimElementIdx, coupledBulkElementIdx);
399 }
400 }
401 }
402 }
403
404 // the surface factor (which fraction of the source is inside the domain and needs to be considered)
405 const auto length = (a-b).two_norm()/Scalar(embeddings);
406 return integral/length;
407 }
408
409 static constexpr GridIndex<bulkIdx> invalidElement_ = std::numeric_limits<GridIndex<bulkIdx>>::max();
410
418 GridIndex<bulkIdx> bulkElementIndex_(const GlobalPosition& point,
419 const GlobalPosition& min,
420 const GlobalPosition& max,
421 const std::array<int, bulkDim>& cells) const
422 {
423 if constexpr (bulkIsCartesian)
424 return intersectingEntityCartesianGrid(point, min, max, cells);
425 else
426 {
427 const auto candidates = intersectingEntities(
428 point, this->problem(bulkIdx).gridGeometry().boundingBoxTree(), true);
429 return candidates.empty() ? invalidElement_ : GridIndex<bulkIdx>(candidates[0]);
430 }
431 }
432
433 void prepareDataStructures_()
434 {
435 // clear all internal members like pointsource vectors and stencils
436 // initializes the point source id counter
437 this->clear();
438 bulkSourceIds_.clear();
439 bulkSourceWeights_.clear();
440 extendedSourceStencil_.stencil().clear();
441
442 // precompute the vertex indices for efficiency for the box method
443 this->precomputeVertexIndices(bulkIdx);
444 this->precomputeVertexIndices(lowDimIdx);
445
446 bulkSourceIds_.resize(this->gridView(bulkIdx).size(0));
447 bulkSourceWeights_.resize(this->gridView(bulkIdx).size(0));
448
449 // intersect the bounding box trees
450 this->glueGrids();
451
452 // reserve memory for data
453 this->pointSourceData().reserve(this->glue().size());
454 this->averageDistanceToBulkCell().reserve(this->glue().size());
455 fluxScalingFactor_.reserve(this->glue().size());
456
457 // reserve memory for stencils
458 const auto numBulkElements = this->gridView(bulkIdx).size(0);
459 for (GridIndex<bulkIdx> bulkElementIdx = 0; bulkElementIdx < numBulkElements; ++bulkElementIdx)
460 {
461 this->couplingStencils(bulkIdx)[bulkElementIdx].reserve(10);
462 extendedSourceStencil_.stencil()[bulkElementIdx].reserve(10);
463 for (auto& ids : bulkSourceIds_[bulkElementIdx]) ids.reserve(10);
464 for (auto& w : bulkSourceWeights_[bulkElementIdx]) w.reserve(10);
465 }
466 }
467
469 void makeUniqueStencil_()
470 {
471 // make extra stencils unique
472 for (auto&& stencil : extendedSourceStencil_.stencil())
473 {
474 std::sort(stencil.second.begin(), stencil.second.end());
475 stencil.second.erase(std::unique(stencil.second.begin(), stencil.second.end()), stencil.second.end());
476
477 // remove the vertices element (box)
478 if constexpr (isBox<bulkIdx>())
479 {
480 const auto& indices = this->vertexIndices(bulkIdx, stencil.first);
481 stencil.second.erase(std::remove_if(stencil.second.begin(), stencil.second.end(),
482 [&](auto i){ return std::find(indices.begin(), indices.end(), i) != indices.end(); }),
483 stencil.second.end());
484 }
485 // remove the own element (cell-centered)
486 else
487 {
488 stencil.second.erase(std::remove_if(stencil.second.begin(), stencil.second.end(),
489 [&](auto i){ return i == stencil.first; }),
490 stencil.second.end());
491 }
492 }
493
494 // make stencils unique
495 using namespace Dune::Hybrid;
496 forEach(integralRange(Dune::index_constant<2>{}), [&](const auto domainIdx)
497 {
498 for (auto&& stencil : this->couplingStencils(domainIdx))
499 {
500 std::sort(stencil.second.begin(), stencil.second.end());
501 stencil.second.erase(std::unique(stencil.second.begin(), stencil.second.end()), stencil.second.end());
502 }
503 });
504 }
505
507 void addBulkSourceStencils_(GridIndex<bulkIdx> bulkElementIdx, GridIndex<lowDimIdx> coupledLowDimElementIdx, GridIndex<bulkIdx> coupledBulkElementIdx)
508 {
509 // add the lowdim element to the coupling stencil of this bulk element
510 if constexpr (isBox<lowDimIdx>())
511 {
512 const auto& vertices = this->vertexIndices(lowDimIdx, coupledLowDimElementIdx);
513 this->couplingStencils(bulkIdx)[bulkElementIdx].insert(this->couplingStencils(bulkIdx)[bulkElementIdx].end(),
514 vertices.begin(), vertices.end());
515
516 }
517 else
518 {
519 auto& s = this->couplingStencils(bulkIdx)[bulkElementIdx];
520 s.push_back(coupledLowDimElementIdx);
521 }
522
523 // the extended source stencil, every 3d element with a source is coupled to
524 // the element/dofs where the 3d quantities are measured
525 if constexpr (isBox<bulkIdx>())
526 {
527 const auto& vertices = this->vertexIndices(bulkIdx, coupledBulkElementIdx);
528 extendedSourceStencil_.stencil()[bulkElementIdx].insert(extendedSourceStencil_.stencil()[bulkElementIdx].end(),
529 vertices.begin(), vertices.end());
530 }
531 else
532 {
533 auto& s = extendedSourceStencil_.stencil()[bulkElementIdx];
534 s.push_back(coupledBulkElementIdx);
535 }
536 }
537
539 Scalar evalConstKernel_(const GlobalPosition& a,
540 const GlobalPosition& b,
541 const GlobalPosition& point,
542 const Scalar R,
543 const Scalar rho) const noexcept
544 {
545 // projection of point onto line a + t*(b-a)
546 const auto ab = b - a;
547 const auto t = (point - a)*ab/ab.two_norm2();
548
549 // return 0 if we are outside cylinder
550 if (t < 0.0 || t > 1.0)
551 return 0.0;
552
553 // compute distance
554 auto proj = a; proj.axpy(t, ab);
555 const auto radiusSquared = (proj - point).two_norm2();
556
557 if (radiusSquared > rho*rho)
558 return 0.0;
559
560 return 1.0/(M_PI*rho*rho);
561 }
562
566 template<class SpatialParams>
567 auto kernelWidthFactor_(const SpatialParams& spatialParams, unsigned int eIdx)
568 -> std::enable_if_t<hasKernelWidthFactor<SpatialParams, unsigned int>(), Scalar>
569 { return spatialParams.kernelWidthFactor(eIdx); }
570
574 template<class SpatialParams>
575 auto kernelWidthFactor_(const SpatialParams& spatialParams, unsigned int eIdx)
576 -> std::enable_if_t<!hasKernelWidthFactor<SpatialParams, unsigned int>(), Scalar>
577 {
578 static const Scalar kernelWidthFactor = getParam<Scalar>("MixedDimension.KernelWidthFactor");
579 return kernelWidthFactor;
580 }
581
583 EmbeddedCoupling::ExtendedSourceStencil<ThisType> extendedSourceStencil_;
584
586 std::vector<std::array<std::vector<std::size_t>, isBox<bulkIdx>() ? 1<<bulkDim : 1>> bulkSourceIds_;
588 std::vector<std::array<std::vector<Scalar>, isBox<bulkIdx>() ? 1<<bulkDim : 1>> bulkSourceWeights_;
589
591 std::vector<Scalar> fluxScalingFactor_;
592};
593
595template<class MDTraits>
598
599} // end namespace Dumux
600
601#endif
const Problem< i > & problem(Dune::index_constant< i > domainIdx) const
Definition multidomain/couplingmanager.hh:318
void evalAdditionalDomainDerivatives(Dune::index_constant< i > domainI, const LocalAssemblerI &localAssemblerI, const typename LocalAssemblerI::LocalResidual::ElementResidualVector &, JacobianMatrixDiagBlock &A, GridVariables &gridVariables)
evaluate additional derivatives of the element residual of a domain with respect to dofs in the same ...
Definition couplingmanager1d3d_kernel.hh:133
static constexpr Embedded1d3dCouplingMode::Kernel couplingMode
Definition couplingmanager1d3d_kernel.hh:98
const BaseType::template CouplingStencils< bulkIdx >::mapped_type & extendedSourceStencil(std::size_t eIdx) const
Extended source stencil (for the bulk domain).
Definition couplingmanager1d3d_kernel.hh:308
const std::vector< Scalar > & bulkSourceWeights(GridIndex< bulkIdx > eIdx, int scvIdx=0) const
return all source ids for a bulk elements
Definition couplingmanager1d3d_kernel.hh:295
void extendJacobianPattern(Dune::index_constant< id > domainI, JacobianPattern &pattern) const
extend the jacobian pattern of the diagonal block of domain i by those entries that are not already i...
Definition couplingmanager1d3d_kernel.hh:120
const std::vector< std::size_t > & bulkSourceIds(GridIndex< bulkIdx > eIdx, int scvIdx=0) const
Methods to be accessed by the subproblems.
Definition couplingmanager1d3d_kernel.hh:291
void computePointSourceData(std::size_t order=1, bool verbose=false)
Definition couplingmanager1d3d_kernel.hh:151
Scalar fluxScalingFactor(std::size_t id) const
The flux scaling factor for a source with id.
Definition couplingmanager1d3d_kernel.hh:299
void init(std::shared_ptr< Problem< bulkIdx > > bulkProblem, std::shared_ptr< Problem< lowDimIdx > > lowDimProblem, const SolutionVector &curSol)
Definition couplingmanager1d3d_kernel.hh:102
Manages the coupling between bulk elements and lower dimensional elements Point sources on each integ...
Definition couplingmanager1d3dbase.hh:35
void init(std::shared_ptr< Problem< bulkIdx > > bulkProblem, std::shared_ptr< Problem< lowDimIdx > > lowDimProblem, const SolutionVector &curSol)
Definition couplingmanager1d3dbase.hh:57
Manages the coupling between bulk elements and lower dimensional elements Point sources on each integ...
Definition couplingmanager1d3d.hh:24
Helper class to integrate over a cylinder domain.
Definition cylinderintegration.hh:48
void setGeometry(const GlobalPosition &bottomCenter, const GlobalPosition &topCenter, const Scalar radius, int verbosity=0)
Set the geometry of the cylinder.
Definition cylinderintegration.hh:85
Manages the coupling between bulk elements and lower dimensional elements Point sources on each integ...
Definition couplingmanagerbase.hh:71
std::vector< GridIndex< i > > & vertexIndices(Dune::index_constant< i > dom, GridIndex< i > eIdx)
Definition couplingmanagerbase.hh:672
const std::vector< PointSource< i > > & pointSources(Dune::index_constant< i > dom) const
Definition couplingmanagerbase.hh:398
const CouplingStencils< i > & couplingStencils(Dune::index_constant< i > dom) const
Definition couplingmanagerbase.hh:403
const CouplingStencil< i > & emptyStencil(Dune::index_constant< i > dom) const
Definition couplingmanagerbase.hh:412
const PointSourceData & pointSourceData(std::size_t id) const
Definition couplingmanagerbase.hh:368
void getShapeValues(Dune::index_constant< i > domainI, const FVGG &gridGeometry, const Geometry &geo, const GlobalPosition &globalPos, ShapeValues &shapeValues)
Definition couplingmanagerbase.hh:615
Defines all properties used in Dumux.
Coupling manager for low-dimensional domains embedded in the bulk domain.
Integration over cylindrical and elliptic cylindrical domains Lowest order integration formulas that ...
Helper functions for distance queries.
Extended source stencil helper class for coupling managers.
std::size_t intersectingEntityCartesianGrid(const Dune::FieldVector< ctype, dimworld > &point, const Dune::FieldVector< ctype, dimworld > &min, const Dune::FieldVector< ctype, dimworld > &max, const std::array< int, std::size_t(dimworld)> &cells)
Compute the index of the intersecting element of a Cartesian grid with a point The grid is given by t...
Definition intersectingentities.hh:558
Corners::value_type center(const Corners &corners)
The center of a given list of corners.
Definition center.hh:24
static Geometry::ctype averageDistanceLineGeometry(const typename Geometry::GlobalCoordinate &a, const typename Geometry::GlobalCoordinate &b, const Geometry &geometry, std::size_t integrationOrder=2)
Compute the average distance from a line through the points a and b to a geometry by integration.
Definition distance.hh:285
std::vector< std::pair< int, std::size_t > > intersectingEntities(const Dune::FieldVector< ctype, dimworld > &point, const DistributedBoundingBoxTree< EntitySet > &tree, bool isCartesianGrid=false, bool onlyOwned=true)
Compute all intersections between entities and a point on a distributed tree.
Definition distributedintersectingentities.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:165
T getParam(Args &&... args)
A free function to get a parameter from the parameter tree singleton.
Definition parameters.hh:155
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
Defines the index types used for grid and local indices.
constexpr Box box
Definition method.hh:176
Definition couplingmanager1d3d_average.hh:34
constexpr Kernel kernel
Definition couplingmanager1d3d_kernel.hh:38
constexpr Line line
Definition couplingmanager1d3d_line.hh:31
typename ScalarType< X >::Type Scalar
Definition odesolver.hh:52
Definition adapt.hh:17
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::w
Definition pengrobinsonmixture.hh:140
bool intersectsPointBoundingBox(const Dune::FieldVector< ctype, dimworld > &point, const ctype *b)
Check whether a point is intersectin a bounding box (dimworld == 3).
Definition boundingboxtree.hh:305
Type trait that is specialized for coupling manager supporting multithreaded assembly.
Definition assemblytraits.hh:43
Definition couplingmanager1d3d_kernel.hh:34
static std::string name()
Definition couplingmanager1d3d_kernel.hh:35
Structure to define the index types used for grid and local indices.
Definition indextraits.hh:26
Helper class to create (named and comparable) tagged types Tags any given type. The tagged type is eq...
Definition tag.hh:30
Helper class to create (named and comparable) tagged types.