14#ifndef DUMUX_TRACER_LOCAL_RESIDUAL_HH 
   15#define DUMUX_TRACER_LOCAL_RESIDUAL_HH 
   17#include <dune/common/exceptions.hh> 
   34template<
class TypeTag>
 
   42    using FVElementGeometry = 
typename GridGeometry::LocalView;
 
   43    using SubControlVolume = 
typename GridGeometry::SubControlVolume;
 
   44    using SubControlVolumeFace = 
typename GridGeometry::SubControlVolumeFace;
 
   49    using GridView = 
typename GridGeometry::GridView;
 
   50    using Element = 
typename GridView::template Codim<0>::Entity;
 
   56    static constexpr int numComponents = ModelTraits::numFluidComponents();
 
   58    static constexpr int phaseIdx = 0;
 
   61    using ParentType::ParentType;
 
   75                               const SubControlVolume& scv,
 
   76                               const VolumeVariables& volVars)
 const 
   78        NumEqVector storage(0.0);
 
   84        const Scalar saturation = max(1e-8, volVars.saturation(phaseIdx));
 
   89            for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
 
   90                storage[compIdx] += volVars.porosity()
 
   91                                    * volVars.molarDensity(phaseIdx)
 
   92                                    * volVars.moleFraction(phaseIdx, compIdx)
 
   98            for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
 
   99                storage[compIdx] += volVars.porosity()
 
  100                                    * volVars.density(phaseIdx)
 
  101                                    * volVars.massFraction(phaseIdx, compIdx)
 
 
  120                            const Element& element,
 
  121                            const FVElementGeometry& fvGeometry,
 
  122                            const ElementVolumeVariables& elemVolVars,
 
  123                            const SubControlVolumeFace& scvf,
 
  124                            const ElementFluxVariablesCache& elemFluxVarsCache)
 const 
  126        FluxVariables fluxVars;
 
  127        fluxVars.init(problem, element, fvGeometry, elemVolVars, scvf, elemFluxVarsCache);
 
  128        static constexpr auto referenceSystemFormulationDiffusion = FluxVariables::MolecularDiffusionType::referenceSystemFormulation();
 
  130        NumEqVector flux(0.0);
 
  132        const auto massOrMoleDensity = [](
const auto& volVars, 
const int phaseIdx)
 
  133        { 
return useMoles ? volVars.molarDensity(phaseIdx) : volVars.density(phaseIdx); };
 
  135        const auto massOrMoleFraction = [](
const auto& volVars, 
const int phaseIdx, 
const int compIdx)
 
  136        { 
return useMoles ? volVars.moleFraction(phaseIdx, compIdx) : volVars.massFraction(phaseIdx, compIdx); };
 
  139        const auto adaptFluxUnits = [](
const Scalar referenceFlux, 
const Scalar molarMass,
 
  143                return useMoles ? referenceFlux/molarMass
 
  146                return useMoles ? referenceFlux
 
  147                                : referenceFlux*molarMass;
 
  149                DUNE_THROW(Dune::NotImplemented, 
"other reference systems than mass and molar averaged are not implemented");
 
  152        const auto diffusiveFluxes = fluxVars.molecularDiffusionFlux(phaseIdx);
 
  153        auto dispersiveFluxes = 
decltype(diffusiveFluxes)(0.0);
 
  154        if constexpr (ModelTraits::enableCompositionalDispersion())
 
  155            dispersiveFluxes = fluxVars.compositionalDispersionFlux(phaseIdx);
 
  157        for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
 
  160            auto upwindTerm = [&massOrMoleDensity, &
massOrMoleFraction, compIdx](
const auto& volVars)
 
  161            { 
return massOrMoleDensity(volVars, phaseIdx)*
massOrMoleFraction(volVars, phaseIdx, compIdx); };
 
  164            flux[compIdx] += fluxVars.advectiveFlux(phaseIdx, upwindTerm);
 
  166            flux[compIdx] += adaptFluxUnits(diffusiveFluxes[compIdx],
 
  167                                            FluidSystem::molarMass(compIdx),
 
  168                                            referenceSystemFormulationDiffusion);
 
  169            if constexpr (ModelTraits::enableCompositionalDispersion())
 
  171                static constexpr auto referenceSystemFormulationDispersion =
 
  172                    FluxVariables::DispersionFluxType::referenceSystemFormulation();
 
  173                flux[compIdx] += adaptFluxUnits(dispersiveFluxes[compIdx],
 
  174                                                FluidSystem::molarMass(compIdx),
 
  175                                                referenceSystemFormulationDispersion);
 
 
  192    template<
class PartialDerivativeMatrix>
 
  194                               const Problem& problem,
 
  195                               const Element& element,
 
  196                               const FVElementGeometry& fvGeometry,
 
  197                               const VolumeVariables& curVolVars,
 
  198                               const SubControlVolume& scv)
 const 
  204        const auto saturation = max(1e-8, curVolVars.saturation(phaseIdx));
 
  206        const auto porosity = curVolVars.porosity();
 
  207        const auto rho = useMoles ? curVolVars.molarDensity() : curVolVars.density();
 
  208        const auto d_storage = Extrusion::volume(fvGeometry, scv)*porosity*rho*saturation/this->timeLoop().timeStepSize();
 
  210        for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
 
  211            partialDerivatives[compIdx][compIdx] += d_storage;
 
 
  224    template<
