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 const auto avgMinDist = averageDistanceSegmentGeometry(a, b, outside.geometry());
253 this->averageDistanceToBulkCell().push_back(avgMinDist);
254 fluxScalingFactor_.push_back(this->problem(bulkIdx).fluxScalingFactor(avgMinDist, radius, kernelWidth));
255
256 // export the lowdim coupling stencil
257 // we insert all vertices / elements and make it unique later
258 if constexpr (isBox<bulkIdx>())
259 {
260 const auto& vertices = this->vertexIndices(bulkIdx, bulkElementIdx);
261 this->couplingStencils(lowDimIdx)[lowDimElementIdx].insert(this->couplingStencils(lowDimIdx)[lowDimElementIdx].end(),
262 vertices.begin(), vertices.end());
263 }
264 else
265 {
266 this->couplingStencils(lowDimIdx)[lowDimElementIdx].push_back(bulkElementIdx);
267 }
268 }
269 }
270
271 // make the stencils unique
272 makeUniqueStencil_();
273
274 if (!this->pointSources(bulkIdx).empty())
275 DUNE_THROW(Dune::InvalidStateException, "Kernel method shouldn't have point sources in the bulk domain but only volume sources!");
276
277 std::cout << "[coupling] Finished preparing manager in " << watch.elapsed() << " seconds." << std::endl;
278 }
279
283 // \{
284
285
287 const std::vector<std::size_t>& bulkSourceIds(GridIndex<bulkIdx> eIdx, int scvIdx = 0) const
288 { return bulkSourceIds_[eIdx][scvIdx]; }
289
291 const std::vector<Scalar>& bulkSourceWeights(GridIndex<bulkIdx> eIdx, int scvIdx = 0) const
292 { return bulkSourceWeights_[eIdx][scvIdx]; }
293
295 Scalar fluxScalingFactor(std::size_t id) const
296 { return fluxScalingFactor_[id]; }
297
298 // \}
299
303 const typename BaseType::template CouplingStencils<bulkIdx>::mapped_type&
304 extendedSourceStencil(std::size_t eIdx) const
305 {
306 const auto& sourceStencils = extendedSourceStencil_.stencil();
307 if (auto stencil = sourceStencils.find(eIdx); stencil != sourceStencils.end())
308 return stencil->second;
309
310 return this->emptyStencil(bulkIdx);
311 }
312
313private:
315 template<class Line, class CylIntegration>
316 Scalar computeBulkSource(const Line& line, const Scalar radius, const Scalar kernelWidth,
317 std::size_t id, GridIndex<lowDimIdx> lowDimElementIdx, GridIndex<bulkIdx> coupledBulkElementIdx,
318 const CylIntegration& cylIntegration, int embeddings)
319 {
320 // Monte-carlo integration on the cylinder defined by line and radius
321 // The bounding box is taken from the grid itself so that unstructured grids, which
322 // have no Grid.LowerLeft/UpperRight/Cells parameters, work unchanged. Only the
323 // Cartesian fast path needs the cell counts.
324 const auto& min = this->problem(bulkIdx).gridGeometry().bBoxMin();
325 const auto& max = this->problem(bulkIdx).gridGeometry().bBoxMax();
326 std::array<int, bulkDim> cells{};
327 if constexpr (bulkIsCartesian)
328 {
329 static const auto bulkParamGroup = this->problem(bulkIdx).paramGroup();
330 static const auto cartesianCells = getParamFromGroup<std::array<int, bulkDim>>(bulkParamGroup, "Grid.Cells");
331 cells = cartesianCells;
332 }
333 const auto cylSamples = cylIntegration.size();
334 const auto& a = line.corner(0);
335 const auto& b = line.corner(1);
336
337 // optionally write debugging / visual output of the integration points
338 static const auto writeIntegrationPointsToFile = getParam<bool>("MixedDimension.WriteIntegrationPointsToFile", false);
339 if (writeIntegrationPointsToFile)
340 {
341 std::ofstream ipPointFile("kernel_points.log", std::ios::app);
342 for (int i = 0; i < cylSamples; ++i)
343 {
344 const auto& point = cylIntegration.integrationPoint(i);
345 if (const bool hasIntersection = intersectsPointBoundingBox(point, min, max); hasIntersection)
346 ipPointFile << point[0] << "," << point[1] << "," << point[2] << '\n';
347 }
348 }
349
350 Scalar integral = 0.0;
351 for (int i = 0; i < cylSamples; ++i)
352 {
353 const auto& point = cylIntegration.integrationPoint(i);
354 if (const bool hasIntersection = intersectsPointBoundingBox(point, min, max); hasIntersection)
355 {
356 const auto bulkElementIdx = bulkElementIndex_(point, min, max, cells);
357 if (bulkElementIdx == invalidElement_)
358 continue;
359 assert(bulkElementIdx < this->problem(bulkIdx).gridGeometry().gridView().size(0));
360 const auto localWeight = evalConstKernel_(a, b, point, radius, kernelWidth)*cylIntegration.integrationElement(i)/Scalar(embeddings);
361 integral += localWeight;
362
363 if constexpr (isBox<bulkIdx>())
364 {
365 using ShapeValues = std::vector<Dune::FieldVector<Scalar, 1> >;
366 const auto& gg = this->problem(bulkIdx).gridGeometry();
367 ShapeValues shapeValues;
368 this->getShapeValues(bulkIdx, gg, gg.element(bulkElementIdx).geometry(), point, shapeValues);
369
370 bool addedStencil = false;
371 for (int v = 0; v < static_cast<int>(shapeValues.size()); ++v)
372 {
373 const auto w = localWeight*shapeValues[v][0];
374 if (!bulkSourceIds_[bulkElementIdx][v].empty() && id == bulkSourceIds_[bulkElementIdx][v].back())
375 bulkSourceWeights_[bulkElementIdx][v].back() += w;
376 else
377 {
378 bulkSourceIds_[bulkElementIdx][v].emplace_back(id);
379 bulkSourceWeights_[bulkElementIdx][v].emplace_back(w);
380 addedStencil = true;
381 }
382 }
383 if (addedStencil)
384 addBulkSourceStencils_(bulkElementIdx, lowDimElementIdx, coupledBulkElementIdx);
385 }
386 else
387 {
388 if (!bulkSourceIds_[bulkElementIdx][0].empty() && id == bulkSourceIds_[bulkElementIdx][0].back())
389 bulkSourceWeights_[bulkElementIdx][0].back() += localWeight;
390 else
391 {
392 bulkSourceIds_[bulkElementIdx][0].emplace_back(id);
393 bulkSourceWeights_[bulkElementIdx][0].emplace_back(localWeight);
394 addBulkSourceStencils_(bulkElementIdx, lowDimElementIdx, coupledBulkElementIdx);
395 }
396 }
397 }
398 }
399
400 // the surface factor (which fraction of the source is inside the domain and needs to be considered)
401 const auto length = (a-b).two_norm()/Scalar(embeddings);
402 return integral/length;
403 }
404
405 static constexpr GridIndex<bulkIdx> invalidElement_ = std::numeric_limits<GridIndex<bulkIdx>>::max();
406
414 GridIndex<bulkIdx> bulkElementIndex_(const GlobalPosition& point,
415 const GlobalPosition& min,
416 const GlobalPosition& max,
417 const std::array<int, bulkDim>& cells) const
418 {
419 if constexpr (bulkIsCartesian)
420 return intersectingEntityCartesianGrid(point, min, max, cells);
421 else
422 {
423 const auto candidates = intersectingEntities(
424 point, this->problem(bulkIdx).gridGeometry().boundingBoxTree(), true);
425 return candidates.empty() ? invalidElement_ : GridIndex<bulkIdx>(candidates[0]);
426 }
427 }
428
429 void prepareDataStructures_()
430 {
431 // clear all internal members like pointsource vectors and stencils
432 // initializes the point source id counter
433 this->clear();
434 bulkSourceIds_.clear();
435 bulkSourceWeights_.clear();
436 extendedSourceStencil_.stencil().clear();
437
438 // precompute the vertex indices for efficiency for the box method
439 this->precomputeVertexIndices(bulkIdx);
440 this->precomputeVertexIndices(lowDimIdx);
441
442 bulkSourceIds_.resize(this->gridView(bulkIdx).size(0));
443 bulkSourceWeights_.resize(this->gridView(bulkIdx).size(0));
444
445 // intersect the bounding box trees
446 this->glueGrids();
447
448 // reserve memory for data
449 this->pointSourceData().reserve(this->glue().size());
450 this->averageDistanceToBulkCell().reserve(this->glue().size());
451 fluxScalingFactor_.reserve(this->glue().size());
452
453 // reserve memory for stencils
454 const auto numBulkElements = this->gridView(bulkIdx).size(0);
455 for (GridIndex<bulkIdx> bulkElementIdx = 0; bulkElementIdx < numBulkElements; ++bulkElementIdx)
456 {
457 this->couplingStencils(bulkIdx)[bulkElementIdx].reserve(10);
458 extendedSourceStencil_.stencil()[bulkElementIdx].reserve(10);
459 for (auto& ids : bulkSourceIds_[bulkElementIdx]) ids.reserve(10);
460 for (auto& w : bulkSourceWeights_[bulkElementIdx]) w.reserve(10);
461 }
462 }
463
465 void makeUniqueStencil_()
466 {
467 // make extra stencils unique
468 for (auto&& stencil : extendedSourceStencil_.stencil())
469 {
470 std::sort(stencil.second.begin(), stencil.second.end());
471 stencil.second.erase(std::unique(stencil.second.begin(), stencil.second.end()), stencil.second.end());
472
473 // remove the vertices element (box)
474 if constexpr (isBox<bulkIdx>())
475 {
476 const auto& indices = this->vertexIndices(bulkIdx, stencil.first);
477 stencil.second.erase(std::remove_if(stencil.second.begin(), stencil.second.end(),
478 [&](auto i){ return std::find(indices.begin(), indices.end(), i) != indices.end(); }),
479 stencil.second.end());
480 }
481 // remove the own element (cell-centered)
482 else
483 {
484 stencil.second.erase(std::remove_if(stencil.second.begin(), stencil.second.end(),
485 [&](auto i){ return i == stencil.first; }),
486 stencil.second.end());
487 }
488 }
489
490 // make stencils unique
491 using namespace Dune::Hybrid;
492 forEach(integralRange(Dune::index_constant<2>{}), [&](const auto domainIdx)
493 {
494 for (auto&& stencil : this->couplingStencils(domainIdx))
495 {
496 std::sort(stencil.second.begin(), stencil.second.end());
497 stencil.second.erase(std::unique(stencil.second.begin(), stencil.second.end()), stencil.second.end());
498 }
499 });
500 }
501
503 void addBulkSourceStencils_(GridIndex<bulkIdx> bulkElementIdx, GridIndex<lowDimIdx> coupledLowDimElementIdx, GridIndex<bulkIdx> coupledBulkElementIdx)
504 {
505 // add the lowdim element to the coupling stencil of this bulk element
506 if constexpr (isBox<lowDimIdx>())
507 {
508 const auto& vertices = this->vertexIndices(lowDimIdx, coupledLowDimElementIdx);
509 this->couplingStencils(bulkIdx)[bulkElementIdx].insert(this->couplingStencils(bulkIdx)[bulkElementIdx].end(),
510 vertices.begin(), vertices.end());
511
512 }
513 else
514 {
515 auto& s = this->couplingStencils(bulkIdx)[bulkElementIdx];
516 s.push_back(coupledLowDimElementIdx);
517 }
518
519 // the extended source stencil, every 3d element with a source is coupled to
520 // the element/dofs where the 3d quantities are measured
521 if constexpr (isBox<bulkIdx>())
522 {
523 const auto& vertices = this->vertexIndices(bulkIdx, coupledBulkElementIdx);
524 extendedSourceStencil_.stencil()[bulkElementIdx].insert(extendedSourceStencil_.stencil()[bulkElementIdx].end(),
525 vertices.begin(), vertices.end());
526 }
527 else
528 {
529 auto& s = extendedSourceStencil_.stencil()[bulkElementIdx];
530 s.push_back(coupledBulkElementIdx);
531 }
532 }
533
535 Scalar evalConstKernel_(const GlobalPosition& a,
536 const GlobalPosition& b,
537 const GlobalPosition& point,
538 const Scalar R,
539 const Scalar rho) const noexcept
540 {
541 // projection of point onto line a + t*(b-a)
542 const auto ab = b - a;
543 const auto t = (point - a)*ab/ab.two_norm2();
544
545 // return 0 if we are outside cylinder
546 if (t < 0.0 || t > 1.0)
547 return 0.0;
548
549 // compute distance
550 auto proj = a; proj.axpy(t, ab);
551 const auto radiusSquared = (proj - point).two_norm2();
552
553 if (radiusSquared > rho*rho)
554 return 0.0;
555
556 return 1.0/(M_PI*rho*rho);
557 }
558
562 template<class SpatialParams>
563 auto kernelWidthFactor_(const SpatialParams& spatialParams, unsigned int eIdx)
564 -> std::enable_if_t<hasKernelWidthFactor<SpatialParams, unsigned int>(), Scalar>
565 { return spatialParams.kernelWidthFactor(eIdx); }
566
570 template<class SpatialParams>
571 auto kernelWidthFactor_(const SpatialParams& spatialParams, unsigned int eIdx)
572 -> std::enable_if_t<!hasKernelWidthFactor<SpatialParams, unsigned int>(), Scalar>
573 {
574 static const Scalar kernelWidthFactor = getParam<Scalar>("MixedDimension.KernelWidthFactor");
575 return kernelWidthFactor;
576 }
577
579 EmbeddedCoupling::ExtendedSourceStencil<ThisType> extendedSourceStencil_;
580
582 std::vector<std::array<std::vector<std::size_t>, isBox<bulkIdx>() ? 1<<bulkDim : 1>> bulkSourceIds_;
584 std::vector<std::array<std::vector<Scalar>, isBox<bulkIdx>() ? 1<<bulkDim : 1>> bulkSourceWeights_;
585
587 std::vector<Scalar> fluxScalingFactor_;
588};
589
591template<class MDTraits>
594
595} // end namespace Dumux
596
597#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:304
const std::vector< Scalar > & bulkSourceWeights(GridIndex< bulkIdx > eIdx, int scvIdx=0) const
return all source ids for a bulk elements
Definition couplingmanager1d3d_kernel.hh:291
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:287
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:295
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 averageDistanceSegmentGeometry(const typename Geometry::GlobalCoordinate &a, const typename Geometry::GlobalCoordinate &b, const Geometry &geometry, std::size_t integrationOrder=2)
Compute the average distance from a segment to a geometry by integration.
Definition distance.hh:265
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.