282class SnappyGridManager : 
public Dumux::GridManager<Dune::YaspGrid<dim, Dune::TensorProductCoordinates<typename OtherGridCreator::Grid::ctype, OtherGridCreator::Grid::LeafGridView::dimensionworld>>>
 
  284    using Scalar = 
typename OtherGridCreator::Grid::ctype;
 
  285    using OtherGrid = 
typename OtherGridCreator::Grid;
 
  286    using IntVector = std::vector<int>;
 
  287    using ScalarVector = std::vector<Scalar>;
 
  289    static constexpr auto dimWorld = OtherGrid::LeafGridView::dimensionworld;
 
  290    using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
 
  293    using LowDimGridData = 
typename OtherGridCreator::GridData;
 
  295    struct GridConstructionData
 
  297            std::array<ScalarVector, dim> positions;
 
  298            std::array<IntVector, dim> cells;
 
  299            std::array<ScalarVector, dim> grading;
 
  300            std::array<std::optional<ScalarVector>, dim> interfacePositions;
 
  305    using ParentType::ParentType;
 
  308    void init(
const OtherGrid& otherGrid, 
const LowDimGridData& otherData, 
const std::string& modelParamGroup = 
"")
 
  310        modelParamGroup_ = modelParamGroup;
 
  311        std::array<ScalarVector, dim> positions;
 
  312        std::array<IntVector, dim> cells;
 
  313        std::array<ScalarVector, dim> grading;
 
  314        std::array<std::optional<ScalarVector>, dim> interFacePositions;
 
  321                                                                                  "Grid.CouplinglineNormal",
 
  322                                                                                  [](){ GlobalPosition tmp(0.0); tmp[tmp.size()-1] = 1.0; 
return tmp; }());
 
  324        const auto couplingPlaneNormalDirectionIndex = SnappyGridManagerHelper::directionIndex(couplingPlaneNormal);
 
  325        const auto couplingPlane = SnappyGridManagerHelper::makeCouplingPlane(lowerLeft, upperRight, couplingPlaneNormal, modelParamGroup);
 
  327        std::cout << 
"plane: \n";
 
  328        for (
int i = 0; i < couplingPlane.corners(); ++i)
 
  329            std::cout << couplingPlane.corner(i) << std::endl;
 
  331        const auto pointsOnAxisParallelLines = SnappyGridManagerHelper::getPointsOnLine(lowerLeft, upperRight, couplingPlaneNormal, otherGrid.leafGridView(), otherData, modelParamGroup_);
 
  333        for (
int i = 0; i < dim; ++i)
 
  336            positions[i].push_back(lowerLeft[i]);
 
  338            if (i != couplingPlaneNormalDirectionIndex) 
 
  340                if (!pointsOnAxisParallelLines[i].has_value())
 
  341                    DUNE_THROW(Dune::GridError, 
"Something went wrong with the coupling plane normal");
 
  343                const auto& pointsOnLine = (*pointsOnAxisParallelLines[i]);
 
  345                std::cout << 
"point " << i << std::endl;
 
  346                for (
auto x : pointsOnLine)
 
  347                    std::cout << x.pos << std::endl;
 
  352                addUpstreamPositions_(i, upstreamPositions, positions, pointsOnLine);
 
  353                addUpstreamCells_(i, upstreamPositions, cells);
 
  355                addCouplingPositions_(i, positions, pointsOnLine, interFacePositions, lowerLeft, upperRight);
 
  356                addCouplingCells_(i, cells, pointsOnLine);
 
  359                const ScalarVector downstreamPositions = 