class PartialDerivativeMatrix>
 
  226                              const Problem& problem,
 
  227                              const Element& element,
 
  228                              const FVElementGeometry& fvGeometry,
 
  229                              const VolumeVariables& curVolVars,
 
  230                              const SubControlVolume& scv)
 const 
 
  235    template<
class PartialDerivativeMatrices, 
class T = TypeTag>
 
  238                       const Problem& problem,
 
  239                       const Element& element,
 
  240                       const FVElementGeometry& fvGeometry,
 
  241                       const ElementVolumeVariables& curElemVolVars,
 
  242                       const ElementFluxVariablesCache& elemFluxVarsCache,
 
  243                       const SubControlVolumeFace& scvf)
 const 
  246            DUNE_THROW(Dune::NotImplemented, 
"Analytic flux differentiation only implemented for tpfa");
 
  249        auto rho = [](
const VolumeVariables& volVars)
 
  250        { 
return useMoles ? volVars.molarDensity() : volVars.density(); };
 
  253        const auto volFlux = problem.spatialParams().volumeFlux(element, fvGeometry, curElemVolVars, scvf);
 
  259        const auto& insideVolVars = curElemVolVars[scvf.insideScvIdx()];
 
  260        const auto& outsideVolVars = curElemVolVars[scvf.outsideScvIdx()];
 
  262        const Scalar insideWeight = std::signbit(volFlux) ? (1.0 - upwindWeight) : upwindWeight;
 
  263        const Scalar outsideWeight = 1.0 - insideWeight;
 
  264        const auto advDerivII = volFlux*rho(insideVolVars)*insideWeight;
 
  265        const auto advDerivIJ = volFlux*rho(outsideVolVars)*outsideWeight;
 
  268        static constexpr auto referenceSystemFormulation = FluxVariables::MolecularDiffusionType::referenceSystemFormulation();
 
  269        const auto& fluxCache = elemFluxVarsCache[scvf];
 
  270        const Scalar rhoInside = 
massOrMolarDensity(insideVolVars, referenceSystemFormulation, phaseIdx);
 
  271        const Scalar rhoOutside = 
massOrMolarDensity(outsideVolVars, referenceSystemFormulation, phaseIdx);
 
  274        for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
 
  277            Scalar diffDeriv = 0.0;
 
  280                diffDeriv = useMoles ? 
massOrMolarDensity*fluxCache.diffusionTij(phaseIdx, compIdx)/FluidSystem::molarMass(compIdx)
 
  286                                            : 
