24#ifndef DUMUX_DISCRETIZATION_CC_TPFA_FACET_COUPLING_DARCYS_LAW_HH
25#define DUMUX_DISCRETIZATION_CC_TPFA_FACET_COUPLING_DARCYS_LAW_HH
30#include <dune/common/float_cmp.hh>
43template<
class ScalarType,
class Gr
idGeometry,
bool isNetwork>
52template<
class AdvectionType,
class Gr
idGeometry,
bool isNetwork>
61template<
class ScalarType,
class Gr
idGeometry>
64 int(GridGeometry::GridView::dimensionworld) ) >;
70template<
class AdvectionType,
class Gr
idGeometry>
73 using Scalar =
typename AdvectionType::Scalar;
74 using FVElementGeometry =
typename GridGeometry::LocalView;
75 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
76 using Element =
typename GridGeometry::GridView::template Codim<0>::Entity;
85 static constexpr int insideTijIdx = 0;
86 static constexpr int outsideTijIdx = 1;
87 static constexpr int facetTijIdx = 2;
96 template<
class Problem,
class ElementVolumeVariables >
98 const Element& element,
99 const FVElementGeometry& fvGeometry,
100 const ElementVolumeVariables& elemVolVars,
101 const SubControlVolumeFace &scvf)
103 tij_ = AdvectionType::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g_);
111 {
return tij_[insideTijIdx]; }
115 {
return tij_[insideTijIdx]; }
119 {
return tij_[outsideTijIdx]; }
123 {
return tij_[facetTijIdx]; }
130 std::array<Scalar, 3> tij_;
131 GravityCoefficients g_;
138template<
class ScalarType,
class Gr
idGeometry>
144 using FVElementGeometry =
typename GridGeometry::LocalView;
145 using SubControlVolume =
typename GridGeometry::SubControlVolume;
146 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
148 using GridView =
typename GridGeometry::GridView;
149 using Element =
typename GridView::template Codim<0>::Entity;
150 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
160 using TijContainer =
typename Cache::AdvectionTransmissibilityContainer;
164 template<
class Problem,
class ElementVolumeVariables,
class ElementFluxVarsCache >
166 const Element& element,
167 const FVElementGeometry& fvGeometry,
168 const ElementVolumeVariables& elemVolVars,
169 const SubControlVolumeFace& scvf,
171 const ElementFluxVarsCache& elemFluxVarsCache)
173 if (!problem.couplingManager().isOnInteriorBoundary(element, scvf))
174 return TpfaDarcysLaw::flux(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, elemFluxVarsCache);
177 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
178 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
179 const auto pInside = insideVolVars.pressure(phaseIdx);
180 const auto pFacet = facetVolVars.pressure(phaseIdx);
183 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
184 Scalar flux = fluxVarsCache.advectionTijInside()*pInside + fluxVarsCache.advectionTijFacet()*pFacet;
187 static const Scalar gravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
191 const auto& g = problem.spatialParams().gravity(scvf.ipGlobal());
192 const auto rho = 0.5*(insideVolVars.density(phaseIdx) + facetVolVars.density(phaseIdx));
193 const auto rhoTimesArea = rho*scvf.area();
194 const auto alpha_inside = rhoTimesArea*insideVolVars.extrusionFactor()
195 *
vtmv(scvf.unitOuterNormal(), insideVolVars.permeability(), g);
197 flux += alpha_inside;
198 if (!scvf.boundary())
200 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
203 if ( problem.interiorBoundaryTypes(element, scvf).hasOnlyNeumann() )
205 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
206 const auto alpha_facet = rhoTimesArea*insideVolVars.extrusionFactor()
207 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), g);
208 const auto alpha_outside = rhoTimesArea*outsideVolVars.extrusionFactor()
209 *
vtmv(scvf.unitOuterNormal(), outsideVolVars.permeability(), g);
211 flux -= fluxVarsCache.gravityCoefficients()[0]*(xi*alpha_inside - alpha_facet + (1.0 - xi)*alpha_outside);
212 flux += fluxVarsCache.gravityCoefficients()[1]*(xi*alpha_outside - alpha_facet + (1.0 - xi)*alpha_inside);
216 flux += fluxVarsCache.advectionTijOutside()*outsideVolVars.pressure(phaseIdx);
222 return scvf.boundary() ? flux
223 : flux + fluxVarsCache.advectionTijOutside()*elemVolVars[scvf.outsideScvIdx()].pressure(phaseIdx);
228 template<
class Problem,
class ElementVolumeVariables >
230 const Element& element,
231 const FVElementGeometry& fvGeometry,
232 const ElementVolumeVariables& elemVolVars,
233 const SubControlVolumeFace& scvf)
235 typename Cache::GravityCoefficients g;
236 return calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g);
241 template<
class Problem,
class ElementVolumeVariables >
243 const Element& element,
244 const FVElementGeometry& fvGeometry,
245 const ElementVolumeVariables& elemVolVars,
246 const SubControlVolumeFace& scvf,
247 typename Cache::GravityCoefficients& g)
250 if (!problem.couplingManager().isCoupled(element, scvf))
253 tij[Cache::insideTijIdx] = TpfaDarcysLaw::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf);
258 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
260 const auto insideScvIdx = scvf.insideScvIdx();
261 const auto& insideScv = fvGeometry.scv(insideScvIdx);
262 const auto& insideVolVars = elemVolVars[insideScvIdx];
265 insideVolVars.permeability(),
266 insideVolVars.extrusionFactor());
269 const auto iBcTypes = problem.interiorBoundaryTypes(element, scvf);
272 if (iBcTypes.hasOnlyNeumann())
274 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
275 const auto wFacet = 2.0*scvf.area()*insideVolVars.extrusionFactor()
276 /facetVolVars.extrusionFactor()
277 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), scvf.unitOuterNormal());
286 if (!scvf.boundary())
288 const auto outsideScvIdx = scvf.outsideScvIdx();
289 const auto& outsideVolVars = elemVolVars[outsideScvIdx];
291 fvGeometry.scv(outsideScvIdx),
292 outsideVolVars.permeability(),
293 outsideVolVars.extrusionFactor());
295 if ( !Dune::FloatCmp::eq(xi, 1.0, 1e-6) )
302 const Scalar xiMinusOne = (xi - 1.0);
303 const Scalar a01 = xiMinusOne*wOut;
304 const Scalar a11 = xi*wOut + wFacet;
305 const Scalar detA = (xi*wIn + wFacet)*a11 - xiMinusOne*wIn*a01;
306 g[0] = wIn*a11/detA; g[1] = -wIn*a01/detA;
309 const Scalar factor = wIn * wFacet / ( wIn * wOut * ( 2.0 * xi - 1.0 ) + wFacet * ( xi * ( wIn + wOut ) + wFacet ) );
310 tij[Cache::insideTijIdx] = factor * ( wOut * xi + wFacet );
311 tij[Cache::outsideTijIdx] = factor * ( wOut * ( 1.0 - xi ) );
312 tij[Cache::facetTijIdx] = factor * ( - wOut - wFacet );
316 g[0] = wIn/(wIn+wFacet); g[1] = 0.0;
317 tij[Cache::insideTijIdx] = wFacet*g[0];
318 tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
319 tij[Cache::outsideTijIdx] = 0.0;
325 tij[Cache::insideTijIdx] = wFacet*wIn/(wIn+wFacet);
326 tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
327 tij[Cache::outsideTijIdx] = 0.0;
330 else if (iBcTypes.hasOnlyDirichlet())
332 tij[Cache::insideTijIdx] = wIn;
333 tij[Cache::outsideTijIdx] = 0.0;
334 tij[Cache::facetTijIdx] = -wIn;
337 DUNE_THROW(Dune::NotImplemented,
"Interior boundary types other than pure Dirichlet or Neumann");
347template<
class AdvectionType,
class Gr
idGeometry>
350 using Scalar =
typename AdvectionType::Scalar;
351 using FVElementGeometry =
typename GridGeometry::LocalView;
352 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
353 using Element =
typename GridGeometry::GridView::template Codim<0>::Entity;
362 static constexpr int insideTijIdx = 0;
363 static constexpr int facetTijIdx = 1;
369 template<
class Problem,
class ElementVolumeVariables >
371 const Element& element,
372 const FVElementGeometry& fvGeometry,
373 const ElementVolumeVariables& elemVolVars,
374 const SubControlVolumeFace &scvf)
376 tij_ = AdvectionType::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf);
384 {
return tij_[insideTijIdx]; }
388 {
return tij_[insideTijIdx]; }
392 {
return tij_[facetTijIdx]; }
395 AdvectionTransmissibilityContainer tij_;
402template<
class ScalarType,
class Gr
idGeometry>
408 using FVElementGeometry =
typename GridGeometry::LocalView;
409 using SubControlVolume =
typename GridGeometry::SubControlVolume;
410 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
412 using GridView =
typename GridGeometry::GridView;
413 using Element =
typename GridView::template Codim<0>::Entity;
414 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
424 using TijContainer =
typename Cache::AdvectionTransmissibilityContainer;
427 template<
class Problem,
class ElementVolumeVariables,
class ElementFluxVarsCache >
429 const Element& element,
430 const FVElementGeometry& fvGeometry,
431 const ElementVolumeVariables& elemVolVars,
432 const SubControlVolumeFace& scvf,
434 const ElementFluxVarsCache& elemFluxVarsCache)
436 static const Scalar gravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
438 DUNE_THROW(Dune::NotImplemented,
"Gravity for darcys law with facet coupling on surface grids");
440 if (!problem.couplingManager().isOnInteriorBoundary(element, scvf))
441 return TpfaDarcysLaw::flux(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, elemFluxVarsCache);
444 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
445 const auto pInside = insideVolVars.pressure(phaseIdx);
446 const auto pFacet = problem.couplingManager().getLowDimVolVars(element, scvf).pressure(phaseIdx);
449 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
451 return fluxVarsCache.advectionTijInside()*pInside + fluxVarsCache.advectionTijFacet()*pFacet;
453 return fluxVarsCache.advectionTijInside()*pInside + fluxVarsCache.advectionTijFacet()*pFacet;
458 template<
class Problem,
class ElementVolumeVariables >
460 const Element& element,
461 const FVElementGeometry& fvGeometry,
462 const ElementVolumeVariables& elemVolVars,
463 const SubControlVolumeFace& scvf)
466 if (!problem.couplingManager().isCoupled(element, scvf))
469 tij[Cache::insideTijIdx] = TpfaDarcysLaw::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf);
474 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
479 if (Dune::FloatCmp::ne(xi, 1.0, 1e-6))
480 DUNE_THROW(Dune::InvalidStateException,
"Xi != 1.0 cannot be used on surface grids");
482 const auto area = scvf.area();
483 const auto insideScvIdx = scvf.insideScvIdx();
484 const auto& insideScv = fvGeometry.scv(insideScvIdx);
485 const auto& insideVolVars = elemVolVars[insideScvIdx];
489 const auto iBcTypes = problem.interiorBoundaryTypes(element, scvf);
492 if (iBcTypes.hasOnlyNeumann())
494 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
499 const auto wFacet = 2.0*area*insideVolVars.extrusionFactor()
500 /sqrt(facetVolVars.extrusionFactor())
501 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), scvf.unitOuterNormal());
504 tij[Cache::insideTijIdx] = wFacet*wIn/(wIn+wFacet);
505 tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
507 else if (iBcTypes.hasOnlyDirichlet())
509 tij[Cache::insideTijIdx] = wIn;
510 tij[Cache::facetTijIdx] = -wIn;
513 DUNE_THROW(Dune::NotImplemented,
"Interior boundary types other than pure Dirichlet or Neumann");
Define some often used mathematical functions.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
The available discretization methods in Dumux.
DiscretizationMethod
The available discretization methods in Dumux.
Definition: method.hh:37
Tensor::field_type computeTpfaTransmissibility(const SubControlVolumeFace &scvf, const SubControlVolume &scv, const Tensor &T, typename SubControlVolume::Traits::Scalar extrusionFactor)
Free function to evaluate the Tpfa transmissibility associated with the flux (in the form of flux = T...
Definition: tpfa/computetransmissibility.hh:47
Dune::DenseMatrix< MAT >::value_type vtmv(const Dune::DenseVector< V1 > &v1, const Dune::DenseMatrix< MAT > &M, const Dune::DenseVector< V2 > &v2)
Evaluates the scalar product of a vector v2, projected by a matrix M, with a vector v1.
Definition: math.hh:840
Class that fills the cache corresponding to tpfa Darcy's Law.
Definition: flux/cctpfa/darcyslaw.hh:69
Specialization of the CCTpfaDarcysLaw grids where dim=dimWorld.
Definition: flux/cctpfa/darcyslaw.hh:129
Specialization of the CCTpfaDarcysLaw grids where dim < dimWorld (network/surface grids)
Definition: flux/cctpfa/darcyslaw.hh:283
Forward declaration of the implementation.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:44
The cache corresponding to tpfa Darcy's Law with facet coupling.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:53
const GravityCoefficients & gravityCoefficients() const
return the coefficients for the computation of gravity at the scvf
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:126
std::array< Scalar, 3 > AdvectionTransmissibilityContainer
Export transmissibility storage type.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:90
Scalar advectionTijInside() const
returns the transmissibility associated with the inside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:114
std::array< Scalar, 2 > GravityCoefficients
Export the type used for the gravity coefficients.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:93
void updateAdvection(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf)
update subject to a given problem
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:97
Scalar advectionTijOutside() const
returns the transmissibility associated with the outside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:118
Scalar advectionTijFacet() const
returns the transmissibility associated with the outside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:122
Scalar advectionTij() const
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:110
Specialization of CCTpfaFacetCouplingDarcysLawImpl for dim=dimWorld.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:140
static Scalar flux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf, int phaseIdx, const ElementFluxVarsCache &elemFluxVarsCache)
Compute the advective flux.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:165
ScalarType Scalar
state the scalar type of the law
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:154
static TijContainer calculateTransmissibility(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf)
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:229
static TijContainer calculateTransmissibility(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf, typename Cache::GravityCoefficients &g)
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:242
typename Cache::AdvectionTransmissibilityContainer TijContainer
export the type used to store transmissibilities
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:160
std::array< Scalar, 2 > AdvectionTransmissibilityContainer
Export transmissibility storage type.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:366
Scalar advectionTij() const
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:383
Scalar advectionTijInside() const
returns the transmissibility associated with the inside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:387
void updateAdvection(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf)
update subject to a given problem
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:370
Scalar advectionTijFacet() const
returns the transmissibility associated with the outside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:391
Specialization of CCTpfaFacetCouplingDarcysLawImpl for dim<dimWorld.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:404
static TijContainer calculateTransmissibility(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf)
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:459
typename Cache::AdvectionTransmissibilityContainer TijContainer
export the type used to store transmissibilities
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:424
ScalarType Scalar
state the scalar type of the law
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:418
static Scalar flux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf, int phaseIdx, const ElementFluxVarsCache &elemFluxVarsCache)
Compute the advective flux.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:428
Free functions to evaluate the transmissibilities associated with flux evaluations across sub-control...
Darcy's law for cell-centered finite volume schemes with two-point flux approximation.
Declares all properties used in Dumux.