getParamFromGroup<ScalarVector>(modelParamGroup, 
"Grid.DownstreamPositions" + std::to_string(i), ScalarVector{});
 
  361                addDownstreamPositions_(i, downstreamPositions, positions, upperRight);
 
  362                addDownstreamCells_(i, downstreamPositions, cells);
 
  365                positions[i].push_back(upperRight[i]);
 
  369                grading[i].resize(positions[i].size()-1, 1.0);
 
  371                addUpstreamGrading_(i, upstreamPositions, grading);
 
  372                addDownstreamGrading_(i, downstreamPositions, positions, grading);
 
  377                if (i != couplingPlaneNormalDirectionIndex)
 
  378                    DUNE_THROW(Dune::GridError, 
"Something went wrong with the coupling plane normal");
 
  383                addNormalPositions_(i, normalPositions, positions, upperRight);
 
  384                positions[i].push_back(upperRight[i]);
 
  385                addNormalCells_(i, normalPositions, cells);
 
  386                grading[i].resize(positions[i].size()-1, 1.0);
 
  387                addNormalGrading_(i, normalPositions, grading);
 
  390            if (positions[i].size() != cells[i].size() + 1)
 
  391                DUNE_THROW(Dune::GridError, 
"Wrong number of cells in " << i);
 
  397        gridConstructionData_ = GridConstructionData{std::move(positions), std::move(cells), std::move(grading), std::move(interFacePositions)};
 
 
  402    { 
return gridConstructionData_; }
 
 
  410    template<
class Po
intsOnLine>
 
  412                               const ScalarVector& upstreamPositions,
 
  413                               std::array<ScalarVector, dim>& positions,
 
  414                               const PointsOnLine& points)
 
  416        if (!upstreamPositions.empty())
 
  419            for (
const Scalar pos : upstreamPositions)
 
  421                if ((pos < points[0].pos - points[0].radius) && (pos > gridLowerLeft))
 
  424                    DUNE_THROW(Dune::RangeError, 
"Make sure to set positions only in the inlet");
 
  430                           const ScalarVector& upstreamPositions,
 
  431                           std::array<IntVector, dim>& cells)
 
  437        if (cellsUpstream.empty())
 
  440        if (cellsUpstream.size() != upstreamPositions.size() + 1)
 
  441            DUNE_THROW(Dumux::ParameterException, 
"UpstreamCells" << std::to_string(
directionIndex) << 
" must equal UpstreamPositions" << std::to_string(
directionIndex) <<  
" + 1");
 
  443        for (
int c : cellsUpstream)
 
  446                DUNE_THROW(Dumux::ParameterException, 
"UpstreamCells" << std::to_string(
directionIndex) << 
" must have values greater than zero.");
 
  452                             const ScalarVector& upstreamPositions,
 
  453                             std::array<ScalarVector, dim>& grading)
 
  455        if (upstreamPositions.empty())
 
  460        if (!upstreamGrading.empty())
 
  462            if (upstreamGrading.size() != upstreamPositions.size() + 1)
 
  463                DUNE_THROW(Dune::RangeError, 
"UpstreamGrading"  << std::to_string(
directionIndex) << 
" must equal UpstreamPositions" << std::to_string(
directionIndex) <<  
" + 1");
 
  465            for (
int i = 0; i < upstreamPositions.size() + 1; ++i)
 
  475                                 const ScalarVector& downstreamPositions,
 
  476                                 std::array<ScalarVector, dim>& gridPositions,
 
  477                                 const GlobalPosition& gridUpperRight)
 
  479        if (!downstreamPositions.empty())
 
  481            for (
const Scalar pos : downstreamPositions)
 
  486                    DUNE_THROW(Dune::RangeError, 
"Make sure to set ascending positions only in the outlet");
 
  492                             const ScalarVector& downstreamPositions,
 
  493                             std::array<IntVector, dim>& cells)
 
  499        if (downstreamcells.empty())
 
  502        if (downstreamcells.size() != downstreamPositions.size() + 1)
 
  503            DUNE_THROW(Dumux::ParameterException, 
"DownstreamCells" << std::to_string(
directionIndex) << 
" must equal DownstreamPositions" << std::to_string(
directionIndex) <<  
" + 1");
 
  505        for (
int c : downstreamcells)
 
  508                DUNE_THROW(Dumux::ParameterException, 
"DownstreamCells" << std::to_string(
directionIndex) << 
" must have values greater than zero.");
 
  514                               const ScalarVector& downstreamPositions,
 
  515                               std::array<ScalarVector, dim>& gridPositions,
 
  516                               std::array<ScalarVector, dim>& grading)
 
  518        if (downstreamPositions.empty())
 
  523        if (!downstreamGrading.empty())
 
  525            if (downstreamGrading.size() != downstreamPositions.size() + 1)
 
  526                DUNE_THROW(Dune::RangeError, 
"DownstreamGrading"  << std::to_string(
directionIndex) << 
" must equal DownstreamPositions" << std::to_string(
directionIndex) <<  
" + 1");
 
  528            const int offSet = gridPositions[
directionIndex].size() - downstreamPositions.size() - 2;
 
  529            for (
int i = 0; i < downstreamPositions.size() + 1; ++i)
 
  538    template<