massOrMolarDensity*fluxCache.diffusionTij(phaseIdx, compIdx)*FluidSystem::molarMass(compIdx);
 
  289                DUNE_THROW(Dune::NotImplemented, 
"other reference systems than mass and molar averaged are not implemented");
 
  291            derivativeMatrices[scvf.insideScvIdx()][compIdx][compIdx] += (advDerivII + diffDeriv);
 
  292            if (!scvf.boundary())
 
  293                derivativeMatrices[scvf.outsideScvIdx()][compIdx][compIdx] += (advDerivIJ - diffDeriv);
 
 
  297    template<
class JacobianMatrix, 
class T = TypeTag>
 
  300                       const Problem& problem,
 
  301                       const Element& element,
 
  302                       const FVElementGeometry& fvGeometry,
 
  303                       const ElementVolumeVariables& curElemVolVars,
 
  304                       const ElementFluxVariablesCache& elemFluxVarsCache,
 
  305                       const SubControlVolumeFace& scvf)
 const 
  309        auto rho = [](
const VolumeVariables& volVars)
 
  310        { 
return useMoles ? volVars.molarDensity() : volVars.density(); };
 
  313        const auto volFlux = problem.spatialParams().volumeFlux(element, fvGeometry, curElemVolVars, scvf);
 
  319        const auto& insideVolVars = curElemVolVars[scvf.insideScvIdx()];
 
  320        const auto& outsideVolVars = curElemVolVars[scvf.outsideScvIdx()];
 
  322        const auto insideWeight = std::signbit(volFlux) ? (1.0 - upwindWeight) : upwindWeight;
 
  323        const auto outsideWeight = 1.0 - insideWeight;
 
  324        const auto advDerivII = volFlux*rho(insideVolVars)*insideWeight;
 
  325        const auto advDerivIJ = volFlux*rho(outsideVolVars)*outsideWeight;
 
  328        static constexpr auto referenceSystemFormulation = FluxVariables::MolecularDiffusionType::referenceSystemFormulation();
 
  330        const auto ti = DiffusionType::calculateTransmissibilities(problem,
 
  335                                                                   elemFluxVarsCache[scvf],
 
  337        const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
 
  338        const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
 
  340        for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
 
  342            for (
const auto& scv : scvs(fvGeometry))
 
  345                auto diffDeriv = 0.0;
 
  347                    diffDeriv += useMoles ? ti[compIdx][scv.indexInElement()]/FluidSystem::molarMass(compIdx)
 
  348                                        : ti[compIdx][scv.indexInElement()];
 
  350                    diffDeriv += useMoles ? ti[compIdx][scv.indexInElement()]
 
  351                                            : ti[compIdx][scv.indexInElement()]*FluidSystem::molarMass(compIdx);
 
  353                    DUNE_THROW(Dune::NotImplemented, 
"other reference systems than mass and molar averaged are not implemented");
 
  354                A[insideScv.dofIndex()][scv.dofIndex()][compIdx][compIdx] += diffDeriv;
 
  355                A[outsideScv.dofIndex()][scv.dofIndex()][compIdx][compIdx] -= diffDeriv;
 
  358            A[insideScv.dofIndex()][insideScv.dofIndex()][compIdx][compIdx] += advDerivII;
 
  359            A[insideScv.dofIndex()][outsideScv.dofIndex()][compIdx][compIdx] += advDerivIJ;
 
  360            A[outsideScv.dofIndex()][outsideScv.dofIndex()][compIdx][compIdx] -= advDerivII;
 
  361            A[outsideScv.dofIndex()][insideScv.dofIndex()][compIdx][compIdx] -= advDerivIJ;
 
 
  365    template<
class PartialDerivativeMatrices>
 
  367                                       const Problem& problem,
 
  368                                       const Element& element,
 
  369                                       const FVElementGeometry& fvGeometry,
 
  370                                       const ElementVolumeVariables& curElemVolVars,
 
  371                                       const ElementFluxVariablesCache& elemFluxVarsCache,
 
  372                                       const SubControlVolumeFace& scvf)
 const 
  376                           curElemVolVars, elemFluxVarsCache, scvf);
 
 
  379    template<
