From 021a6c95506849533c3a01c4d521f53c97e402d4 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de> Date: Thu, 2 Aug 2018 11:45:29 +0200 Subject: [PATCH] [staggered] Clean-up Fick's law --- .../staggered/freeflow/fickslaw.hh | 118 +++++++----------- dumux/freeflow/nonisothermal/localresidual.hh | 2 +- 2 files changed, 44 insertions(+), 76 deletions(-) diff --git a/dumux/discretization/staggered/freeflow/fickslaw.hh b/dumux/discretization/staggered/freeflow/fickslaw.hh index f56fde0bd6..105badc410 100644 --- a/dumux/discretization/staggered/freeflow/fickslaw.hh +++ b/dumux/discretization/staggered/freeflow/fickslaw.hh @@ -25,7 +25,7 @@ #define DUMUX_DISCRETIZATION_STAGGERED_FICKS_LAW_HH #include <numeric> -#include <dune/common/float_cmp.hh> +#include <dune/common/fvector.hh> #include <dumux/common/properties.hh> #include <dumux/common/parameters.hh> @@ -48,30 +48,20 @@ template <class TypeTag> class FicksLawImplementation<TypeTag, DiscretizationMethod::staggered > { using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using FVElementGeometry = typename FVGridGeometry::LocalView; using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; using GridView = typename FVGridGeometry::GridView; using Element = typename GridView::template Codim<0>::Entity; using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; - using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables); - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - - static constexpr int dim = GridView::dimension; - static constexpr int dimWorld = GridView::dimensionworld; - using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); + using Indices = typename ModelTraits::Indices; + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); static constexpr int numComponents = ModelTraits::numComponents(); - static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); + using NumEqVector = Dune::FieldVector<Scalar, numComponents>; - static_assert(ModelTraits::numPhases() == 1, "Only one phase allowed supported!"); - - enum { - conti0EqIdx = Indices::conti0EqIdx - }; + static_assert(ModelTraits::numPhases() == 1, "Only one phase supported!"); public: // state the discretization method this implementation belongs to @@ -81,90 +71,68 @@ public: //! We don't cache anything for this law using Cache = FluxVariablesCaching::EmptyDiffusionCache; - static CellCenterPrimaryVariables flux(const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - const ElementVolumeVariables& elemVolVars, - const SubControlVolumeFace &scvf) + template<class Problem> + static NumEqVector flux(const Problem& problem, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace &scvf) { - CellCenterPrimaryVariables flux(0.0); + NumEqVector flux(0.0); + + // There is no diffusion over outflow boundaries (grad x == 0). + // We assume that if an outflow BC is set for the first transported component, this + // also holds for all other components. + if (scvf.boundary() && problem.boundaryTypes(element, scvf).isOutflow(Indices::conti0EqIdx + 1)) + return flux; + const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx()); const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()]; const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()]; + const Scalar insideDistance = (insideScv.dofPosition() - scvf.ipGlobal()).two_norm(); const Scalar insideMolarDensity = insideVolVars.molarDensity(); - for(int compIdx = 0; compIdx < numComponents; ++compIdx) + for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - if(compIdx == FluidSystem::getMainComponent(0)) + if (compIdx == FluidSystem::getMainComponent(0)) continue; - // get equation index - const auto eqIdx = conti0EqIdx + compIdx; + const Scalar insideMoleFraction = insideVolVars.moleFraction(compIdx); + const Scalar outsideMoleFraction = outsideVolVars.moleFraction(compIdx); - if(scvf.boundary()) + const Scalar insideD = insideVolVars.effectiveDiffusivity(0, compIdx) * insideVolVars.extrusionFactor(); + + if (scvf.boundary()) { - const auto bcTypes = problem.boundaryTypes(element, scvf); - if(bcTypes.isOutflow(eqIdx) || bcTypes.isSymmetry()) - return flux; + flux[compIdx] = insideMolarDensity * insideD + * (insideMoleFraction - outsideMoleFraction) / insideDistance; } + else + { + const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx()); + const Scalar outsideD = outsideVolVars.effectiveDiffusivity(0, compIdx) * outsideVolVars.extrusionFactor(); + const Scalar outsideDistance = (outsideScv.dofPosition() - scvf.ipGlobal()).two_norm(); + const Scalar outsideMolarDensity = outsideVolVars.molarDensity(); - const Scalar tij = transmissibility_(fvGeometry, elemVolVars, scvf, compIdx); - const Scalar insideMoleFraction = insideVolVars.moleFraction(compIdx); + const Scalar avgDensity = 0.5*(insideMolarDensity + outsideMolarDensity); + const Scalar avgD = harmonicMean(insideD, outsideD, insideDistance, outsideDistance); - const Scalar outsideMolarDensity = scvf.boundary() ? insideVolVars.molarDensity() : outsideVolVars.molarDensity(); - const Scalar avgDensity = 0.5*(insideMolarDensity + outsideMolarDensity); - const Scalar outsideMoleFraction = outsideVolVars.moleFraction(compIdx); - flux[compIdx] = avgDensity * tij * (insideMoleFraction - outsideMoleFraction); + flux[compIdx] = avgDensity * avgD + * (insideMoleFraction - outsideMoleFraction) / (insideDistance + outsideDistance); + } } // Fick's law (for binary systems) states that the net flux of moles within the bulk phase has to be zero: // If a given amount of molecules A travel into one direction, the same amount of molecules B have to // go into the opposite direction. const Scalar cumulativeFlux = std::accumulate(flux.begin(), flux.end(), 0.0); - flux[FluidSystem::getMainComponent(0)] = - cumulativeFlux; - - return flux; - } - - static Scalar transmissibility_(const FVElementGeometry& fvGeometry, - const ElementVolumeVariables& elemVolVars, - const SubControlVolumeFace& scvf, - const int compIdx) - { - Scalar tij = 0.0; - const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx()); - const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()]; - - const Scalar insideDistance = (insideScv.dofPosition() - scvf.ipGlobal()).two_norm(); - const Scalar insideD = insideVolVars.effectiveDiffusivity(0, compIdx); - const Scalar ti = calculateOmega_(insideDistance, insideD, insideVolVars.extrusionFactor()); + flux[FluidSystem::getMainComponent(0)] = -cumulativeFlux; - if(scvf.boundary()) - tij = scvf.area() * ti; - else - { - const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx()); - const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()]; - const Scalar outsideDistance = (outsideScv.dofPosition() - scvf.ipGlobal()).two_norm(); - const Scalar outsideD = outsideVolVars.effectiveDiffusivity(0, compIdx); - const Scalar tj = calculateOmega_(outsideDistance, outsideD, outsideVolVars.extrusionFactor()); - - tij = scvf.area()*(ti * tj)/(ti + tj); - } - return tij; - } + flux *= scvf.area(); - static Scalar calculateOmega_(const Scalar distance, - const Scalar D, - const Scalar extrusionFactor) - { - Scalar omega = D / distance; - omega *= extrusionFactor; - - return omega; + return flux; } - }; } // end namespace diff --git a/dumux/freeflow/nonisothermal/localresidual.hh b/dumux/freeflow/nonisothermal/localresidual.hh index e3032d77f3..630c23d5de 100644 --- a/dumux/freeflow/nonisothermal/localresidual.hh +++ b/dumux/freeflow/nonisothermal/localresidual.hh @@ -152,7 +152,7 @@ public: ParentType::heatFlux(flux, problem, element, fvGeometry, elemVolVars, elemFaceVars, scvf); static constexpr auto localEnergyBalanceIdx = NumEqVector::dimension - 1; - NumEqVector diffusiveFlux = FluxVariables::MolecularDiffusionType::flux(problem, element, fvGeometry, elemVolVars, scvf); + auto diffusiveFlux = FluxVariables::MolecularDiffusionType::flux(problem, element, fvGeometry, elemVolVars, scvf); for (int compIdx = 0; compIdx < FluxVariables::numComponents; ++compIdx) { const bool insideIsUpstream = scvf.directionSign() == sign(diffusiveFlux[compIdx]); -- GitLab