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>
44template<
class ScalarType,
class Gr
idGeometry,
bool isNetwork>
53template<
class AdvectionType,
class Gr
idGeometry,
bool isNetwork>
62template<
class ScalarType,
class Gr
idGeometry>
65 int(GridGeometry::GridView::dimensionworld) ) >;
71template<
class AdvectionType,
class Gr
idGeometry>
74 using Scalar =
typename AdvectionType::Scalar;
75 using FVElementGeometry =
typename GridGeometry::LocalView;
76 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
77 using Element =
typename GridGeometry::GridView::template Codim<0>::Entity;
86 static constexpr int insideTijIdx = 0;
87 static constexpr int outsideTijIdx = 1;
88 static constexpr int facetTijIdx = 2;
97 template<
class Problem,
class ElementVolumeVariables >
99 const Element& element,
100 const FVElementGeometry& fvGeometry,
101 const ElementVolumeVariables& elemVolVars,
102 const SubControlVolumeFace &scvf)
104 tij_ = AdvectionType::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g_);
112 {
return tij_[insideTijIdx]; }
116 {
return tij_[insideTijIdx]; }
120 {
return tij_[outsideTijIdx]; }
124 {
return tij_[facetTijIdx]; }
131 std::array<Scalar, 3> tij_;
132 GravityCoefficients g_;
139template<
class ScalarType,
class Gr
idGeometry>
145 using FVElementGeometry =
typename GridGeometry::LocalView;
146 using SubControlVolume =
typename GridGeometry::SubControlVolume;
147 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
150 using GridView =
typename GridGeometry::GridView;
151 using Element =
typename GridView::template Codim<0>::Entity;
152 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
162 using TijContainer =
typename Cache::AdvectionTransmissibilityContainer;
166 template<
class Problem,
class ElementVolumeVariables,
class ElementFluxVarsCache >
168 const Element& element,
169 const FVElementGeometry& fvGeometry,
170 const ElementVolumeVariables& elemVolVars,
171 const SubControlVolumeFace& scvf,
173 const ElementFluxVarsCache& elemFluxVarsCache)
175 if (!problem.couplingManager().isOnInteriorBoundary(element, scvf))
176 return TpfaDarcysLaw::flux(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, elemFluxVarsCache);
179 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
180 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
181 const auto pInside = insideVolVars.pressure(phaseIdx);
182 const auto pFacet = facetVolVars.pressure(phaseIdx);
185 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
186 Scalar flux = fluxVarsCache.advectionTijInside()*pInside + fluxVarsCache.advectionTijFacet()*pFacet;
189 static const Scalar gravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
193 const auto& g = problem.spatialParams().gravity(scvf.ipGlobal());
194 const auto rho = 0.5*(insideVolVars.density(phaseIdx) + facetVolVars.density(phaseIdx));
195 const auto rhoTimesArea = rho*Extrusion::area(scvf);
196 const auto alpha_inside = rhoTimesArea*insideVolVars.extrusionFactor()
197 *
vtmv(scvf.unitOuterNormal(), insideVolVars.permeability(), g);
199 flux += alpha_inside;
200 if (!scvf.boundary())
202 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
205 if ( problem.interiorBoundaryTypes(element, scvf).hasOnlyNeumann() )
207 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
208 const auto alpha_facet = rhoTimesArea*insideVolVars.extrusionFactor()
209 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), g);
210 const auto alpha_outside = rhoTimesArea*outsideVolVars.extrusionFactor()
211 *
vtmv(scvf.unitOuterNormal(), outsideVolVars.permeability(), g);
213 flux -= fluxVarsCache.gravityCoefficients()[0]*(xi*alpha_inside - alpha_facet + (1.0 - xi)*alpha_outside);
214 flux += fluxVarsCache.gravityCoefficients()[1]*(xi*alpha_outside - alpha_facet + (1.0 - xi)*alpha_inside);
218 flux += fluxVarsCache.advectionTijOutside()*outsideVolVars.pressure(phaseIdx);
224 return scvf.boundary() ? flux
225 : flux + fluxVarsCache.advectionTijOutside()*elemVolVars[scvf.outsideScvIdx()].pressure(phaseIdx);
230 template<
class Problem,
class ElementVolumeVariables >
232 const Element& element,
233 const FVElementGeometry& fvGeometry,
234 const ElementVolumeVariables& elemVolVars,
235 const SubControlVolumeFace& scvf)
237 typename Cache::GravityCoefficients g;
238 return calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g);
243 template<
class Problem,
class ElementVolumeVariables >
245 const Element& element,
246 const FVElementGeometry& fvGeometry,
247 const ElementVolumeVariables& elemVolVars,
248 const SubControlVolumeFace& scvf,
249 typename Cache::GravityCoefficients& g)
252 if (!problem.couplingManager().isCoupled(element, scvf))
255 tij[Cache::insideTijIdx] = TpfaDarcysLaw::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf);
260 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
262 const auto insideScvIdx = scvf.insideScvIdx();
263 const auto& insideScv = fvGeometry.scv(insideScvIdx);
264 const auto& insideVolVars = elemVolVars[insideScvIdx];
265 const auto wIn = Extrusion::area(scvf)
267 insideVolVars.permeability(),
268 insideVolVars.extrusionFactor());
271 const auto iBcTypes = problem.interiorBoundaryTypes(element, scvf);
274 if (iBcTypes.hasOnlyNeumann())
276 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
277 const auto wFacet = 2.0*Extrusion::area(scvf)*insideVolVars.extrusionFactor()
278 /facetVolVars.extrusionFactor()
279 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), scvf.unitOuterNormal());
288 if (!scvf.boundary())
290 const auto outsideScvIdx = scvf.outsideScvIdx();
291 const auto& outsideVolVars = elemVolVars[outsideScvIdx];
292 const auto wOut = -1.0*Extrusion::area(scvf)
294 outsideVolVars.permeability(),
295 outsideVolVars.extrusionFactor());
297 if ( !Dune::FloatCmp::eq(xi, 1.0, 1e-6) )
304 const Scalar xiMinusOne = (xi - 1.0);
305 const Scalar a01 = xiMinusOne*wOut;
306 const Scalar a11 = xi*wOut + wFacet;
307 const Scalar detA = (xi*wIn + wFacet)*a11 - xiMinusOne*wIn*a01;
308 g[0] = wIn*a11/detA; g[1] = -wIn*a01/detA;
311 const Scalar factor = wIn * wFacet / ( wIn * wOut * ( 2.0 * xi - 1.0 ) + wFacet * ( xi * ( wIn + wOut ) + wFacet ) );
312 tij[Cache::insideTijIdx] = factor * ( wOut * xi + wFacet );
313 tij[Cache::outsideTijIdx] = factor * ( wOut * ( 1.0 - xi ) );
314 tij[Cache::facetTijIdx] = factor * ( - wOut - wFacet );
318 g[0] = wIn/(wIn+wFacet); g[1] = 0.0;
319 tij[Cache::insideTijIdx] = wFacet*g[0];
320 tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
321 tij[Cache::outsideTijIdx] = 0.0;
327 tij[Cache::insideTijIdx] = wFacet*wIn/(wIn+wFacet);
328 tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
329 tij[Cache::outsideTijIdx] = 0.0;
332 else if (iBcTypes.hasOnlyDirichlet())
334 tij[Cache::insideTijIdx] = wIn;
335 tij[Cache::outsideTijIdx] = 0.0;
336 tij[Cache::facetTijIdx] = -wIn;
339 DUNE_THROW(Dune::NotImplemented,
"Interior boundary types other than pure Dirichlet or Neumann");
349template<
class AdvectionType,
class Gr
idGeometry>
352 using Scalar =
typename AdvectionType::Scalar;
353 using FVElementGeometry =
typename GridGeometry::LocalView;
354 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
355 using Element =
typename GridGeometry::GridView::template Codim<0>::Entity;
364 static constexpr int insideTijIdx = 0;
365 static constexpr int facetTijIdx = 1;
374 template<
class Problem,
class ElementVolumeVariables >
376 const Element& element,
377 const FVElementGeometry& fvGeometry,
378 const ElementVolumeVariables& elemVolVars,
379 const SubControlVolumeFace &scvf)
381 tij_ = AdvectionType::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g_);
389 {
return tij_[insideTijIdx]; }
393 {
return tij_[insideTijIdx]; }
397 {
return tij_[facetTijIdx]; }
404 AdvectionTransmissibilityContainer tij_;
405 GravityCoefficients g_;
412template<
class ScalarType,
class Gr
idGeometry>
418 using FVElementGeometry =
typename GridGeometry::LocalView;
419 using SubControlVolume =
typename GridGeometry::SubControlVolume;
420 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
423 using GridView =
typename GridGeometry::GridView;
424 using Element =
typename GridView::template Codim<0>::Entity;
425 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
435 using TijContainer =
typename Cache::AdvectionTransmissibilityContainer;
438 template<
class Problem,
class ElementVolumeVariables,
class ElementFluxVarsCache >
440 const Element& element,
441 const FVElementGeometry& fvGeometry,
442 const ElementVolumeVariables& elemVolVars,
443 const SubControlVolumeFace& scvf,
445 const ElementFluxVarsCache& elemFluxVarsCache)
447 if (!problem.couplingManager().isOnInteriorBoundary(element, scvf))
448 return TpfaDarcysLaw::flux(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, elemFluxVarsCache);
453 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
454 if (Dune::FloatCmp::ne(xi, 1.0, 1e-6))
455 DUNE_THROW(Dune::InvalidStateException,
"Xi != 1.0 cannot be used on surface grids");
458 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
459 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
460 const auto pInside = insideVolVars.pressure(phaseIdx);
461 const auto pFacet = facetVolVars.pressure(phaseIdx);
464 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
465 Scalar flux = fluxVarsCache.advectionTijInside()*pInside + fluxVarsCache.advectionTijFacet()*pFacet;
467 static const Scalar gravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
471 const auto& g = problem.spatialParams().gravity(scvf.ipGlobal());
472 const auto rho = 0.5*(insideVolVars.density(phaseIdx) + facetVolVars.density(phaseIdx));
473 const auto rhoTimesArea = rho*Extrusion::area(scvf);
474 const auto alpha_inside = rhoTimesArea*insideVolVars.extrusionFactor()
475 *
vtmv(scvf.unitOuterNormal(), insideVolVars.permeability(), g);
477 flux += alpha_inside;
480 if ( !scvf.boundary() && problem.interiorBoundaryTypes(element, scvf).hasOnlyNeumann() )
482 const auto alpha_facet = rhoTimesArea*insideVolVars.extrusionFactor()
483 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), g);
485 flux -= fluxVarsCache.gravityCoefficients()[0]*(alpha_inside - alpha_facet);
494 template<
class Problem,
class ElementVolumeVariables >
496 const Element& element,
497 const FVElementGeometry& fvGeometry,
498 const ElementVolumeVariables& elemVolVars,
499 const SubControlVolumeFace& scvf)
501 typename Cache::GravityCoefficients g;
502 return calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g);
507 template<
class Problem,
class ElementVolumeVariables >
509 const Element& element,
510 const FVElementGeometry& fvGeometry,
511 const ElementVolumeVariables& elemVolVars,
512 const SubControlVolumeFace& scvf,
513 typename Cache::GravityCoefficients& g)
516 if (!problem.couplingManager().isCoupled(element, scvf))
519 tij[Cache::insideTijIdx] = TpfaDarcysLaw::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf);
524 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
529 if (Dune::FloatCmp::ne(xi, 1.0, 1e-6))
530 DUNE_THROW(Dune::InvalidStateException,
"Xi != 1.0 cannot be used on surface grids");
532 const auto area = Extrusion::area(scvf);
533 const auto insideScvIdx = scvf.insideScvIdx();
534 const auto& insideScv = fvGeometry.scv(insideScvIdx);
535 const auto& insideVolVars = elemVolVars[insideScvIdx];
539 const auto iBcTypes = problem.interiorBoundaryTypes(element, scvf);
542 if (iBcTypes.hasOnlyNeumann())
544 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
549 const auto wFacet = 2.0*area*insideVolVars.extrusionFactor()
550 /sqrt(facetVolVars.extrusionFactor())
551 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), scvf.unitOuterNormal());
554 g[0] = wIn/(wIn+wFacet);
555 tij[Cache::insideTijIdx] = wFacet*g[0];
556 tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
558 else if (iBcTypes.hasOnlyDirichlet())
560 tij[Cache::insideTijIdx] = wIn;
561 tij[Cache::facetTijIdx] = -wIn;
564 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.
Helper classes to compute the integration elements.
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:849
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition: extrusion.hh:177
Class that fills the cache corresponding to tpfa Darcy's Law.
Definition: flux/cctpfa/darcyslaw.hh:70
Specialization of the CCTpfaDarcysLaw grids where dim=dimWorld.
Definition: flux/cctpfa/darcyslaw.hh:130
Specialization of the CCTpfaDarcysLaw grids where dim < dimWorld (network/surface grids)
Definition: flux/cctpfa/darcyslaw.hh:294
Forward declaration of the implementation.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:45
The cache corresponding to tpfa Darcy's Law with facet coupling.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:54
const GravityCoefficients & gravityCoefficients() const
return the coefficients for the computation of gravity at the scvf
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:127
std::array< Scalar, 3 > AdvectionTransmissibilityContainer
Export transmissibility storage type.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:91
Scalar advectionTijInside() const
returns the transmissibility associated with the inside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:115
std::array< Scalar, 2 > GravityCoefficients
Export the type used for the gravity coefficients.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:94
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:98
Scalar advectionTijOutside() const
returns the transmissibility associated with the outside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:119
Scalar advectionTijFacet() const
returns the transmissibility associated with the outside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:123
Scalar advectionTij() const
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:111
Specialization of CCTpfaFacetCouplingDarcysLawImpl for dim=dimWorld.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:141
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:167
ScalarType Scalar
state the scalar type of the law
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:156
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:231
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:244
typename Cache::AdvectionTransmissibilityContainer TijContainer
export the type used to store transmissibilities
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:162
std::array< Scalar, 1 > GravityCoefficients
Export the type used for the gravity coefficients.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:371
std::array< Scalar, 2 > AdvectionTransmissibilityContainer
Export transmissibility storage type.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:368
Scalar advectionTij() const
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:388
Scalar advectionTijInside() const
returns the transmissibility associated with the inside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:392
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:375
const GravityCoefficients & gravityCoefficients() const
return the coefficients for the computation of gravity at the scvf
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:400
Scalar advectionTijFacet() const
returns the transmissibility associated with the outside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:396
Specialization of CCTpfaFacetCouplingDarcysLawImpl for dim<dimWorld.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:414
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:495
typename Cache::AdvectionTransmissibilityContainer TijContainer
export the type used to store transmissibilities
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:435
ScalarType Scalar
state the scalar type of the law
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:429
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:439
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:508
Declares all properties used in Dumux.
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.