class PartialDerivativeMatrices>
 
  381                                 const Problem& problem,
 
  382                                 const Element& element,
 
  383                                 const FVElementGeometry& fvGeometry,
 
  384                                 const ElementVolumeVariables& curElemVolVars,
 
  385                                 const ElementFluxVariablesCache& elemFluxVarsCache,
 
  386                                 const SubControlVolumeFace& scvf)
 const 
 
 
Element-wise calculation of the local residual for problems using fully implicit tracer model.
Definition porousmediumflow/tracer/localresidual.hh:37
NumEqVector computeStorage(const Problem &problem, const SubControlVolume &scv, const VolumeVariables &volVars) const
Evaluates the amount of all conservation quantities (e.g. phase mass) within a sub-control volume.
Definition porousmediumflow/tracer/localresidual.hh:74
void addRobinFluxDerivatives(PartialDerivativeMatrices &derivativeMatrices, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &curElemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Definition porousmediumflow/tracer/localresidual.hh:380
std::enable_if_t< GetPropType< T, Properties::GridGeometry >::discMethod !=DiscretizationMethods::box, void > addFluxDerivatives(PartialDerivativeMatrices &derivativeMatrices, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &curElemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Definition porousmediumflow/tracer/localresidual.hh:237
void addSourceDerivatives(PartialDerivativeMatrix &partialDerivatives, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const VolumeVariables &curVolVars, const SubControlVolume &scv) const
TODO docme!
Definition porousmediumflow/tracer/localresidual.hh:225
void addStorageDerivatives(PartialDerivativeMatrix &partialDerivatives, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const VolumeVariables &curVolVars, const SubControlVolume &scv) const
TODO docme!
Definition porousmediumflow/tracer/localresidual.hh:193
NumEqVector computeFlux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluates the total flux of all conservation quantities over a face of a sub-control volume.
Definition porousmediumflow/tracer/localresidual.hh:119
std::enable_if_t< GetPropType< T, Properties::GridGeometry >::discMethod==DiscretizationMethods::box, void > addFluxDerivatives(JacobianMatrix &A, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &curElemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Definition porousmediumflow/tracer/localresidual.hh:299
void addCCDirichletFluxDerivatives(PartialDerivativeMatrices &derivativeMatrices, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &curElemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Definition porousmediumflow/tracer/localresidual.hh:366
Defines all properties used in Dumux.
The default local operator than can be specialized for each discretization scheme.
Helper classes to compute the integration elements.
typename NumEqVectorTraits< PrimaryVariables >::type NumEqVector
A vector with the same size as numbers of equations This is the default implementation and has to be ...
Definition numeqvector.hh:34
VolumeVariables::PrimaryVariables::value_type massOrMoleFraction(const VolumeVariables &volVars, ReferenceSystemFormulation referenceSys, const int phaseIdx, const int compIdx)
returns the mass or mole fraction to be used in Fick's law based on the reference system
Definition referencesystemformulation.hh:54
VolumeVariables::PrimaryVariables::value_type massOrMolarDensity(const VolumeVariables &volVars, ReferenceSystemFormulation referenceSys, const int phaseIdx)
evaluates the density to be used in Fick's law based on the reference system
Definition referencesystemformulation.hh:43
ReferenceSystemFormulation
The formulations available for Fick's law related to the reference system.
Definition referencesystemformulation.hh:33
@ massAveraged
Definition referencesystemformulation.hh:34
@ molarAveraged
Definition referencesystemformulation.hh:34
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:149
T getParam(Args &&... args)
A free function to get a parameter from the parameter tree singleton.
Definition parameters.hh:139
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:310
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
The available discretization methods in Dumux.
constexpr CCTpfa cctpfa
Definition method.hh:145
constexpr Box box
Definition method.hh:147
typename Detail::DiscretizationDefaultLocalOperator< TypeTag >::type DiscretizationDefaultLocalOperator
Definition defaultlocaloperator.hh:26
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:166
A helper to deduce a vector with the same size as numbers of equations.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.