class Po
intsOnLine>
 
  540                               std::array<ScalarVector, dim>& positions,
 
  541                               const PointsOnLine& points,
 
  542                               std::array<std::optional<ScalarVector>, dim>& interFacePositions,
 
  543                               const GlobalPosition& gridLowerLeft,
 
  544                               const GlobalPosition& gridUpperRight)
 
  550        for (
const auto& point : points)
 
  552            const auto left = point.pos - point.radius;
 
  553            const auto right = point.pos + point.radius;
 
  556                DUNE_THROW(Dune::RangeError, 
"Pore body radii are too large, they intersect!");
 
  570    template<
class Po
intsOnLine>
 
  572                           std::array<IntVector, dim>& cells,
 
  573                           const PointsOnLine& points)
 
  577        const int fixedCellsBetweenPores = 
getParamFromGroup<int>(modelParamGroup_, 
"Grid.FixedCellsBetweenPores", -1);
 
  580        for (
int i = 0; i < points.size(); ++i)
 
  583            if (i < points.size() -1)
 
  585                if (fixedCellsBetweenPores > 0)
 
  591                    const auto spacingLeft = points[i].radius*2.0 / cellsPerPore;
 
  592                    const auto spacingRight = points[i+1].radius*2.0 / cellsPerPore;
 
  593                    const auto avgSpacing = (spacingLeft + spacingRight) / 2;
 
  594                    const auto lengthBetween = (points[i+1].pos - (points[i+1].radius))
 
  595                                             - (points[i].pos + (points[i].radius));
 
  596                    const int cellsBetween = std::ceil(lengthBetween / avgSpacing);
 
  608                             const ScalarVector& normalPositions,
 
  609                             std::array<ScalarVector, dim>& gridPositions,
 
  610                             const GlobalPosition& gridUpperRight)
 
  612        if (!normalPositions.empty())
 
  614            for (
const Scalar pos : normalPositions)
 
  619                    DUNE_THROW(Dune::RangeError, 
"Make sure to set ascending normal positions");
 
  625                         const ScalarVector& normalPositions,
 
  626                         std::array<IntVector, dim>& cells)
 
  630        if (cellsNormal.size() != normalPositions.size() + 1)
 
  631            DUNE_THROW(Dumux::ParameterException, 
"Cells" << std::to_string(
directionIndex) << 
" must be of size " << normalPositions.size() + 1);
 
  633        for (
int c : cellsNormal)
 
  638                           const ScalarVector& normalPositions,
 
  639                           std::array<ScalarVector, dim>& grading)
 
  643        if (!normalGrading.empty())
 
  645            if (normalGrading.size() != normalPositions.size() + 1)
 
  646                DUNE_THROW(Dune::RangeError, 
"Grading"  << std::to_string(
directionIndex) << 
" must be of size " << normalPositions.size() + 1);
 
  648            for (
int i = 0; i < normalPositions.size() + 1; ++i)
 
  654    std::string modelParamGroup_ = 
"";
 
  655    GridConstructionData gridConstructionData_;