294class SnappyGridManager :
public Dumux::GridManager<Dune::YaspGrid<dim, Dune::TensorProductCoordinates<typename OtherGridCreator::Grid::ctype, OtherGridCreator::Grid::LeafGridView::dimensionworld>>>
296 using Scalar =
typename OtherGridCreator::Grid::ctype;
297 using OtherGrid =
typename OtherGridCreator::Grid;
298 using IntVector = std::vector<int>;
299 using ScalarVector = std::vector<Scalar>;
301 static constexpr auto dimWorld = OtherGrid::LeafGridView::dimensionworld;
302 using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
305 using LowDimGridData =
typename OtherGridCreator::GridData;
307 struct GridConstructionData
309 std::array<ScalarVector, dim> positions;
310 std::array<IntVector, dim> cells;
311 std::array<ScalarVector, dim> grading;
312 std::array<std::optional<ScalarVector>, dim> interfacePositions;
317 using ParentType::ParentType;
320 void init(
const OtherGrid& otherGrid,
const LowDimGridData& otherData,
const std::string& modelParamGroup =
"")
322 modelParamGroup_ = modelParamGroup;
323 std::array<ScalarVector, dim> positions;
324 std::array<IntVector, dim> cells;
325 std::array<ScalarVector, dim> grading;
326 std::array<std::optional<ScalarVector>, dim> interFacePositions;
333 "Grid.CouplinglineNormal",
334 [](){ GlobalPosition tmp(0.0); tmp[tmp.size()-1] = 1.0;
return tmp; }());
336 const auto couplingPlaneNormalDirectionIndex = SnappyGridManagerHelper::directionIndex(couplingPlaneNormal);
337 const auto couplingPlane = SnappyGridManagerHelper::makeCouplingPlane(lowerLeft, upperRight, couplingPlaneNormal, modelParamGroup);
339 std::cout <<
"plane: \n";
340 for (
int i = 0; i < couplingPlane.corners(); ++i)
341 std::cout << couplingPlane.corner(i) << std::endl;
343 const auto pointsOnAxisParallelLines = SnappyGridManagerHelper::getPointsOnLine(lowerLeft, upperRight, couplingPlaneNormal, otherGrid.leafGridView(), otherData, modelParamGroup_);
345 for (
int i = 0; i < dim; ++i)
348 positions[i].push_back(lowerLeft[i]);
350 if (i != couplingPlaneNormalDirectionIndex)
352 if (!pointsOnAxisParallelLines[i].has_value())
353 DUNE_THROW(Dune::GridError,
"Something went wrong with the coupling plane normal");
355 const auto& pointsOnLine = (*pointsOnAxisParallelLines[i]);
357 std::cout <<
"point " << i << std::endl;
358 for (
auto x : pointsOnLine)
359 std::cout << x.pos << std::endl;
364 addUpstreamPositions_(i, upstreamPositions, positions, pointsOnLine);
365 addUpstreamCells_(i, upstreamPositions, cells);
367 addCouplingPositions_(i, positions, pointsOnLine, interFacePositions, lowerLeft, upperRight);
368 addCouplingCells_(i, cells, pointsOnLine);
371 const ScalarVector downstreamPositions =
getParamFromGroup<ScalarVector>(modelParamGroup,
"Grid.DownstreamPositions" + std::to_string(i), ScalarVector{});
373 addDownstreamPositions_(i, downstreamPositions, positions, upperRight);
374 addDownstreamCells_(i, downstreamPositions, cells);
377 positions[i].push_back(upperRight[i]);
381 grading[i].resize(positions[i].size()-1, 1.0);
383 addUpstreamGrading_(i, upstreamPositions, grading);
384 addDownstreamGrading_(i, downstreamPositions, positions, grading);
389 if (i != couplingPlaneNormalDirectionIndex)
390 DUNE_THROW(Dune::GridError,
"Something went wrong with the coupling plane normal");
395 addNormalPositions_(i, normalPositions, positions, upperRight);
396 positions[i].push_back(upperRight[i]);
397 addNormalCells_(i, normalPositions, cells);
398 grading[i].resize(positions[i].size()-1, 1.0);
399 addNormalGrading_(i, normalPositions, grading);
402 if (positions[i].size() != cells[i].size() + 1)
403 DUNE_THROW(Dune::GridError,
"Wrong number of cells in " << i);
409 gridConstructionData_ = GridConstructionData{std::move(positions), std::move(cells), std::move(grading), std::move(interFacePositions)};
414 {
return gridConstructionData_; }
422 template<
class Po
intsOnLine>
424 const ScalarVector& upstreamPositions,
425 std::array<ScalarVector, dim>& positions,
426 const PointsOnLine& points)
428 if (!upstreamPositions.empty())
431 for (
const Scalar pos : upstreamPositions)
433 if ((pos < points[0].pos - points[0].radius) && (pos > gridLowerLeft))
436 DUNE_THROW(Dune::RangeError,
"Make sure to set positions only in the inlet");
442 const ScalarVector& upstreamPositions,
443 std::array<IntVector, dim>& cells)
449 if (cellsUpstream.empty())
452 if (cellsUpstream.size() != upstreamPositions.size() + 1)
453 DUNE_THROW(Dumux::ParameterException,
"UpstreamCells" << std::to_string(
directionIndex) <<
" must equal UpstreamPositions" << std::to_string(
directionIndex) <<
" + 1");
455 for (
int c : cellsUpstream)
458 DUNE_THROW(Dumux::ParameterException,
"UpstreamCells" << std::to_string(
directionIndex) <<
" must have values greater than zero.");
464 const ScalarVector& upstreamPositions,
465 std::array<ScalarVector, dim>& grading)
467 if (upstreamPositions.empty())
472 if (!upstreamGrading.empty())
474 if (upstreamGrading.size() != upstreamPositions.size() + 1)
475 DUNE_THROW(Dune::RangeError,
"UpstreamGrading" << std::to_string(
directionIndex) <<
" must equal UpstreamPositions" << std::to_string(
directionIndex) <<
" + 1");
477 for (
int i = 0; i < upstreamPositions.size() + 1; ++i)
487 const ScalarVector& downstreamPositions,
488 std::array<ScalarVector, dim>& gridPositions,
489 const GlobalPosition& gridUpperRight)
491 if (!downstreamPositions.empty())
493 for (
const Scalar pos : downstreamPositions)
498 DUNE_THROW(Dune::RangeError,
"Make sure to set ascending positions only in the outlet");
504 const ScalarVector& downstreamPositions,
505 std::array<IntVector, dim>& cells)
511 if (downstreamcells.empty())
514 if (downstreamcells.size() != downstreamPositions.size() + 1)
515 DUNE_THROW(Dumux::ParameterException,
"DownstreamCells" << std::to_string(
directionIndex) <<
" must equal DownstreamPositions" << std::to_string(
directionIndex) <<
" + 1");
517 for (
int c : downstreamcells)
520 DUNE_THROW(Dumux::ParameterException,
"DownstreamCells" << std::to_string(
directionIndex) <<
" must have values greater than zero.");
526 const ScalarVector& downstreamPositions,
527 std::array<ScalarVector, dim>& gridPositions,
528 std::array<ScalarVector, dim>& grading)
530 if (downstreamPositions.empty())
535 if (!downstreamGrading.empty())
537 if (downstreamGrading.size() != downstreamPositions.size() + 1)
538 DUNE_THROW(Dune::RangeError,
"DownstreamGrading" << std::to_string(
directionIndex) <<
" must equal DownstreamPositions" << std::to_string(
directionIndex) <<
" + 1");
540 const int offSet = gridPositions[
directionIndex].size() - downstreamPositions.size() - 2;
541 for (
int i = 0; i < downstreamPositions.size() + 1; ++i)
550 template<
class Po
intsOnLine>
552 std::array<ScalarVector, dim>& positions,
553 const PointsOnLine& points,
554 std::array<std::optional<ScalarVector>, dim>& interFacePositions,
555 const GlobalPosition& gridLowerLeft,
556 const GlobalPosition& gridUpperRight)
562 for (
const auto& point : points)
564 const auto left = point.pos - point.radius;
565 const auto right = point.pos + point.radius;
568 DUNE_THROW(Dune::RangeError,
"Throat radii are too large, they intersect!");
582 template<
class Po
intsOnLine>
584 std::array<IntVector, dim>& cells,
585 const PointsOnLine& points)
589 const int fixedCellsBetweenThroats =
getParamFromGroup<int>(modelParamGroup_,
"Grid.FixedCellsBetweenThroats", -1);
592 for (
int i = 0; i < points.size(); ++i)
595 if (i < points.size() -1)
597 if (fixedCellsBetweenThroats > 0)
601 const auto spacingLeft = points[i].radius*2.0 / cellsPerThroat;
602 const auto spacingRight = points[i+1].radius*2.0 / cellsPerThroat;
603 const auto avgSpacing = (spacingLeft + spacingRight) / 2;
604 const auto lengthBetween = (points[i+1].pos - (points[i+1].radius))
605 - (points[i].pos + (points[i].radius));
606 const int cellsBetween = std::ceil(lengthBetween / avgSpacing);
618 const ScalarVector& normalPositions,
619 std::array<ScalarVector, dim>& gridPositions,
620 const GlobalPosition& gridUpperRight)
622 if (!normalPositions.empty())
624 for (
const Scalar pos : normalPositions)
629 DUNE_THROW(Dune::RangeError,
"Make sure to set ascending normal positions");
635 const ScalarVector& normalPositions,
636 std::array<IntVector, dim>& cells)
640 if (cellsNormal.size() != normalPositions.size() + 1)
641 DUNE_THROW(Dumux::ParameterException,
"Cells" << std::to_string(
directionIndex) <<
" must be of size " << normalPositions.size() + 1);
643 for (
int c : cellsNormal)
648 const ScalarVector& normalPositions,
649 std::array<ScalarVector, dim>& grading)
653 if (!normalGrading.empty())
655 if (normalGrading.size() != normalPositions.size() + 1)
656 DUNE_THROW(Dune::RangeError,
"Grading" << std::to_string(
directionIndex) <<
" must be of size " << normalPositions.size() + 1);
658 for (
int i = 0; i < normalPositions.size() + 1; ++i)
664 std::string modelParamGroup_ =
"";
665 GridConstructionData gridConstructionData_;