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.");
144 verbose_ = getParamFromGroup<bool>(problem_().paramGroup(),
"FluxOverSurface.Verbose",
false);
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)
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_)
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_;
Class used to calculate fluxes over surfaces. This only works for the staggered grid discretization.
Definition: fluxoversurface.hh:38
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
Detect if a point intersects a geometry.
Create Dune geometries from user-specified points.
constexpr Line line
Definition: couplingmanager1d3d_line.hh:31
constexpr Surface surface
Definition: couplingmanager1d3d_surface.hh:37
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.