12#ifndef DUMUX_FLUX_OVER_SURFACE_STAGGERED_HH 
   13#define DUMUX_FLUX_OVER_SURFACE_STAGGERED_HH 
   20#include <dune/common/exceptions.hh> 
   21#include <dune/common/fvector.hh> 
   22#include <dune/geometry/type.hh> 
   23#include <dune/geometry/multilineargeometry.hh> 
   36template<
class Gr
idVariables, 
class SolutionVector, 
class ModelTraits, 
class LocalRes
idual>
 
   39    using Scalar = 
typename GridVariables::Scalar;
 
   40    using GridGeometry = 
typename GridVariables::GridGeometry;
 
   41    using FVElementGeometry = 
typename GridGeometry::LocalView;
 
   42    using SubControlVolumeFace = 
typename FVElementGeometry::SubControlVolumeFace;
 
   44    using GridView = 
typename GridGeometry::GridView;
 
   45    using VolumeVariables = 
typename GridVariables::VolumeVariables;
 
   46    using Element = 
typename GridView::template Codim<0>::Entity;
 
   48    using CellCenterPrimaryVariables = std::decay_t<decltype(std::declval<SolutionVector>()[GridGeometry::cellCenterIdx()][0])>;
 
   52        dim = GridView::dimension,
 
   53        dimWorld = GridView::dimensionworld
 
   56    using GlobalPosition = 
typename Element::Geometry::GlobalCoordinate;
 
   58    static constexpr auto surfaceDim = dimWorld - 1;
 
   59    using SurfaceGeometryType = Dune::MultiLinearGeometry< Scalar, surfaceDim, dimWorld >;
 
   64    template<
int mydim, 
int coordDim, 
class Scalar=
double>
 
   67        using Geo = SurfaceGeometryType;
 
   72        SurfaceData(Geo&& geo)
 
   75            geometries_.push_back(std::move(geo));
 
   78        SurfaceData(std::vector<Geo>&& geo)
 
   80            values_.resize(geo.size());
 
   81            geometries_ = std::forward<decltype(geo)>(geo);
 
   84        void addValue(
int surfaceIdx, 
const CellCenterPrimaryVariables& value)
 
   86            values_[surfaceIdx] += value;
 
   89        void addSubSurface(Geo&& geo)
 
   91            values_.emplace_back(0.0);
 
   92            geometries_.push_back(std::move(geo));
 
   95        auto& subSurfaces()
 const 
  100        CellCenterPrimaryVariables& value(
int surfaceIdx)
 const 
  102            return values_[surfaceIdx];
 
  110        void printSurfaceBoundaries(
int surfaceIdx)
 const 
  112            const auto& geometry = geometries_[surfaceIdx];
 
  113            for(
int i = 0; i < geometry.corners(); ++i)
 
  114                std::cout << 
"(" << geometry.corner(i) << 
")  ";
 
  119            std::fill(values_.begin(), values_.end(), CellCenterPrimaryVariables(0.0));
 
  124        std::vector<Geo> geometries_;
 
  125        std::vector<CellCenterPrimaryVariables> values_;
 
  138    : gridVariables_(gridVariables),
 
  141        static_assert(std::is_same<Sol, SolutionVector>::value, 
"Make sure that sol has the same type as SolutionVector." 
  142                                                                "Use StaggeredVtkOutputModule<GridVariables, decltype(sol)> when calling the constructor.");
 
 
  155        surfaces_[name] = SurfaceData<surfaceDim,dim>(std::forward<
decltype(surfaces)>(surfaces));
 
 
  166    void addSurface(
const std::string& name, 
const GlobalPosition& p0, 
const GlobalPosition& p1)
 
  168        surfaces_[name].addSubSurface(
makeSurface(std::vector<GlobalPosition>{p0, p1}));
 
 
  182                    const GlobalPosition& p0,
 
  183                    const GlobalPosition& p1,
 
  184                    const GlobalPosition& p2,
 
  185                    const GlobalPosition& p3)
 
  187        surfaces_[name].addSubSurface(
makeSurface(std::vector<GlobalPosition>{p0, p1, p2, p3}));
 
 
  195    static SurfaceGeometryType 
makeSurface(
const std::vector<Dune::FieldVector<Scalar, 2>>& corners)
 
  197            return SurfaceGeometryType(Dune::GeometryTypes::line, corners);
 
 
  205    static SurfaceGeometryType 
makeSurface(
const std::vector<Dune::FieldVector<Scalar, 3>>& corners)
 
 
  215        auto fluxType = [
this](
const auto& element,
 
  216                               const auto& fvGeometry,
 
  217                               const auto& elemVolVars,
 
  218                               const auto& elemFaceVars,
 
  220                               const auto& elemFluxVarsCache)
 
  222            LocalResidual localResidual(&problem_());
 
  225                return localResidual.computeBoundaryFluxForCellCenter(problem_(), element, fvGeometry, scvf, elemVolVars, elemFaceVars, {}, elemFluxVarsCache);
 
  227                return localResidual.computeFluxForCellCenter(problem_(), element, fvGeometry, elemVolVars, elemFaceVars, scvf, elemFluxVarsCache);
 
 
  238        auto fluxType = [](
const auto& element,
 
  239                           const auto& fvGeometry,
 
  240                           const auto& elemVolVars,
 
  241                           const auto& elemFaceVars,
 
  243                           const auto& elemFluxVarsCache)
 
  245            CellCenterPrimaryVariables result(0.0);
 
  246            const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
 
  247            const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
 
  248            const Scalar extrusionFactor = 
