12#ifndef DUMUX_DISCRETIZATION_CC_TPFA_FACET_COUPLING_DARCYS_LAW_HH
13#define DUMUX_DISCRETIZATION_CC_TPFA_FACET_COUPLING_DARCYS_LAW_HH
18#include <dune/common/float_cmp.hh>
32template<
class ScalarType,
class Gr
idGeometry,
bool isNetwork>
41template<
class AdvectionType,
class Gr
idGeometry,
bool isNetwork>
50template<
class ScalarType,
class Gr
idGeometry>
53 int(GridGeometry::GridView::dimensionworld) ) >;
59template<
class AdvectionType,
class Gr
idGeometry>
62 using Scalar =
typename AdvectionType::Scalar;
63 using FVElementGeometry =
typename GridGeometry::LocalView;
64 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
65 using Element =
typename GridGeometry::GridView::template Codim<0>::Entity;
74 static constexpr int insideTijIdx = 0;
75 static constexpr int outsideTijIdx = 1;
76 static constexpr int facetTijIdx = 2;
85 template<
class Problem,
class ElementVolumeVariables >
87 const Element& element,
88 const FVElementGeometry& fvGeometry,
89 const ElementVolumeVariables& elemVolVars,
90 const SubControlVolumeFace &scvf)
92 tij_ = AdvectionType::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g_);
100 {
return tij_[insideTijIdx]; }
104 {
return tij_[insideTijIdx]; }
108 {
return tij_[outsideTijIdx]; }
112 {
return tij_[facetTijIdx]; }
119 std::array<Scalar, 3> tij_;
120 GravityCoefficients g_;
127template<
class ScalarType,
class Gr
idGeometry>
133 using FVElementGeometry =
typename GridGeometry::LocalView;
134 using SubControlVolume =
typename GridGeometry::SubControlVolume;
135 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
138 using GridView =
typename GridGeometry::GridView;
139 using Element =
typename GridView::template Codim<0>::Entity;
140 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
151 using TijContainer =
typename Cache::AdvectionTransmissibilityContainer;
155 template<
class Problem,
class ElementVolumeVariables,
class ElementFluxVarsCache >
157 const Element& element,
158 const FVElementGeometry& fvGeometry,
159 const ElementVolumeVariables& elemVolVars,
160 const SubControlVolumeFace& scvf,
162 const ElementFluxVarsCache& elemFluxVarsCache)
164 if (!problem.couplingManager().isOnInteriorBoundary(element, scvf))
165 return TpfaDarcysLaw::flux(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, elemFluxVarsCache);
168 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
169 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
170 const auto pInside = insideVolVars.pressure(phaseIdx);
171 const auto pFacet = facetVolVars.pressure(phaseIdx);
174 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
175 Scalar flux = fluxVarsCache.advectionTijInside()*pInside + fluxVarsCache.advectionTijFacet()*pFacet;
178 static const Scalar gravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
182 const auto& g = problem.spatialParams().gravity(scvf.ipGlobal());
183 const auto rho = 0.5*(insideVolVars.density(phaseIdx) + facetVolVars.density(phaseIdx));
184 const auto rhoTimesArea = rho*Extrusion::area(fvGeometry, scvf);
185 const auto alpha_inside = rhoTimesArea*insideVolVars.extrusionFactor()
186 *
vtmv(scvf.unitOuterNormal(), insideVolVars.permeability(), g);
188 flux += alpha_inside;
189 if (!scvf.boundary())
191 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
194 if ( problem.interiorBoundaryTypes(element, scvf).hasOnlyNeumann() )
196 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
197 const auto alpha_facet = rhoTimesArea*insideVolVars.extrusionFactor()
198 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), g);
199 const auto alpha_outside = rhoTimesArea*outsideVolVars.extrusionFactor()
200 *
vtmv(scvf.unitOuterNormal(), outsideVolVars.permeability(), g);
202 flux -= fluxVarsCache.gravityCoefficients()[0]*(xi*alpha_inside - alpha_facet + (1.0 - xi)*alpha_outside);
203 flux += fluxVarsCache.gravityCoefficients()[1]*(xi*alpha_outside - alpha_facet + (1.0 - xi)*alpha_inside);
207 flux += fluxVarsCache.advectionTijOutside()*outsideVolVars.pressure(phaseIdx);
213 return scvf.boundary() ? flux
214 : flux + fluxVarsCache.advectionTijOutside()*elemVolVars[scvf.outsideScvIdx()].pressure(phaseIdx);
219 template<
class Problem,
class ElementVolumeVariables >
221 const Element& element,
222 const FVElementGeometry& fvGeometry,
223 const ElementVolumeVariables& elemVolVars,
224 const SubControlVolumeFace& scvf)
226 typename Cache::GravityCoefficients g;
227 return calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g);
232 template<
class Problem,
class ElementVolumeVariables >
234 const Element& element,
235 const FVElementGeometry& fvGeometry,
236 const ElementVolumeVariables& elemVolVars,
237 const SubControlVolumeFace& scvf,
238 typename Cache::GravityCoefficients& g)
241 if (!problem.couplingManager().isCoupled(element, scvf))
244 tij[Cache::insideTijIdx] = TpfaDarcysLaw::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf);
249 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
251 const auto insideScvIdx = scvf.insideScvIdx();
252 const auto& insideScv = fvGeometry.scv(insideScvIdx);
253 const auto& insideVolVars = elemVolVars[insideScvIdx];
254 const auto wIn = Extrusion::area(fvGeometry, scvf)
256 insideVolVars.permeability(),
257 insideVolVars.extrusionFactor());
260 const auto iBcTypes = problem.interiorBoundaryTypes(element, scvf);
263 if (iBcTypes.hasOnlyNeumann())
265 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
266 const auto wFacet = 2.0*Extrusion::area(fvGeometry, scvf)*insideVolVars.extrusionFactor()
267 /facetVolVars.extrusionFactor()
268 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), scvf.unitOuterNormal());
277 if (!scvf.boundary())
279 const auto outsideScvIdx = scvf.outsideScvIdx();
280 const auto& outsideVolVars = elemVolVars[outsideScvIdx];
281 const auto wOut = -1.0*Extrusion::area(fvGeometry, scvf)
283 outsideVolVars.permeability(),
284 outsideVolVars.extrusionFactor());
286 if ( !Dune::FloatCmp::eq(xi, 1.0, 1e-6) )
293 const Scalar xiMinusOne = (xi - 1.0);
294 const Scalar a01 = xiMinusOne*wOut;
295 const Scalar a11 = xi*wOut + wFacet;
296 const Scalar detA = (xi*wIn + wFacet)*a11 - xiMinusOne*wIn*a01;
297 g[0] = wIn*a11/detA; g[1] = -wIn*a01/detA;
300 const Scalar factor = wIn * wFacet / ( wIn * wOut * ( 2.0 * xi - 1.0 ) + wFacet * ( xi * ( wIn + wOut ) + wFacet ) );
301 tij[Cache::insideTijIdx] = factor * ( wOut * xi + wFacet );
302 tij[Cache::outsideTijIdx] = factor * ( wOut * ( 1.0 - xi ) );
303 tij[Cache::facetTijIdx] = factor * ( - wOut - wFacet );
307 g[0] = wIn/(wIn+wFacet); g[1] = 0.0;
308 tij[Cache::insideTijIdx] = wFacet*g[0];
309 tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
310 tij[Cache::outsideTijIdx] = 0.0;
316 tij[Cache::insideTijIdx] = wFacet*wIn/(wIn+wFacet);
317 tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
318 tij[Cache::outsideTijIdx] = 0.0;
321 else if (iBcTypes.hasOnlyDirichlet())
323 tij[Cache::insideTijIdx] = wIn;
324 tij[Cache::outsideTijIdx] = 0.0;
325 tij[Cache::facetTijIdx] = -wIn;
328 DUNE_THROW(Dune::NotImplemented,
"Interior boundary types other than pure Dirichlet or Neumann");
338template<
class AdvectionType,
class Gr
idGeometry>
341 using Scalar =
typename AdvectionType::Scalar;
342 using FVElementGeometry =
typename GridGeometry::LocalView;
343 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
344 using Element =
typename GridGeometry::GridView::template Codim<0>::Entity;
353 static constexpr int insideTijIdx = 0;
354 static constexpr int facetTijIdx = 1;
363 template<
class Problem,
class ElementVolumeVariables >
365 const Element& element,
366 const FVElementGeometry& fvGeometry,
367 const ElementVolumeVariables& elemVolVars,
368 const SubControlVolumeFace &scvf)
370 tij_ = AdvectionType::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g_);
378 {
return tij_[insideTijIdx]; }
382 {
return tij_[insideTijIdx]; }
386 {
return tij_[facetTijIdx]; }
393 AdvectionTransmissibilityContainer tij_;
394 GravityCoefficients g_;
401template<
class ScalarType,
class Gr
idGeometry>
407 using FVElementGeometry =
typename GridGeometry::LocalView;
408 using SubControlVolume =
typename GridGeometry::SubControlVolume;
409 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;
425 using TijContainer =
typename Cache::AdvectionTransmissibilityContainer;
428 template<
class Problem,
class ElementVolumeVariables,
class ElementFluxVarsCache >
430 const Element& element,
431 const FVElementGeometry& fvGeometry,
432 const ElementVolumeVariables& elemVolVars,
433 const SubControlVolumeFace& scvf,
435 const ElementFluxVarsCache& elemFluxVarsCache)
437 if (!problem.couplingManager().isOnInteriorBoundary(element, scvf))
438 return TpfaDarcysLaw::flux(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, elemFluxVarsCache);
443 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
444 if (Dune::FloatCmp::ne(xi, 1.0, 1e-6))
445 DUNE_THROW(Dune::InvalidStateException,
"Xi != 1.0 cannot be used on surface grids");
448 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
449 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
450 const auto pInside = insideVolVars.pressure(phaseIdx);
451 const auto pFacet = facetVolVars.pressure(phaseIdx);
454 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
455 Scalar flux = fluxVarsCache.advectionTijInside()*pInside + fluxVarsCache.advectionTijFacet()*pFacet;
457 static const Scalar gravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
461 const auto& g = problem.spatialParams().gravity(scvf.ipGlobal());
462 const auto rho = 0.5*(insideVolVars.density(phaseIdx) + facetVolVars.density(phaseIdx));
463 const auto rhoTimesArea = rho*Extrusion::area(fvGeometry, scvf);
464 const auto alpha_inside = rhoTimesArea*insideVolVars.extrusionFactor()
465 *
vtmv(scvf.unitOuterNormal(), insideVolVars.permeability(), g);
467 flux += alpha_inside;
470 if ( !scvf.boundary() && problem.interiorBoundaryTypes(element, scvf).hasOnlyNeumann() )
472 const auto alpha_facet = rhoTimesArea*insideVolVars.extrusionFactor()
473 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), g);
475 flux -= fluxVarsCache.gravityCoefficients()[0]*(alpha_inside - alpha_facet);
484 template<
class Problem,
class ElementVolumeVariables >
486 const Element& element,
487 const FVElementGeometry& fvGeometry,
488 const ElementVolumeVariables& elemVolVars,
489 const SubControlVolumeFace& scvf)
491 typename Cache::GravityCoefficients g;
492 return calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g);
497 template<
class Problem,
class ElementVolumeVariables >
499 const Element& element,
500 const FVElementGeometry& fvGeometry,
501 const ElementVolumeVariables& elemVolVars,
502 const SubControlVolumeFace& scvf,
503 typename Cache::GravityCoefficients& g)
506 if (!problem.couplingManager().isCoupled(element, scvf))
509 tij[Cache::insideTijIdx] = TpfaDarcysLaw::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf);
514 static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(),
"FacetCoupling.Xi", 1.0);
519 if (Dune::FloatCmp::ne(xi, 1.0, 1e-6))
520 DUNE_THROW(Dune::InvalidStateException,
"Xi != 1.0 cannot be used on surface grids");
522 const auto area = Extrusion::area(fvGeometry, scvf);
523 const auto insideScvIdx = scvf.insideScvIdx();
524 const auto& insideScv = fvGeometry.scv(insideScvIdx);
525 const auto& insideVolVars = elemVolVars[insideScvIdx];
526 const auto wIn = area*
computeTpfaTransmissibility(fvGeometry, scvf, insideScv, insideVolVars.permeability(), insideVolVars.extrusionFactor());
529 const auto iBcTypes = problem.interiorBoundaryTypes(element, scvf);
532 if (iBcTypes.hasOnlyNeumann())
534 const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
539 const auto wFacet = 2.0*area*insideVolVars.extrusionFactor()
540 /sqrt(facetVolVars.extrusionFactor())
541 *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), scvf.unitOuterNormal());
544 g[0] = wIn/(wIn+wFacet);
545 tij[Cache::insideTijIdx] = wFacet*g[0];
546 tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
548 else if (iBcTypes.hasOnlyDirichlet())
550 tij[Cache::insideTijIdx] = wIn;
551 tij[Cache::facetTijIdx] = -wIn;
554 DUNE_THROW(Dune::NotImplemented,
"Interior boundary types other than pure Dirichlet or Neumann");
Specialization of the CCTpfaDarcysLaw grids where dim=dimWorld.
Definition: flux/cctpfa/darcyslaw.hh:118
Specialization of the CCTpfaDarcysLaw grids where dim < dimWorld (network/surface grids)
Definition: flux/cctpfa/darcyslaw.hh:283
const GravityCoefficients & gravityCoefficients() const
return the coefficients for the computation of gravity at the scvf
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:115
std::array< Scalar, 3 > AdvectionTransmissibilityContainer
Export transmissibility storage type.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:79
Scalar advectionTijInside() const
returns the transmissibility associated with the inside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:103
std::array< Scalar, 2 > GravityCoefficients
Export the type used for the gravity coefficients.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:82
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:86
Scalar advectionTijOutside() const
returns the transmissibility associated with the outside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:107
Scalar advectionTijFacet() const
returns the transmissibility associated with the outside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:111
Scalar advectionTij() const
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:99
std::array< Scalar, 1 > GravityCoefficients
Export the type used for the gravity coefficients.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:360
std::array< Scalar, 2 > AdvectionTransmissibilityContainer
Export transmissibility storage type.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:357
Scalar advectionTij() const
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:377
Scalar advectionTijInside() const
returns the transmissibility associated with the inside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:381
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:364
const GravityCoefficients & gravityCoefficients() const
return the coefficients for the computation of gravity at the scvf
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:389
Scalar advectionTijFacet() const
returns the transmissibility associated with the outside cell
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:385
The cache corresponding to tpfa Darcy's Law with facet coupling.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:42
Specialization of CCTpfaFacetCouplingDarcysLawImpl for dim=dimWorld.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:129
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:156
ScalarType Scalar
state the scalar type of the law
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:144
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:220
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:233
typename Cache::AdvectionTransmissibilityContainer TijContainer
export the type used to store transmissibilities
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:151
Specialization of CCTpfaFacetCouplingDarcysLawImpl for dim<dimWorld.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:403
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:485
typename Cache::AdvectionTransmissibilityContainer TijContainer
export the type used to store transmissibilities
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:425
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:429
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:498
Forward declaration of the implementation.
Definition: multidomain/facet/cellcentered/tpfa/darcyslaw.hh:33
Class that fills the cache corresponding to tpfa Darcy's Law.
Definition: flux/cctpfa/darcyslaw.hh:58
Defines all properties used in Dumux.
Helper classes to compute the integration elements.
Darcy's law for cell-centered finite volume schemes with two-point flux approximation.
Tensor::field_type computeTpfaTransmissibility(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolumeFace &scvf, const typename FVElementGeometry::SubControlVolume &scv, const Tensor &T, typename FVElementGeometry::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:36
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:851
Define some often used mathematical functions.
The available discretization methods in Dumux.
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.
Free functions to evaluate the transmissibilities associated with flux evaluations across sub-control...