From d1656d9a6aa2ef9f85993f3f046802da42acab05 Mon Sep 17 00:00:00 2001 From: Maziar Veyskarami <maziar.veyskarami@iws.uni-stuttgart.de> Date: Thu, 18 Nov 2021 07:39:22 +0000 Subject: [PATCH] Fix BoundaryFlux class in pore network --- dumux/porenetwork/common/boundaryflux.hh | 53 +++++++++++++++--------- test/porenetwork/1p/problem.hh | 2 - test/porenetwork/1pnc/problem.hh | 2 - test/porenetwork/2p/problem.hh | 4 +- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/dumux/porenetwork/common/boundaryflux.hh b/dumux/porenetwork/common/boundaryflux.hh index 0646063b3f..0187f7fa56 100644 --- a/dumux/porenetwork/common/boundaryflux.hh +++ b/dumux/porenetwork/common/boundaryflux.hh @@ -98,7 +98,7 @@ public: } /*! - * \brief Returns the cumulative flux in \f$\mathrm{[\frac{kg}{s}]}\f$, \f$\mathrm{[\frac{mole}{s}]}\f$ or \f$\mathrm{[\frac{J}{s}]}\f$ of several pore throats for a given list of pore labels to consider + * \brief Returns the cumulative flux in \f$\mathrm{[\frac{kg}{s}]}\f$, \f$\mathrm{[\frac{mole}{s}]}\f$ or \f$\mathrm{[\frac{J}{s}]}\f$ of several pores for a given list of pore labels to consider * * \param labels A list of pore labels which will be considered for the flux calculation * \param verbose If set true, the fluxes at all individual SCVs are printed @@ -119,7 +119,7 @@ public: // sum up the fluxes for (const auto& element : elements(localResidual_.problem().gridGeometry().gridView())) - getFlux(element, restriction, verbose); + computeBoundaryFlux_(element, restriction, verbose); Result result; result.totalFlux = std::accumulate(boundaryFluxes_.begin(), boundaryFluxes_.end(), NumEqVector(0.0));; @@ -133,7 +133,7 @@ public: } /*! - * \brief Returns the cumulative flux in \f$\mathrm{[\frac{kg}{s}]}\f$, \f$\mathrm{[\frac{mole}{s}]}\f$ or \f$\mathrm{[\frac{J}{s}]}\f$ of several pore throats at a given location on the boundary + * \brief Returns the cumulative flux in \f$\mathrm{[\frac{kg}{s}]}\f$, \f$\mathrm{[\frac{mole}{s}]}\f$ or \f$\mathrm{[\frac{J}{s}]}\f$ of several pores at a given location on the boundary * * \param minMax Consider bBoxMin or bBoxMax by setting "min" or "max" * \param coord x, y or z coordinate at which bBoxMin or bBoxMax is evaluated @@ -177,7 +177,7 @@ public: // sum up the fluxes for (const auto& element : elements(localResidual_.problem().gridGeometry().gridView())) - getFlux(element, restriction, verbose); + computeBoundaryFlux_(element, restriction, verbose); Result result; result.totalFlux = std::accumulate(boundaryFluxes_.begin(), boundaryFluxes_.end(), NumEqVector(0.0));; @@ -188,23 +188,22 @@ public: } return result; - } +private: + /*! - * \brief Returns the cumulative flux in \f$\mathrm{[\frac{kg}{s}]}\f$, \f$\mathrm{[\frac{mole}{s}]}\f$ or \f$\mathrm{[\frac{J}{s}]}\f$ of several pore throats at a given location on the boundary + * \brief Computes the cumulative flux in \f$\mathrm{[\frac{kg}{s}]}\f$, \f$\mathrm{[\frac{mole}{s}]}\f$ or \f$\mathrm{[\frac{J}{s}]}\f$ of an individual pore on the boundary * * \param element The element * \param considerScv A lambda function to decide whether to consider a scv or not * \param verbose If set true, the fluxes at all individual SCVs are printed */ template<class RestrictingFunction> - NumEqVector getFlux(const Element& element, - RestrictingFunction considerScv, - const bool verbose = false) const + void computeBoundaryFlux_(const Element& element, + RestrictingFunction considerScv, + const bool verbose = false) const { - NumEqVector flux(0.0); - // by default, all coordinate directions are considered for the definition of a boundary // make sure FVElementGeometry and volume variables are bound to the element @@ -215,11 +214,9 @@ public: if (!isStationary_) prevElemVolVars.bindElement(element, fvGeometry, sol_); - const auto elemFluxVarsCache = localView(gridVariables_.gridFluxVarsCache()).bindElement(element, fvGeometry, curElemVolVars); - ElementBoundaryTypes elemBcTypes; elemBcTypes.update(localResidual_.problem(), element, fvGeometry); - + const auto elemFluxVarsCache = localView(gridVariables_.gridFluxVarsCache()).bindElement(element, fvGeometry, curElemVolVars); auto residual = localResidual_.evalFluxAndSource(element, fvGeometry, curElemVolVars, elemFluxVarsCache, elemBcTypes); if (!isStationary_) @@ -232,21 +229,37 @@ public: { isConsidered_[scv.dofIndex()] = true; + // get the type of the boundary condition on the scv + const auto& bcTypes = elemBcTypes[scv.localDofIndex()]; + + NumEqVector flux(0.0); + for (int eqIdx = 0; eqIdx < NumEqVector::dimension; ++eqIdx) + { + // Check the type of the boudary condition. + // If BC is Dirichlet type, the flux is equal to the local residual of the element's scv on the boundary. + // Otherwise the flux is either zero or equal to a source term at the element's scv on the boundary. + // Technicaly, the PNM considers source terms instead of Neumann BCs. + if (!bcTypes.isDirichlet(eqIdx)) + { + auto source = localResidual_.computeSource(localResidual_.problem(), element, fvGeometry, curElemVolVars, scv); + source *= scv.volume() * curElemVolVars[scv].extrusionFactor(); + flux[eqIdx] = source[eqIdx]; + } + else + flux[eqIdx] = residual[scv.indexInElement()][eqIdx]; + } + // The flux must be substracted: // On an inlet boundary, the flux part of the local residual will be positive, since all fluxes will leave the SCV towards to interior domain. // For the domain itself, however, the sign has to be negative, since mass is entering the system. - flux -= residual[scv.indexInElement()]; - - boundaryFluxes_[scv.dofIndex()] -= residual[scv.indexInElement()]; + boundaryFluxes_[scv.dofIndex()] -= flux; if (verbose) - std::cout << "SCV of element " << scv.elementIndex() << " at vertex " << scv.dofIndex() << " has flux: " << residual[scv.indexInElement()] << std::endl; + std::cout << "SCV of element " << scv.elementIndex() << " at vertex " << scv.dofIndex() << " has flux: " << flux << std::endl; } } - return flux; } -private: const LocalResidual localResidual_; // store a copy of the local residual const GridVariables& gridVariables_; const SolutionVector& sol_; diff --git a/test/porenetwork/1p/problem.hh b/test/porenetwork/1p/problem.hh index 44146bdcdb..9ac8c1161e 100644 --- a/test/porenetwork/1p/problem.hh +++ b/test/porenetwork/1p/problem.hh @@ -87,8 +87,6 @@ public: BoundaryTypes bcTypes; if (isInletPore_(scv) || isOutletPore_(scv)) bcTypes.setAllDirichlet(); - else // neuman for the remaining boundaries - bcTypes.setAllNeumann(); #if !ISOTHERMAL bcTypes.setDirichlet(Indices::temperatureIdx); #endif diff --git a/test/porenetwork/1pnc/problem.hh b/test/porenetwork/1pnc/problem.hh index 6748321a1f..8d3b94b716 100644 --- a/test/porenetwork/1pnc/problem.hh +++ b/test/porenetwork/1pnc/problem.hh @@ -103,8 +103,6 @@ public: BoundaryTypes bcTypes; if (isInletPore_(scv) || isOutletPore_(scv)) bcTypes.setAllDirichlet(); - else // neuman for the remaining boundaries - bcTypes.setAllNeumann(); #if !ISOTHERMAL bcTypes.setDirichlet(temperatureIdx); #endif diff --git a/test/porenetwork/2p/problem.hh b/test/porenetwork/2p/problem.hh index 1971defef3..138ada0141 100644 --- a/test/porenetwork/2p/problem.hh +++ b/test/porenetwork/2p/problem.hh @@ -119,10 +119,8 @@ public: if (useFixedPressureAndSaturationBoundary_ && isInletPore_(scv)) bcTypes.setAllDirichlet(); else if (isOutletPore_(scv)) - bcTypes.setAllDirichlet(); + bcTypes.setAllDirichlet(); - else // neuman for the remaining boundaries - bcTypes.setAllNeumann(); #if !ISOTHERMAL bcTypes.setDirichlet(temperatureIdx); #endif -- GitLab