harmonicMean(insideVolVars.extrusionFactor(), outsideVolVars.extrusionFactor());
 
  249            result[0] = elemFaceVars[scvf].velocitySelf() * Extrusion::area(fvGeometry, scvf) * extrusionFactor * scvf.directionSign();
 
 
  268    template<
class FluxType>
 
  272        for(
auto&& surface : surfaces_)
 
  273            surface.second.resetValues();
 
  276        std::vector<bool> dofVisited(problem_().gridGeometry().numFaceDofs(), 
false);
 
  278        auto fvGeometry = 
localView(problem_().gridGeometry());
 
  279        auto elemVolVars = 
localView(gridVariables_.curGridVolVars());
 
  280        auto elemFaceVars = 
localView(gridVariables_.curGridFaceVars());
 
  281        auto elemFluxVarsCache = 
localView(gridVariables_.gridFluxVarsCache());
 
  283        for(
auto&& element : elements(problem_().gridGeometry().gridView()))
 
  285            fvGeometry.bind(element);
 
  286            elemVolVars.bind(element, fvGeometry, sol_);
 
  287            elemFaceVars.bind(element, fvGeometry, sol_);
 
  288            elemFluxVarsCache.bind(element, fvGeometry, elemVolVars);
 
  290            for(
auto && scvf : scvfs(fvGeometry))
 
  292                const auto dofIdx = scvf.dofIndex();
 
  294                if(dofVisited[dofIdx])
 
  297                dofVisited[dofIdx] = 
true;
 
  301                for(
auto&& surface : surfaces_)
 
  303                    const auto& subSurfaces = surface.second.subSurfaces();
 
  305                    for(
int surfaceIdx = 0; surfaceIdx < subSurfaces.size(); ++surfaceIdx)
 
  309                            const auto result = fluxType(element, fvGeometry, elemVolVars, elemFaceVars, scvf, elemFluxVarsCache);
 
  311                            surface.second.addValue(surfaceIdx, result);
 
  315                                std::cout << 
"Flux at face "  << scvf.center() << 
" (" << surface.first << 
"): " << result;
 
  316                                std::cout << 
" (directionIndex: " << scvf.directionIndex() << 
"; surface boundaries: ";
 
  317                                surface.second.printSurfaceBoundaries(surfaceIdx);
 
  318                                std::cout << 
", surfaceIdx " << surfaceIdx << 
")" << std::endl;
 
 
  332    auto& 
values(
const std::string& name)
 const 
  334        return surfaces_.at(name).values();
 
 
  344        const auto& surfaceResults = 
values(name);
 
  345        return std::accumulate(surfaceResults.begin(), surfaceResults.end(), CellCenterPrimaryVariables(0.0));
 
 
  350    const auto& problem_()
 const { 
return gridVariables_.curGridVolVars().problem(); }
 
  352    std::map<std::string, SurfaceData<surfaceDim ,dim> > surfaces_;
 
  353    const GridVariables& gridVariables_;
 
  354    const SolutionVector& sol_;
 
 
std::vector< SurfaceGeometryType > SurfaceList
Definition fluxoversurface.hh:130
auto & values(const std::string &name) const
Return the fluxes of the individual sub surface of a given name.
Definition fluxoversurface.hh:332
void addSurface(const std::string &name, const GlobalPosition &p0, const GlobalPosition &p1)
Add a surface under a given name, specifying the surface's corner points. This is a specialization fo...
Definition fluxoversurface.hh:166
void calculateVolumeFluxes()
Calculate the volume fluxes over all surfaces.
Definition fluxoversurface.hh:236
void addSurface(const std::string &name, SurfaceList &&surfaces)
Add a collection of sub surfaces under a given name.
Definition fluxoversurface.hh:153
auto netFlux(const std::string &name) const
Return the cumulative net fluxes of a surface of a given name.
Definition fluxoversurface.hh:342
static SurfaceGeometryType makeSurface(const std::vector< Dune::FieldVector< Scalar, 2 > > &corners)
Creates a geometrical surface object for (2D).
Definition fluxoversurface.hh:195
void addSurface(const std::string &name, const GlobalPosition &p0, const GlobalPosition &p1, const GlobalPosition &p2, const GlobalPosition &p3)
Add a surface under a given name, specifying the surface's corner points. This is a specialization fo...
Definition fluxoversurface.hh:181
void calculateMassOrMoleFluxes()
Calculate the mass or mole fluxes over all surfaces.
Definition fluxoversurface.hh:213
FluxOverSurface(const GridVariables &gridVariables, const Sol &sol)
The constructor.
Definition fluxoversurface.hh:136
static SurfaceGeometryType makeSurface(const std::vector< Dune::FieldVector< Scalar, 3 > > &corners)
Creates a geometrical surface object for (3D).
Definition fluxoversurface.hh:205
void calculateFluxes(const FluxType &fluxType)
Calculate the fluxes over all surfaces for a given flux type.
Definition fluxoversurface.hh:269
Helper classes to compute the integration elements.
constexpr Scalar harmonicMean(Scalar x, Scalar y, Scalar wx=1.0, Scalar wy=1.0) noexcept
Calculate the (weighted) harmonic mean of two scalar values.
Definition math.hh:57
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
auto makeDuneQuadrilaterial(const std::vector< Dune::FieldVector< CoordScalar, 3 > > &points)
Creates a dune quadrilateral geometry given 4 corner points.
Definition makegeometry.hh:142
bool intersectsPointGeometry(const Dune::FieldVector< ctype, dimworld > &point, const Geometry &g)
Find out whether a point is inside a three-dimensional geometry.
Definition intersectspointgeometry.hh:28
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:149
Detect if a point intersects a geometry.
Create Dune geometries from user-specified points.
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:166
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.